360項目-08


## 軟件管理 ##android

- 文件大小的計算app

    android.text.Formatter 類能夠格式化文件大小
    // 內部存儲, 其實就是data目錄的容量ide

        File dataDirectory = Environment.getDataDirectory();
           // 所有
        long totalSpace = dataFile.getTotalSpace();
        // 可用
        long usableSpace = dataFile.getUsableSpace();
        // 已用
        long usedSpace = totalSpace - usableSpace;
        mPdvRom.setTitle("內存: ");
        mPdvRom.setTextLeft(Formatter.formatFileSize(getApplicationContext(), usedSpace) + "已用");
        mPdvRom.setTextRight(Formatter.formatFileSize(getApplicationContext(), freeSpace) + "可用");
        mPdvRom.setProgress((int) (usedSpace * 100f / totalSpace + 0.5f)); // 四捨五入
        // SD卡
        File sdDirectory = Environment.getExternalStorageDirectory();
        // 總空間
        long sdTotalSpace = sdDirectory.getTotalSpace();
        // 剩餘空間
        long sdFreeSpace = sdDirectory.getFreeSpace();
        long sdUsedSpace = totalSpace - freeSpace;
        mPdvSD.setTitle("SD卡: ");
        mPdvSD.setTextLeft(Formatter.formatFileSize(getApplicationContext(), sdUsedSpace) + "已用");
        mPdvSD.setTextRight(Formatter.formatFileSize(getApplicationContext(), sdFreeSpace) + "可用");
        mPdvSD.setProgress((int) (sdUsedSpace * 100f / sdTotalSpace+ 0.5f));佈局


## 軟件管理的內容部分 ##優化

- 應用程序列表先簡單實現  標準listview帶優化的寫法動畫

        private class AppAdapter extends BaseAdapter {
            @Override
            public int getCount() {
                return mDatas.size();
            }
            @Override
            public Object getItem(int position) {
                return mDatas.get(position);
            }
            @Override
            public long getItemId(int position) {
                return position;
            }
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                ViewHolder holder;
                if (convertView == null) {
                    convertView = View.inflate(getApplicationContext(), R.layout.item_appinfo, null);
                    holder = new ViewHolder();
                    holder.ivIcon = (ImageView) convertView.findViewById(R.id.item_appinfo_iv_icon);
                    holder.tvName = (TextView) convertView.findViewById(R.id.item_appinfo_tv_name);
                    holder.tvInstallPath = (TextView) convertView.findViewById(R.id
                            .item_appinfo_tv_install);
                    holder.tvSize = (TextView) convertView.findViewById(R.id.item_appinfo_tv_size);
                    convertView.setTag(holder);
                } else {
                    holder = (ViewHolder) convertView.getTag();
                }
                // 這裏可使用 getItem 方法獲取某個位置對應的對象
                AppInfo info = (AppInfo) getItem(position);
                holder.tvName.setText(info.mName);
                holder.ivIcon.setImageDrawable(info.mIcon);
                holder.tvInstallPath.setText(info.mIsInstallSD ? "SD卡安裝" : "手機內存");
                holder.tvSize.setText(Formatter.formatFileSize(getApplicationContext(), info.mSize));
                return convertView;
            }
        }
        static class ViewHolder {
            ImageView ivIcon;
            TextView tvName;
            TextView tvInstallPath;
            TextView tvSize;
        }this

-- 對應的JavaBean:指針

    public class AppInfo {
        public String mName;// 應用的名稱
        public String mPackageName;// 應用的包名
        public Drawable mIcon;// 應用圖標
        public boolean mIsInstallSD;// 是否安裝在sd卡
        public long mSize;// 應用的大小
        public boolean mIsSystem;// 是不是系統程序
    }orm


## 獲取應用程序的信息##xml

- 建立一個包, engine 或者 business, 寫個類, AppInfoProvider

        public class AppInfoProvider {
            public static ArrayList<AppInfo> getAllAppInfo(Context context) {
                PackageManager packageManager = context.getPackageManager();
                // 獲取全部的安裝包信息, PackageInfo 至關於 manifest 節點
                List<PackageInfo> packages = packageManager.getInstalledPackages(0);
                ArrayList<AppInfo> list = new ArrayList<>();
                for (PackageInfo packageInfo : packages) {
                    AppInfo appInfo = new AppInfo();
                    // 獲取包名
                    appInfo.mPackageName = packageInfo.packageName;
                    // 獲取應用名稱
                    ApplicationInfo applicationInfo = packageInfo.applicationInfo;
                    appInfo.mName = applicationInfo.loadLabel(packageManager).toString();
                    // 獲取應用圖標
                    appInfo.mIcon = applicationInfo.loadIcon(packageManager);
                    // 獲取應用安裝包大小
                    String sourceDir = applicationInfo.sourceDir;// data/app/xxx.apk 或者 system/app/xxx.apk
                    //應用安裝包
                    appInfo.mSize = new File(sourceDir).length();
                    // info.mSize = Formatter.formatFileSize(context, length);
    
                    // 是否爲系統應用
                    if((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == ApplicationInfo
                            .FLAG_SYSTEM) {
                        appInfo.mIsSystem = true;
                    }else {
                        appInfo.mIsSystem = false;
                    }
    
                    // 是否爲外部存儲
                    // 應用能夠裝在sd卡上, 在清單文件根節點中配置 android:installLocation 屬性便可
                    if((applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == ApplicationInfo
                            .FLAG_EXTERNAL_STORAGE) {
                        appInfo.mIsInstallSD = true;
                    }else {
                        appInfo.mIsInstallSD = false;
                    }
    
                    list.add(appInfo);
                }
                return list;
            }
        }

注意 flags 和 &, | 運算符的含義

##進度條/include標籤的使用##
- 新建一個佈局文件 loading:


        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:id="@+id/loading"
            android:orientation="vertical" >
        
            <ProgressBar
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:indeterminateDrawable="@drawable/progress_loading"
                android:indeterminateDuration="600" />
        
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="加載中..."
                android:textColor="#a000"
                android:textSize="16sp" />
        
        </LinearLayout>


在其餘佈局文件裏使用 include 標籤引用便可

     <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <ListView
            android:id="@+id/lv_am"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fastScrollEnabled="true" />

        <include
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            layout="@layout/loading" />
    </RelativeLayout>

- 這和直接寫在佈局文件裏效果是同樣的, 在代碼中, 能夠經過id找到相應的控件.

        new Thread() {
            @Override
            public void run() {
                super.run();
                // 模擬耗時操做
                SystemClock.sleep(1000);
                // 填充數據集合s
                infos = AppInfoProvider.getAllAppInfo
                        (getApplicationContext());
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mLlLoading.setVisibility(View.GONE);
                        // 給ListView設置Adapter
                        mLvApp.setAdapter(new AppAdapter());
                    }
                });
            }
        }.start();

- ListView中的條目分組顯示
- 把應用信息分紅用戶應用和系統應用, 在數據加載完成以後分紅兩個集合

                  mInfos = AppInfoProvider.getAllAppInfo(getApplicationContext());
                mSysInfos = new ArrayList<AppInfo>();
                mUserInfos = new ArrayList<AppInfo>();
                // 區分用戶和系統程序 分別添加到兩個集合裏
                for (AppInfo info : mInfos) {
                    if (info.isSys) {
                        // 系統程序
                        mSysInfos.add(info);
                    } else {
                        // 用戶程序
                        mUserInfos.add(info);
                    }
                }
                mInfos.clear();// 清空以前的亂序數據
                // 先添加用戶程序 而後系統程序
                mInfos.addAll(mUserInfos);
                mInfos.addAll(mSysInfos);

 

          


##ListView分隔條目/複雜ListView##  重點 重點 重點 重點 重點 重點 重點 重點 重點 重點 重點 重點 重點 重點 重點 重點 重點 重點 重點

-因爲多了兩個分隔條目, getCount() 方法返回的數量要加2

        @Override
        public int getCount() {
           return mInfos.size() + 2; // 增長兩個分隔條目
        }


- 在 getitem也要對應的改變

          @Override
            public Object getItem(int position) {
                if (position == 0 || position == mUserInfos.size() + 1) {
                    return null;
                }
                if (position < mUserInfos.size() + 1) {
                    return mInfos.get(position - 1);
                } else {
                    return mInfos.get(position - 2);
                }
            }

- 咱們要實現的效果中ListView有兩個分隔條目, 區分用戶應用和系統應用, 有多個條目類型的ListView. 要實現這種效果, 須要重寫 Adapter 裏的兩個方法:

            // 返回有多少種條目類型
            @Override
            public int getViewTypeCount() {
                return 2;
            }
            // 每一個位置對應的條目的類型, 返回值表示條目類型
            @Override
            public int getItemViewType(int position) {
                // 注意返回值必須從0開始, 好比有三種類型, 就得返回 0, 1, 2.
                if (position == 0 || position == mUserDatas.size() + 1) {
                    return 0;
                } else {
                    return 1;
                }
            }

 

-getView方法中, 也得根據當前位置的條目類型返回相應的View:

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            int itemViewType = getItemViewType(position); // 先獲取條目類型
            switch (itemViewType) { // 根據條目類型返回不一樣的View
                case 0:
                       convertView = new TextView(getApplicationContext());
                    tv = (TextView)convertView;
                    tv.setTextColor(Color.BLACK);
                    tv.setTextSize(14);
                    tv.setPadding(4, 4, 4, 4);
                    tv.setBackgroundColor(Color.parseColor("#ffcccccc"));
                    if(position == 0) {
                        tv.setText("用戶程序( " + mUserDatas.size() + " 個)");
                    }else if(position ==  mUserDatas.size() + 1) {
                        tv.setText("系統程序( " + mSystemDatas.size() + " 個)");
                    }
                    break;
                case 1:
                    ViewHolder holder;
                    if (convertView == null || convertView instanceof TextView) {
                        convertView = View.inflate(getApplicationContext(), R.layout.item_appinfo, null);
                        holder = new ViewHolder();
                        holder.ivIcon = (ImageView) convertView.findViewById(R.id.item_appinfo_iv_icon);
                        holder.tvName = (TextView) convertView.findViewById(R.id.item_appinfo_tv_name);
                        holder.tvInstallPath = (TextView) convertView.findViewById(R.id
                                .item_appinfo_tv_install);
                        holder.tvSize = (TextView) convertView.findViewById(R.id.item_appinfo_tv_size);
                        convertView.setTag(holder);
                    } else {
                        holder = (ViewHolder) convertView.getTag();
                    }
                    AppInfo info = (AppInfo) getItem(position);
                    holder.tvName.setText(info.mName);
                    holder.ivIcon.setImageDrawable(info.mIcon);
                    holder.tvInstallPath.setText(info.mIsInstallSD ? "SD卡安裝" : "手機內存");
                    holder.tvSize.setText(Formatter.formatFileSize(getApplicationContext(), info.mSize));
                    break;
            }
            return convertView;
        }

##分隔條目的顯示和隱藏##

在佈局文件里加一個 TextView, 樣式和分隔條目TextView如出一轍, 當滾動ListView的時候, 根據第一個可見條目,
作相應的顯示便可.


       <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent" >
    
            <ListView
                android:id="@+id/lv_am"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fastScrollEnabled="true" />
    
            <include
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                layout="@layout/public_loading" />
    
            <TextView
                android:id="@+id/tv_am_apphead"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="#aaaaaa"
                android:padding="4px"
                android:textColor="@android:color/black"
                android:textSize="15sp"
                android:visibility="invisible" />
        </RelativeLayout>

 


-給ListView設置滾動監聽: 重點 重點 重點 重點 重點 重點 重點 重點 重點 重點 重點 重點 重點 重點 重點 重點 重點 重點 重點


       // 設置listview滑動監聽 在設置的時候 默認的方法都會都一遍
        lvAm.setOnScrollListener(new OnScrollListener() {
            // 滑動狀態的改變
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {

            }

            // 滑動時不停的執行
            // 參1 當前listview 參2 能夠見的第一個條目的索引 參3 可見的條目數量 參4 總數量
            @Override
            public void onScroll(AbsListView view, int firstVisibleItem,
                    int visibleItemCount, int totalItemCount) {
                if (mUserInfos == null || mSysInfos == null) {
                    // 防止空指針 在設置的時候 默認的方法都會都一遍
                    return;
                }
                if (firstVisibleItem >= mUserInfos.size() + 1) {
                    // 顯示系統程序 更換固定條目內容
                    tvTopSize.setText("系統程序(" + mSysInfos.size() + "個)");
                } else {
                    tvTopSize.setText("用戶程序(" + mUserInfos.size() + "個)");
                }
            }
        });

 

- 默認應該是隱藏的, 當加載數據完成以後再顯示:


        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // 顯示ListView頭部信息
                mTvHeader.setVisibility(View.VISIBLE);
                // 隱藏進度條
                mLlLoading.setVisibility(View.GONE);
                // 給ListView設置Adapter
                mLvApp.setAdapter(new AppAdapter());
            }
        });


- ListView的屬性:android:fastScrollEnabled="true",
    這個屬性值設置爲true的話, ListView會出現快速滑動條, 默認false

##PopupWindow的基本使用##   重點 重點 重點 重點 重點 重點 重點 重點

- 它有些方法和View有點像, 有些又和Dialog比較像.
    它也是經過Window加到屏幕上的, 可是它和Dialog的又不太同樣, 它的彈出位置不固定.
- 基本用法, 建立一個示例項目.


        public void popup(View v) {
            TextView contentView = new TextView(getApplicationContext());
            contentView.setTextColor(Color.RED);
            contentView.setText("我是一個彈出窗口");
            int width = ViewGroup.LayoutParams.WRAP_CONTENT;
            int height = ViewGroup.LayoutParams.WRAP_CONTENT;
            // 彈出窗口, 第一個參數表示裏面要顯示的View, 後兩個表示寬高.
            PopupWindow popupWindow = new PopupWindow(contentView, width, height);
            // 若是想讓一個彈出窗可以在點擊別的區域時或者按返回鍵時消失, 須要調用下面兩個方法.
            // 表示能夠獲取焦點
            popupWindow.setFocusable(true);
            // 必須設置背景, 若是實在不想要, 能夠設置 new ColorDrawable(Color.TRANSPARENT)
            popupWindow.setBackgroundDrawable(new ColorDrawable(Color.GREEN));
            // 顯示在某個View的左下角
            // popupWindow.showAsDropDown(mTv);
            // 顯示在屏幕的某個地方, 第一個參數只須要傳當前Activity裏任何一個View就行.
            // popupWindow.showAtLocation(mTv, Gravity.CENTER, 0, 0);
            // 顯示在某個View的左下角, 而且指定x, y軸的偏移量
            popupWindow.showAsDropDown(mTv, mTv.getWidth(), -mTv.getHeight());
        }

##在手機衛士使用PopupWindow##

- 給ListView設置 OnItemClickListener, 點擊某個條目後, 在當前條目下面彈出PopupWindow.
這裏能夠寫一個單獨的方法, 把當前條目對應的View做爲參數傳過去. 而且記錄當前點擊的對象.

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            // 只有點在應用條目上, 才應該顯示PopupWindow, 點在分隔標題上不顯示
            // parent 只的就是ListView, getItemAtPosition內部調用的是 Adapter的 getItem
            AppInfo appInfo = (AppInfo) parent.getItemAtPosition(position);
            if (appInfo != null) {
                mCurrentAppInfo = appInfo;
                showPopupWindow(view);
            }
        }
    
               /**
             * 顯示listview單條點擊的彈出框
             *
             * @param view
             */
            private void showPop(View view) {
                // 爲空的時候再建立對象
                if (pop == null) {
                    // 設置寬高爲包裹內容
                    int width = LayoutParams.WRAP_CONTENT;
                    int height = LayoutParams.WRAP_CONTENT;
                    View contentView = View.inflate(getApplicationContext(), R.layout.popup_am,
                            null);
                    contentView.findViewById(R.id.tv_popam_uninstall).setOnClickListener(this);
                    contentView.findViewById(R.id.tv_popam_open).setOnClickListener(this);
                    contentView.findViewById(R.id.tv_popam_share).setOnClickListener(this);
                    contentView.findViewById(R.id.tv_popam_info).setOnClickListener(this);
        
                    pop = new PopupWindow(contentView, width, height);
                    // 能夠獲取焦點
                    pop.setFocusable(true);
                    // 設置背景 只有設置了背景,點擊 外部區域或者返回鍵 纔會消失
                    pop.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));// 設置背景透明
                    // anchor 錨點 拋錨 讓PopupWindow顯示在指定的anchor下方
                    // pop.showAsDropDown(view);
        
                    // 設置動畫彈出方式
                    pop.setAnimationStyle(R.style.PopAnimation);
                }
                pop.showAsDropDown(view, 60, -view.getHeight());
                // 參1 傳入activity裏任意一個view就能夠
                // pop.showAtLocation(mtv, Gravity.LEFT | Gravity.CENTER_VERTICAL, 50,
                // 0);
            }

- 動畫樣式  pop.setAnimationStyle(R.style.PopAnimation);
這裏能夠仿照輸入法的動畫樣式, 本身寫一個, 在 styles.xml中:

        <style name="PopAnimation">
            <item name="android:windowEnterAnimation">@anim/pop_am_enter</item>
            <item name="android:windowExitAnimation">@anim/pop_am_exit</item>
        </style>

        <?xml version="1.0" encoding="utf-8"?>
            <set xmlns:android="http://schemas.android.com/apk/res/android"
                android:shareInterpolator="false" >
            
                <translate
                    android:duration="@android:integer/config_shortAnimTime"
                    android:fromXDelta="100%"
                    android:interpolator="@interpolator/overshoot"
                    android:toXDelta="0" />
            
                <alpha
                    android:duration="@android:integer/config_shortAnimTime"
                    android:fromAlpha="0.5"
                    android:interpolator="@interpolator/decelerate_cubic"
                    android:toAlpha="1.0" />
            
            </set>


            <?xml version="1.0" encoding="utf-8"?>
                <set xmlns:android="http://schemas.android.com/apk/res/android"
                    android:shareInterpolator="false" >
                
                    <translate
                        android:duration="@android:integer/config_shortAnimTime"
                        android:fromXDelta="0"
                        android:interpolator="@interpolator/anticipate"
                        android:toXDelta="100%" />
                
                    <alpha
                        android:duration="@android:integer/config_shortAnimTime"
                        android:fromAlpha="1.0"
                        android:interpolator="@interpolator/accelerate_cubic"
                        android:toAlpha="0.0" />
                
                </set>

- 注意使用了兩個interpolator文件:

        <overshootInterpolator xmlns:android="http://schemas.android.com/apk/res/android"/>
        <anticipateInterpolator xmlns:android="http://schemas.android.com/apk/res/android"/>

# 卸載, 打開, 分享, 信息#
- 點擊PopupWindow裏面的文字時, 實現相應的功能

        /**
         * 顯示app信息頁面
         *
         * @param packageName
         */
        private void showInfo(String packageName) {
            // <action android:name="android.settings.APPLICATION_DETAILS_SETTINGS"
            // />
            // <category android:name="android.intent.category.DEFAULT" />
            // <data android:scheme="package" />
            Intent intent = new Intent();
            intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            intent.setData(Uri.parse("package:" + packageName));
            startActivity(intent);
        }
    
        /**
         * 分享app
         */
        private void shareApp() {
            // <action android:name="android.intent.action.SEND" />
            // <category android:name="android.intent.category.DEFAULT" />
            // <data android:mimeType="text/plain" />
    
            // sharesdk mob 友盟 極光 百度雲推送
    
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_SEND);
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            intent.setType("text/plain");
            intent.putExtra(Intent.EXTRA_TEXT, "分享一個app,,:" + mCurrentInfo.name);
            startActivity(intent);
        }
    
        /**
         * 打開一個app
         *
         * @param packageName
         */
        private void openApp(String packageName) {
            PackageManager pm = getPackageManager();
            // 返回啓動頁面的intent
            Intent openIntent = pm.getLaunchIntentForPackage(packageName);
            // 有些應用沒有頁面 只有後臺程序 須要判斷空
            if (openIntent != null) {
                startActivity(openIntent);
            }
        }
    
        /**
         * 卸載app
         *
         * @param packageName
         */
        private void unInstallApp(String packageName) {
            // <action android:name="android.intent.action.VIEW" />
            // <action android:name="android.intent.action.DELETE" />
            // <category android:name="android.intent.category.DEFAULT" />
            // <data android:scheme="package" />
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_DELETE);
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            intent.setData(Uri.parse("package:" + packageName));
            startActivityForResult(intent, REQUESTCODE_UNINSTALL);
        }
    
        

## 卸載後的處理 ##
- 簡單的作法, 點擊卸載時, startActivityForResult, 從卸載界面回來的時候, 從新獲取一遍數據便可.  
    注意獲取數據以前, 先清空以前的數據集合.

       @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if (requestCode == REQUESTCODE_UNINSTALL) {// 從卸載頁面返回
                // Activity.RESULT_OK
                // resultCode
                // System.out.println("resultCode ==" + resultCode);
    
                // 重新獲取數據
                // 獲取數據前先清空
                    userAppInfos.clear();
                    sysAppInfos.clear();
                    appInfos = AppInfoProvider.getAllAppInfo(getApplicationContext());
                    // 把用戶程序和系統程序分開
                    for (AppInfo info : appInfos) {
                        if (info.isSystem) {
                            sysAppInfos.add(info);
                        } else {
                            userAppInfos.add(info);
                        }
                    }
                    appAdapter.notifyDataSetChanged();
            }
        }


- 比較高級的作法, 監聽系統卸載應用的廣播:  
  在 onCreate 中註冊廣播接收者:

        // 註冊應用卸載的廣播
        IntentFilter filter = new IntentFilter();
        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
        filter.addDataScheme("package");
        registerReceiver(mPackageReceiver, filter);

- 在 onDestroy 中解除註冊:

        unregisterReceiver(mPackageReceiver);

 對應的廣播接收者:


        private BroadcastReceiver mPackageReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                System.out.println("接收到卸載廣播");
                String dataString = intent.getDataString();
                System.out.println("卸載了:" + dataString);
                String packageName = dataString.replace("package:", "");
                // 只須要遍歷用戶集合就能夠了, 由於系統的刪不掉
                // 一邊遍歷一遍移除須要使用 iterator
                ListIterator<AppInfo> iterator = mUserDatas.listIterator();
                while (iterator.hasNext()) {
                    AppInfo next = iterator.next();
                    if (next.packageName.equals(packageName)) {
                        // 移除
                        iterator.remove();
                        mUserInfos.remove(info);
                        break;
                    }
                }
                // 刷新ListView
                mAdapter.notifyDataSetChanged();
            }
        };


    但其實使用廣播是不靠譜的, 由於有的系統不發這個廣播...

- bug
    
    點擊分割條目的bug   單條點擊事件

    if (position == 0 || position == mUserInfos.size() + 1) {
        //若是點擊的是分割條目 不處理
        return;
    }

    把固定條目變成可點擊 處理透過點擊的bug           android:clickable="true"

相關文章
相關標籤/搜索