Android开发之ListView开发中view对象的复用问题2

需求:当你在复用listView的子项带有checkbox控件的view对象时,由于复用的原理是直接复用前面失去焦点的view对象(不懂得具体可看前面的一篇关于listView优化的记录http://my.oschina.net/zaizaiangels/blog/529308

那么checkbox的记录也会被复用,这就会产生数据错乱

处理方法:

步骤:1、给listView添加监听点击事件的方法,在监听到listView的子项被点击时,认为的去记录该子项下checkbox的状态

2、我们将在一个业务bean中保存每个listView子项的状态,在复用的时候,检查并设置相应的状态即可

代码如下

子项的布局文件

<?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;
    }
}

转载于:https://my.oschina.net/zaizaiangels/blog/530683

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值