【问题标题】:ListView setOnItemClickListener get the wrong item when adpater.notifyDataSetChanged was called调用 adpater.notifyDataSetChanged 时 ListView setOnItemClickListener 得到错误的项目
【发布时间】:2011-07-19 10:22:10
【问题描述】:

我正在使用列表视图来显示下载列表的进度。 我使用一个线程通过在处理程序中调用 notifyDataSetChanged 每秒更新进度。 一切正常,直到我尝试使用 setOnItemClickListener 来获取在列表中单击的项目。当更新线程运行时,onItemClick 的结果是不可预测的,我单击了列表中的第一个项目,但显示的 onItemClick 的结果我单击了第二个。 我认为这是因为单击该项目时数据已更改,但我该如何防止呢? 我尝试在单击项目时将 isListItemBeenClicked 标志设置为 true,并且更新线程仅在 isListItemBeenClicked 为 false 时调用 notifyDataSetChanged,但它不起作用。 谁能帮我解决这个问题?

PS:对不起我蹩脚的英语

代码:

1.刷新处理程序

    listViewRefreshHandler = new Handler() {
        @Override
        public void handleMessage(Message msg){
            if(!isListItemBeenClicked){
                System.out.println("start refresh");
                downloadingTaskList.clear();
                uploadingTaskList.clear();
                completedTaskList.clear();
                downloadingTaskList.addAll(transferService.getDownloadingTaskList());
                uploadingTaskList.addAll(transferService.getUploadingTaskList());
                completedTaskList.addAll(transferService.getCompletedTaskList());
                Collections.sort(completedTaskList, new Comparator<TransferTask>(){
                    @Override
                    public int compare(TransferTask transferTask1, TransferTask transferTask2) {
                        int ret=0;
                        long result=transferTask2.getCompletedDate().getTime()-transferTask1.getCompletedDate().getTime();
                        if(result==0){
                            ret=0;
                        }else if(result>0){
                            ret=1;
                        }else{
                            ret=-1;
                        }
                        return ret;
                    }

                });
                downloadingTaskListAdapter.notifyDataSetChanged();
                completedTaskListAdapter.notifyDataSetChanged();
                uploadingTaskListAdapter.notifyDataSetChanged();
                System.out.println("refresh end");
            }
        }
    };

2.OnItemClickListener

        list.setOnItemClickListener(new OnItemClickListener(){
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            isListItemBeenClicked=true;
            System.out.println("click start");
            TransferTask downloadTask=(TransferTask)view.getTag();
            System.out.println("click "+downloadTask.getFileName());
            System.out.println("click end");
            isListItemBeenClicked=false;

        }
    });

3.更新线程

        new Thread() {
        public void run() {
            while (!isStop) {
                try {
                    Thread.sleep(1000);
                    listViewRefreshHandler.sendEmptyMessage(1);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }.start();

4.TransferTaskListAdapter

public class TransferTaskListAdapter extends BaseAdapter {   

    private Context context;   
    private List<TransferTask> transeferTaskList;

    public TransferTaskListAdapter(Context context, List<TransferTask> downloadTaskList ) {    
        this.context = context;   
        this.transeferTaskList = downloadTaskList;   
    }   

    public int getCount() {                           
        return transeferTaskList.size();   
    }   

    public TransferTask getItem(int position) {        
        return transeferTaskList.get(position);   
    }   

    public long getItemId(int position) {     
        return position;   
    }   
    public View getView(int position, View convertView, ViewGroup parent) {
        System.out.println("get view called");
        TransferTask transferTask=getItem(position);
        if(convertView==null){
            convertView= LayoutInflater.from(context).inflate(R.layout.transfering_task, null);
        }
        convertView.setTag(transferTask);
        ImageView taskStatusImageView=(ImageView)convertView.findViewById(R.id.taskStatus);
        TransferTaskStatus tastStatus=transferTask.getStatus();
        switch(tastStatus){
            case DOWNLOADING:
                taskStatusImageView.setImageResource(R.drawable.icon_status_download);
                break;
            case UPLOADING:
                taskStatusImageView.setImageResource(R.drawable.icon_status_upload);
                break;
            case PAUSED :
                taskStatusImageView.setImageResource(R.drawable.icon_status_paused);
                break;
            case COMPLETED:
                if(transferTask.getType().equals(TaskType.DONWLOAD)){
                    taskStatusImageView.setImageResource(R.drawable.icon_status_download);
                }else{
                    taskStatusImageView.setImageResource(R.drawable.icon_status_upload);
                }

                break;
            case WAITING:
                taskStatusImageView.setImageResource(R.drawable.icon_status_waiting);
                break;
            case STARTING:
                taskStatusImageView.setImageResource(R.drawable.icon_status_waiting);
                break;
            case STOPPING:
                taskStatusImageView.setImageResource(R.drawable.icon_status_waiting);
                break;
            default:
                taskStatusImageView.setImageResource(R.drawable.icon_status_failed);
        }

        String fileName=transferTask.getFileName();
        TextView fileNameTextView=(TextView)convertView.findViewById(R.id.fileName);
        fileNameTextView.setText(fileName);

        long size=transferTask.getSize();
        long transferedSize=transferTask.getTransferedSize();
        FileTransferProgressBar progressBar=(FileTransferProgressBar)convertView.findViewById(R.id.downloadProgress);
        progressBar.setTotalFileSize(size);
        progressBar.setTransferedFileSize(transferedSize);
        System.out.println("get view end");
        return convertView;   
    }   

} 

【问题讨论】:

    标签: android listview


    【解决方案1】:

    尝试使用以下方法:

    TransferTask downloadTask = (TransferTask)parent.getItemAtPosition(position);

    而不是你现在的:

    TransferTask downloadTask=(TransferTask)view.getTag();

    【讨论】:

    • 我会尝试,但有什么不同?
    • 老实说,我认为这两种方法都应该有效,但请试一试,看看是否有帮助。我只是建议它,因为我之前从未使用过 View 参数并且从未遇到任何问题。
    • 我猜想这可能与视图在 ListView 中滚动离开屏幕时的回收方式有关。无论如何,文档说要使用 getItemAtPosition(position) 来获取与 ListView 关联的任何数据。
    猜你喜欢
    • 2021-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多