【问题标题】:GetView ListFragment checkboox IssuesGetView ListFragment 复选框问题
【发布时间】:2014-07-28 03:39:42
【问题描述】:

我有一个 Activity,它扩展了一个包含 2 个文本框和一个复选框的片段列表。我的列表填充得很好,但是当我选中复选框时,它引用了 getView() 调用的最后一个片段,而不是其相关片段(当我选中框 2 时,如果框 8 是 getView 调用的最后一个项目,则框 8 将展开( )在名单上) 我该如何解决?代码如下:

 package com.bango.chdebug;

import java.util.ArrayList;
import java.util.UUID;

import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ListView;
import android.widget.TextView;

public class VoteListFragment extends ListFragment {
    private ArrayList<MediaItem> myML;
    public static boolean myCheckBoxState = false;
    private ArrayList<UUID> voteList;
    private MediaItem temp;
    private int maxVote = 0;
    private CheckBox voteBox;
    public static String VOTE_KEY = "vote";
    public String TAG = "NewMediaList";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        temp = new MediaItem();
        if(savedInstanceState != null){
        myCheckBoxState = savedInstanceState.getBoolean(VOTE_KEY, false);
        }
        getActivity().setTitle("New Movie List");
        voteList = new ArrayList<UUID>();
        myML = MediaDB.get(getActivity()).getVoteMediaItems();
        MediaAdapter medAdapt = new MediaAdapter(myML);
        setListAdapter(medAdapt);
    }

    private class MediaAdapter extends ArrayAdapter<MediaItem> {
        public MediaAdapter(ArrayList<MediaItem> mediaItems) {
            super(getActivity(), 0, mediaItems);
            // mediaItems = parseOfficialList(mediaItems);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            if (convertView == null) {
                convertView = getActivity().getLayoutInflater().inflate(
                        R.layout.new_media_list_item, null);
            }
            temp = getItem(position);
            TextView medTitle = (TextView) convertView
                    .findViewById(R.id.vote_media_title);
            TextView medDate = (TextView) convertView
                    .findViewById(R.id.vote_media_date);
            voteBox = (CheckBox) convertView
                    .findViewById(R.id.vote_media_cb);
            medTitle.setText(temp.getMyTitle());
            voteBox.setEnabled(true);
            voteBox.setOnCheckedChangeListener(new OnCheckedChangeListener(){
                @Override
                public void onCheckedChanged(CompoundButton buttonView,
                        boolean isChecked) {
                    // TODO Auto-generated method stub
                    Log.d("onresume", "On Check called for " + temp.getMyTitle());  
                }
            });
            return convertView;
        }   
    }   
    }

【问题讨论】:

    标签: android android-fragments


    【解决方案1】:

    这个问题已经被问过很多次了,请参考listview-checkbox-troublelistview-with-checkbox-and-all-clickableget-selected-item-using-checkbox-in-listview

    绝对不能保证最后一次调用getView() 应该发生在单击的复选框上。任何文档/示例中都没有提到它,所以你不应该依赖它。 您的列表只是 查看 来显示数据。数据本身应该存储在不同的实体中。在您的代码中未使用该实体。您应该在其中存储已检查/未检查状态并将反向引用存储在视图中(例如存储中的数据位置)。

    下面是稍微修改的片段。请注意,我已将新的 checked 字段添加到 MediaItem 以存储复选框状态。如果需要,您可以使用单独的数组来存储该状态。

    public class VoteListFragment extends ListFragment {
        private ArrayList<MediaItem> myML;
        public static boolean myCheckBoxState = false;
        private ArrayList<UUID> voteList;
        private MediaItem temp;
        private int maxVote = 0;
        private CheckBox voteBox;
        public static String VOTE_KEY = "vote";
        public String TAG = "NewMediaList";
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            // TODO Auto-generated method stub
            super.onCreate(savedInstanceState);
            temp = new MediaItem("item");
            if(savedInstanceState != null){
                myCheckBoxState = savedInstanceState.getBoolean(VOTE_KEY, false);
            }
            getActivity().setTitle("New Movie List");
            voteList = new ArrayList<UUID>();
            myML = getVoteMediaItems(getActivity());
            MediaAdapter medAdapt = new MediaAdapter(myML);
            setListAdapter(medAdapt);
        }
    
        private ArrayList<MediaItem> getVoteMediaItems(final Activity activity) {
            final ArrayList<MediaItem> items = new ArrayList<MediaItem>();
    
            for (int i = 0; i < 100; i++) {
                items.add(new MediaItem(String.valueOf(i) + " item"));
            }
    
            return items;
        }
    
        private class MediaAdapter extends ArrayAdapter<MediaItem> {
    
            private CompoundButton.OnCheckedChangeListener mCheckedListener = new CompoundButton.OnCheckedChangeListener(){
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    Integer position = (Integer) buttonView.getTag();
    
                    if (position != null) {
                        Toast.makeText(getActivity(), "On Check called for " + getItem(position).getMyTitle(), Toast.LENGTH_LONG).show();
                        getItem(position).checked = isChecked;
                    }
                }
            };
    
            public MediaAdapter(ArrayList<MediaItem> mediaItems) {
                super(getActivity(), 0, mediaItems);
                // mediaItems = parseOfficialList(mediaItems);
            }
    
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                // TODO Auto-generated method stub
                if (convertView == null) {
                    convertView = getActivity().getLayoutInflater().inflate(
                            R.layout.new_media_list_item, null);
                }
    
                temp = getItem(position);
    
                // Consider using of ViewHolder pattern instead of call findViewById() to improve performance
                TextView medTitle = (TextView) convertView
                        .findViewById(R.id.vote_media_title);
                TextView medDate = (TextView) convertView
                        .findViewById(R.id.vote_media_date);
                voteBox = (CheckBox) convertView
                        .findViewById(R.id.vote_media_cb);
                medTitle.setText(temp.getMyTitle());
                voteBox.setEnabled(true);
                voteBox.setOnCheckedChangeListener(null);
                voteBox.setChecked(temp.checked);
                voteBox.setTag(position);
    
                voteBox.setOnCheckedChangeListener(mCheckedListener);
                return convertView;
            }
        }
    
        public class MediaItem {
            private String myTitle;
            // Newly added field
            private boolean checked = false;
    
            MediaItem(String title) {
                myTitle = title;
            }
    
            public String getMyTitle() {
                return myTitle;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-07
      • 1970-01-01
      • 2011-03-15
      • 1970-01-01
      • 2011-11-02
      • 2011-10-11
      相关资源
      最近更新 更多