需求:當你在複用listView的子項帶有checkbox控件的view對象時,因爲複用的原理是直接複用前面失去焦點的view對象(不懂得具體可看前面的一篇關於listView優化的記錄http://my.oschina.net/zaizaiangels/blog/529308) java
那麼checkbox的記錄也會被複用,這就會產生數據錯亂 android
處理方法: app
步驟:一、給listView添加監聽點擊事件的方法,在監聽到listView的子項被點擊時,認爲的去記錄該子項下checkbox的狀態 dom
二、咱們將在一個業務bean中保存每一個listView子項的狀態,在複用的時候,檢查並設置相應的狀態便可 ide
代碼以下 佈局
子項的佈局文件 優化
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="65dip"> <ImageView android:id="@+id/iv_task_icon" android:layout_width="55dip" android:layout_height="55dip" android:layout_marginBottom="5dip" android:layout_marginLeft="5dip" android:layout_marginTop="5dip" android:src="@drawable/ic_launcher" /> <TextView android:id="@+id/tv_task_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dip" android:layout_marginTop="3dip" android:layout_toRightOf="@id/iv_task_icon" android:text="程序名稱:" android:textColor="#000000" android:textSize="20sp" /> <TextView android:id="@+id/tv_task_memory_size" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/tv_task_name" android:layout_marginLeft="5dip" android:layout_marginTop="1dip" android:layout_toRightOf="@id/iv_task_icon" android:text="內存佔用:" android:textColor="#88000000" android:textSize="16sp" /> <CheckBox android:id="@+id/cb_task_status" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="10dip" android:clickable="false" android:focusable="false" /> </RelativeLayout>
listView的佈局文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:clickable="true" android:focusable="false"> <TextView android:id="@+id/textView1" android:layout_width="fill_parent" android:layout_height="55dip" android:background="@android:color/holo_green_dark" android:gravity="center" android:text="任務管理器" android:textColor="@android:color/black" android:textSize="22sp" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/tv_process_count" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="運行中的進程" android:textColor="#000000" /> <TextView android:id="@+id/tv_remains_memory" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:text="剩餘/總內存" android:textColor="#000000" /> </RelativeLayout> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:id="@+id/ll_loading" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" android:visibility="invisible"> <ProgressBar android:layout_width="match_parent" android:layout_height="60dip" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="正在加載程序信息" /> </LinearLayout> <ListView android:id="@+id/lv_task_manager" android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="true" android:fastScrollEnabled="true" /> <TextView android:id="@+id/tv_task_prompt_info" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/darker_gray" android:text="用戶進程" android:textColor="@android:color/white" /> </FrameLayout> </LinearLayout>
業務bean代碼:
package com.zaizai.safty.domain; import android.graphics.drawable.Drawable; /** * 進程信息業務bean * Created by zaizai on 2015/11/15. */ public class TaskInfo { private Drawable icon; private String name; //應用程序名字 private String packname; //應用程序包名 private long memorysize;//內存佔用大小 private boolean userTask;//true用戶進程 false系統進程 private boolean checaked; public boolean isChecaked() { return checaked; } public void setChecaked(boolean checaked) { this.checaked = checaked; } @Override public String toString() { return "TaskInfo{" + "icon=" + icon + ", name='" + name + '\'' + ", packname='" + packname + '\'' + ", memorysize=" + memorysize + ", userTask=" + userTask + ", checaked=" + checaked + '}'; } public Drawable getIcon() { return icon; } public void setIcon(Drawable icon) { this.icon = icon; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPackname() { return packname; } public void setPackname(String packname) { this.packname = packname; } public long getMemorysize() { return memorysize; } public void setMemorysize(long memorysize) { this.memorysize = memorysize; } public boolean isUserTask() { return userTask; } public void setUserTask(boolean userTask) { this.userTask = userTask; } } activity代碼
package com.zaizai.safty; import android.graphics.Color; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.text.format.Formatter; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.CheckBox; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.TextView; import com.zaizai.safty.domain.TaskInfo; import com.zaizai.safty.engine.TaskInfoProvider; import com.zaizai.safty.utils.SystemInfoUtils; import java.util.ArrayList; import java.util.List; /** * Created by zaizai on 2015/11/15. */ public class TaskManagerActivity extends AppCompatActivity { private static final String TAG = "zaizai"; private TextView tvProcessCount; private TextView tvRemainsMemory; private LinearLayout llLoading; private ListView lvTaskManager; private List<TaskInfo> allTaskInfos; private List<TaskInfo> userTaskInfos; private List<TaskInfo> systemTaskInfos; private TaskManagerAdapter taskManagerAdapter; private TextView tvTaskPromptInfo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_task_manager); tvProcessCount = (TextView) findViewById(R.id.tv_process_count); tvRemainsMemory = (TextView) findViewById(R.id.tv_remains_memory); llLoading = (LinearLayout) findViewById(R.id.ll_loading); lvTaskManager = (ListView) findViewById(R.id.lv_task_manager); tvTaskPromptInfo = (TextView) findViewById(R.id.tv_task_prompt_info); int processCount = SystemInfoUtils.getRunningProcessCount(this); tvProcessCount.setText("運行中的進程有:" + processCount + "個"); long availableRemainsMemory = SystemInfoUtils.getAvailableRemainsMemoryCount(this); long totalRemainsMemory = SystemInfoUtils.getTotalRemainsMemoryCount(this); tvRemainsMemory.setText("剩餘/總內存:" + Formatter.formatFileSize(this, availableRemainsMemory) + "/" + Formatter.formatFileSize(this, totalRemainsMemory)); /*加載數據到listView*/ fillData(); /*監聽listView的點擊事件,本身保存checkBox的狀態*/ lvTaskManager.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Log.i(TAG, "TaskManagerListView被點擊"); int userTaskCount = 0; if (userTaskInfos != null) { userTaskCount = userTaskInfos.size(); } int systemtaskCount = 0; if (systemTaskInfos != null) { systemtaskCount = systemTaskInfos.size(); } TaskInfo taskInfo = null; if (position == 0) { /*用戶進程的標籤*/ return; } else if (position == userTaskCount + 1) { /*系統進程的標籤*/ return; } else if (position <= userTaskCount && userTaskInfos != null) { /*用戶進程*/ int newPosition = position - 1; taskInfo = userTaskInfos.get(newPosition); } else if (position >= userTaskCount + 2 && position <= (userTaskCount + systemtaskCount + 2) && systemTaskInfos != null) { /*position > userTaskCount + 2 加一由於增長一個系統進程標籤*/ int newPostion = position - userTaskCount - 2; taskInfo = systemTaskInfos.get(newPostion); } if (view instanceof RelativeLayout) { ViewHolder holder = (ViewHolder) view.getTag(); if (taskInfo != null && taskInfo.isChecaked()) { Log.i(TAG, "checkBox被選中"); taskInfo.setChecaked(false); holder.cbTaskStatus.setChecked(false); } else { Log.i(TAG, "checkBox被選中"); taskInfo.setChecaked(true); holder.cbTaskStatus.setChecked(true); } } } }); /*監聽滾動事件,改變提示文本控件的信息*/ lvTaskManager.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (userTaskInfos != null && systemTaskInfos != null) { if (firstVisibleItem >= userTaskInfos.size()) { tvTaskPromptInfo.setText("系統進程:" + systemTaskInfos.size() + "個"); } else { tvTaskPromptInfo.setText("用戶進程:" + userTaskInfos.size() + "個"); } } } }); } /** * 填充數據 */ private void fillData() { llLoading.setVisibility(View.VISIBLE); new Thread(new Runnable() { @Override public void run() { allTaskInfos = TaskInfoProvider.getTaskInfos(TaskManagerActivity.this); userTaskInfos = new ArrayList<TaskInfo>(); systemTaskInfos = new ArrayList<TaskInfo>(); /*將allTaskInfos中的infos進行分類*/ for (TaskInfo info : allTaskInfos) { if (info.isUserTask()) { userTaskInfos.add(info); } else { systemTaskInfos.add(info); } } /*更新界面*/ runOnUiThread(new Runnable() { @Override public void run() { llLoading.setVisibility(View.INVISIBLE); if (taskManagerAdapter == null) { taskManagerAdapter = new TaskManagerAdapter(); lvTaskManager.setAdapter(taskManagerAdapter); } else { taskManagerAdapter.notifyDataSetChanged(); } } }); } }).start(); } private class TaskManagerAdapter extends BaseAdapter { @Override public int getCount() { int size = 0; if (userTaskInfos != null) { size = size + userTaskInfos.size(); } if (systemTaskInfos != null) { size = size + systemTaskInfos.size(); } size = size + 2; return size; } @Override public View getView(int position, View convertView, ViewGroup parent) { TaskInfo taskInfo = null; int userTaskCount = 0; if (userTaskInfos != null) { userTaskCount = userTaskInfos.size(); } int systemtaskCount = 0; if (systemTaskInfos != null) { systemtaskCount = systemTaskInfos.size(); } if (position == 0) { /*用戶進程的標籤*/ TextView tv = new TextView(getApplicationContext()); tv.setBackgroundColor(Color.GRAY); tv.setTextColor(Color.WHITE); tv.setText("用戶進程:" + userTaskCount + "個"); return tv; } else if (position == userTaskCount + 1) { /*系統進程的標籤*/ TextView tv = new TextView(getApplicationContext()); tv.setBackgroundColor(Color.GRAY); tv.setTextColor(Color.WHITE); tv.setText("系統進程:" + systemtaskCount + "個"); return tv; } else if (position <= userTaskCount && userTaskInfos != null) { /*用戶進程*/ int newPosition = position - 1; taskInfo = userTaskInfos.get(newPosition); } else if (position >= userTaskCount + 2 && position <= (userTaskCount + systemtaskCount + 2) && systemTaskInfos != null) { /*position > userTaskCount + 2 加一由於增長一個系統進程標籤*/ int newPostion = position - userTaskCount - 2; taskInfo = systemTaskInfos.get(newPostion); } View view; ViewHolder viewHolder; if (convertView != null && convertView instanceof RelativeLayout) { view = convertView; viewHolder = (ViewHolder) view.getTag(); } else { view = View.inflate(getApplicationContext(), R.layout.list_item_taskinfo, null); viewHolder = new ViewHolder(); viewHolder.ivTaskIcon = (ImageView) view.findViewById(R.id.iv_task_icon); viewHolder.tvTaskName = (TextView) view.findViewById(R.id.tv_task_name); viewHolder.tvTaskMemorySize = (TextView) view.findViewById(R.id.tv_task_memory_size); viewHolder.cbTaskStatus = (CheckBox) view.findViewById(R.id.cb_task_status); view.setTag(viewHolder); } if (taskInfo != null) { viewHolder.ivTaskIcon.setImageDrawable(taskInfo.getIcon()); viewHolder.tvTaskName.setText(taskInfo.getName()); viewHolder.tvTaskMemorySize.setText("內存佔用:" + Formatter.formatFileSize(getApplicationContext(), taskInfo.getMemorysize())); viewHolder.cbTaskStatus.setChecked(taskInfo.isChecaked()); } return view; } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } } static class ViewHolder { ImageView ivTaskIcon; TextView tvTaskName; TextView tvTaskMemorySize; CheckBox cbTaskStatus; } } 數據提供類
package com.zaizai.safty.engine; import android.app.ActivityManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.os.Debug; import com.zaizai.safty.R; import com.zaizai.safty.domain.TaskInfo; import java.util.ArrayList; import java.util.List; /** * 提供手機裏面的進程信息 * Created by zaizai on 2015/11/15. */ public class TaskInfoProvider { public static List<TaskInfo> getTaskInfos(Context context) { //獲得任務管理器 ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); /*包管理器,用來得到程序的基本信息*/ PackageManager packageManager = context.getPackageManager(); List<ActivityManager.RunningAppProcessInfo> appProcessInfos = activityManager.getRunningAppProcesses(); List<TaskInfo> taskInfos = new ArrayList<TaskInfo>(); for (ActivityManager.RunningAppProcessInfo appProcessInfo : appProcessInfos) { TaskInfo taskInfo = new TaskInfo(); /*appProcessInfo.pid;進程id 沒有爲0 * appProcessInfo.processName;應用程序包名 * */ String packname = appProcessInfo.processName; taskInfo.setPackname(packname); Debug.MemoryInfo[] memoryInfos = activityManager.getProcessMemoryInfo(new int[]{appProcessInfo.pid}); long memorysize = memoryInfos[0].getTotalPrivateDirty() * 1024; taskInfo.setMemorysize(memorysize); /*經過包管理器得到程序的基本信息*/ try { ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packname, 0); Drawable icon = applicationInfo.loadIcon(packageManager); taskInfo.setIcon(icon); String name = applicationInfo.loadLabel(packageManager).toString(); taskInfo.setName(name); if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { /*用戶進程*/ taskInfo.setUserTask(true); } else { /*系統進程*/ taskInfo.setUserTask(false); } } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); taskInfo.setIcon(context.getResources().getDrawable(R.drawable.ic_default)); taskInfo.setName(packname); } taskInfos.add(taskInfo); } return taskInfos; } }