自定义listView多选

时间:2012-01-17 05:52:49

标签: android

我正在开发Listview,可以进行多项选择,现在的问题是当我向下或向上滚动选项丢失并在除选定项目之外的任何其他项目上进行选择时。

以下是我的活动。

  public class ContactPickerActivity extends Activity {

    private ArrayList<Contact> arr = new ArrayList<Contact>();
    private Context context;
    private ListView list;
    private ContactArrayAdapter adapter;
    private String strName,strNumber;
    private View view;  
    public static ArrayList<Boolean> arrBoolean = new ArrayList<Boolean>();

    @Override
    public void onCreate(Bundle savedInstance) {
        super.onCreate(savedInstance);
        setContentView(R.layout.contact_picker);
        ProgressDialog pd  = new ProgressDialog(this);
        list = (ListView)findViewById(R.id.contactList);
        arr = new ArrayList<Contact>();
        context = ContactPickerActivity.this;
        arr =  displayContacts();
        Log.i("ContactPicker", "Completed Displaying Contact list ::: " + arr.size());
        adapter = new ContactArrayAdapter(this,arr);
        list.setAdapter(adapter);
//              list.setAdapter(new ArrayAdapter<String>(this,
//                      android.R.layout.simple_list_item_multiple_choice, listContent));
        list.setOnItemClickListener(ContactSelectedListener);
        Log.i("Boolaean >>> ", arrBoolean.size() + "");


    }

    private OnItemClickListener ContactSelectedListener = new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View arg1, int arg2,long arg3) {
            Log.i("ListViewTest","Item Click");
            SparseBooleanArray checked = list.getCheckedItemPositions();
            for (int i = 0; i < arr.size(); i++) {
                Log.i("ListViewTest", arr.get(i)+ ": " + checked.get(i));
            }
        }
    };

    private ArrayList<Contact> displayContacts() {

        ContentResolver cr = getContentResolver();
        Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null);
        Contact contact;
        if (cur.getCount() > 0) {
            while (cur.moveToNext()) {
                contact = new Contact();
                String id = cur.getString(cur.getColumnIndex(People._ID));
                String name = cur.getString(cur.getColumnIndex(People.DISPLAY_NAME));
                contact.setName(name);
                arr.add(contact);
            }
        }
        return arr;
    }
}
********* Adapter *****

public class ContactArrayAdapter extends BaseAdapter {

//  private final List<Contact> list;
    private Context context;    

    private LayoutInflater mInflater;
    private List<Contact> list; 

     public ContactArrayAdapter(Context context,ArrayList<Contact> arrPublicData) {

        this.mInflater = LayoutInflater.from(context);
        this.list = arrPublicData;
    }

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

    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        View view = convertView;
        final ViewHolder viewHolder;
        if (view == null) {         
            view = mInflater.inflate(R.layout.multiselect_row, null);
            viewHolder = new ViewHolder();
            viewHolder.text = (TextView) view.findViewById(R.id.txtItem);
            viewHolder.checkbox = (CheckBox) view.findViewById(R.id.chkItem);

            viewHolder.checkbox
            .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                    Contact element = (Contact) viewHolder.checkbox.getTag();
                    element.setSelected(buttonView.isChecked());
                    ContactPickerActivity.arrBoolean.add(buttonView.isChecked());
                    Log.i("Boolaean 123 >>> ", buttonView.isChecked() + "");
                }
            });
            view.setTag(viewHolder);
            viewHolder.checkbox.setTag(list.get(position));
        } else {
            viewHolder = (ViewHolder) view.getTag();
            ((ViewHolder) view.getTag()).checkbox.setTag(list.get(position));
        }
        ViewHolder holder = (ViewHolder) view.getTag();
        holder.text.setText(list.get(position).getName());
        holder.checkbox.setChecked(list.get(position).isSelected());        
        return view;
    }

    static class ViewHolder {
    protected TextView text;
    protected CheckBox checkbox;
}

我无法检查物品.... 任何帮助都是明确的...... Thanx提前

5 个答案:

答案 0 :(得分:5)

http://www.marvinlabs.com/2010/10/custom-listview-ability-check-items/

检查这个

被修改

holder.chkField.setChecked(true);
holder.chkField.setTag(R.id.chkItem, position);
check.add(position, true);   

您需要将其更改为

if(check.getAt(position)){ 
   holder.chkField.setChecked(true);
}else{
   holder.chkField.setChecked(false);
}
holder.chkField.setTag(R.id.chkItem, position);

将检查条件下的检查侦听器放在下面的行中为true或false

check.add(position, isChecked);          

答案 1 :(得分:2)

公共类ListAdapter扩展了BaseAdapter {

private LayoutInflater mInflater;
private ArrayList<String> arrPublicData;    
private int checkCount = 0;
private ArrayList<Boolean> check = new ArrayList<Boolean>();

 public ListAdapter(Context context,ArrayList<String> arrPublicData) {

    this.mInflater = LayoutInflater.from(context);
    this.arrPublicData = arrPublicData;
    checkCount = arrPublicData == null ? 0 : arrPublicData.size();
}

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

public Object getItem(int position) {
    return position;
}

public long getItemId(int position) {
    return position;
}

public View getView(int position, View convertView, ViewGroup parent) {
    final ViewHolder holder;
    View rowView = convertView;

    if (rowView == null) {
        rowView = mInflater.inflate(R.layout.multiselect_row, null);
        holder = new ViewHolder();

        holder.txtField = (TextView) rowView.findViewById(R.id.txtItem);
        holder.chkField = (CheckBox) rowView.findViewById(R.id.chkItem);
        holder.chkField.setOnCheckedChangeListener(checkedChangeListener);
        holder.chkField.setChecked(true);
        holder.chkField.setTag(R.id.chkItem, position);
        check.add(position, true);      
        rowView.setTag(holder);

    } else {
        holder = (ViewHolder) rowView.getTag();
    }

    holder.txtField.setText(arrPublicData.get(position));    
    if(check.get(position) == true)
    {
       holder.chkField.setText(arrPublicData.get(position));    
    }
    else
    {
       holder.chkField.setText(arrPublicData.get(position));    
    }       

    return rowView;
}

类ViewHolder {     TextView txtField;     CheckBox chkField; }

我认为您没有检查条件是否选中了复选框,因此当您滚动列表视图时,您的复选框会发生变化希望有帮助

答案 2 :(得分:1)

问题在于你的getView方法,请按如下方式更正:

    public class ContactPickerActivity extends Activity {

    private ArrayList<Contacts> arr = new ArrayList<Contacts>();
    private Context context;
    private ListView list;
    private ContactArrayAdapter adapter;
    private String strName,strNumber;
    private View view;  
    public static boolean[] arrBoolean = null;

    @Override
    public void onCreate(Bundle savedInstance) {
        super.onCreate(savedInstance);
        //setContentView(R.layout.contact_picker);
        ProgressDialog pd  = new ProgressDialog(this);
        list = (ListView)findViewById(R.id.contactList);
        arr = new ArrayList<Contact>();
        context = ContactPickerActivity.this;
        arr =  displayContacts();
        arrBoolean=new boolean[arr.size()];
        Arrays.fill(arrBoolean, false);
        Log.i("ContactPicker", "Completed Displaying Contact list ::: " + arr.size());
        adapter = new ContactArrayAdapter(this,arr);
        list.setAdapter(adapter);
//              list.setAdapter(new ArrayAdapter<String>(this,
//                      android.R.layout.simple_list_item_multiple_choice, listContent));
        list.setOnItemClickListener(ContactSelectedListener);
        Log.i("Boolaean >>> ", arrBoolean.size() + "");


    }

    private OnItemClickListener ContactSelectedListener = new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View arg1, int position,long arg3) {
            Log.i("ListViewTest","Item Click");
            arrBoolean[position]=!arrBoolean[position];
            adapter.notifyDataSetChanged();
        }
    };

    private ArrayList<Contacts> displayContacts() {

        ContentResolver cr = getContentResolver();
        Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null);
        Contacts contact;
        if (cur.getCount() > 0) {
            while (cur.moveToNext()) {
                contact = new Contacts();
                String id = cur.getString(cur.getColumnIndex(People._ID));
                String name = cur.getString(cur.getColumnIndex(People.DISPLAY_NAME));
                contact.setName(name);
                arr.add(contact);
            }
        }
        return arr;
    }
}
//********* Adapter *****

public class ContactArrayAdapter extends BaseAdapter {

//  private final List<Contact> list;
    private Context context;    

    private LayoutInflater mInflater;
    private List<Contacts> list; 

     public ContactArrayAdapter(Context context,ArrayList<Contact> arrPublicData) {

        this.mInflater = LayoutInflater.from(context);
        this.list = arrPublicData;
    }

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

    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        View view = convertView;
        final ViewHolder viewHolder;
        if (view == null) {         
            view = mInflater.inflate(R.layout.multiselect_row, null);
            viewHolder = new ViewHolder();
            viewHolder.text = (TextView) view.findViewById(R.id.txtItem);
            viewHolder.checkbox = (CheckBox) view.findViewById(R.id.chkItem);


            view.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) view.getTag();
        }
        ViewHolder holder = (ViewHolder) view.getTag();
        holder.text.setText(list.get(position).getName());
        holder.checkbox.setChecked(ContactPickerActivity.arrBoolean[position]);        
        return view;
    }

    static class ViewHolder {
    protected TextView text;
    protected CheckBox checkbox;
}

答案 3 :(得分:0)

它的发生是因为你多次用同一个id夸大了一个复选框。因此,请按以下方式修改您的代码,

  1. 在Xml中添加 TableRow / LinearLayout 代替 checkBox

  2. {li>

    getView方法中,在运行时创建一个CheckBox,并将其ID设置为位置(列表位置),并使用{将其添加到xml中的T​​ableRow / LinearLayout {1}}方法。

  3. 现在如果问题仍然存在,在 CheckChanged Listener 中创建Vector并在向量中添加已检查项目的位置,并在创建checkBox时检查Vector是否为当前视图位置选中然后使用addView()方法进行检查。

  4. 可能我不清楚,但我不知道更好的解释方法。

答案 4 :(得分:0)

我创建了一个示例程序,其中我根据行的状态设置视图的背景颜色,只需更改后台代码以检查状态;

public class SampleActivity extends Activity {
    private String[] arrItems={"A", "B", "C", "D", "E"};
    private boolean[] arrState={false, false, false, false, false};
    private ListView lv;
    private ArrAdapter adapter;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        lv=(ListView) findViewById(R.id.lvTest);
        adapter=new ArrAdapter(this);
        lv.setAdapter(adapter);
        lv.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position,
                    long id) {
                // TODO Auto-generated method stub
                arrState[position]=!arrState[position];
                adapter.notifyDataSetChanged();
            }
        });

    }

    private class ArrAdapter extends ArrayAdapter<String>
    {
        Context mContext=null;
        public ArrAdapter(Context context) {
            super(context, R.layout.row);
            // TODO Auto-generated constructor stub
            mContext=context;
        }

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return arrItems.length;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            View vi=convertView;
            ViewHolder holder=null;
            if(vi==null)
            {
                vi=LayoutInflater.from(mContext).inflate(R.layout.row, parent, false);
                holder=new ViewHolder();
                holder.mTxt=(TextView) vi.findViewById(R.id.text1);
                vi.setTag(holder);
            }
            else
                holder=(ViewHolder) vi.getTag();
            holder.mTxt.setText(arrItems[position]);
            if(arrState[position])
                vi.setBackgroundColor(Color.BLUE);
            else
                vi.setBackgroundColor(Color.WHITE);
            return super.getView(position, convertView, parent);
        }


        private class ViewHolder
        {
            TextView mTxt=null;
        }


    }

    private void clear()
    {
        Arrays.fill(arrState, false);
        adapter.notifyDataSetChanged();
    }
}