可选中显示错误的项目中选择(使用simpleCursor +自定义布局) [英] Checkable displaying wrong items selected ( used simpleCursor + custom layout)

查看:96
本文介绍了可选中显示错误的项目中选择(使用simpleCursor +自定义布局)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的自定义列表视图的一个问题,这似乎是显示了当我搜索我的列表视图中选择内容的错误项。 (检查截图下面你就明白了)


  1. 搜索名称为AA和选择两行(AABBCCC和AABC)


  2. 我已经搜索与钠却没有选择行(亚娜和Nathan)。但它显示为选中状态。


  3. 删除所有的搜索项目,我删除搜索后没有选择任何行。这是为了显示两行(AABBCC和AABC),但它显示了错误的行亚娜。


我不如何覆盖上述行为。我有一个基于_rowid没有位置,使接触,可检查的。

哪个类将跟踪列表中选定的项目?如何覆盖上述行为??

这有两行名称和编号。
我已经定制我的布局(下文code)在实现可检查。

 搜索名称(EditText上)[完成BTN]
---------------------------------------
Contact_name_1
电话号码
---------------------------------------
Contact_name_2
Phone_no2
---------------------------------------
Contact_name_3
Phone_no3
---------------------------------------

自定义布局,可检查的项目。

 公共类CustomCheckableLists扩展RelativeLayout的实现可勾选{ 私人可勾选mCheckable;公共CustomCheckableLists(上下文的背景下){
    超级(上下文);
}公共CustomCheckableLists(上下文的背景下,ATTRS的AttributeSet)
{
    超(背景下,ATTRS);
}公共布尔器isChecked(){
    返回mCheckable == NULL?假:mCheckable.isChecked();
    //返回false;
}公共无效setChecked(布尔选中){
    如果(mCheckable!= NULL)
        mCheckable.setChecked(选中);
}公共无效切换(){
     如果(mCheckable!= NULL)
            mCheckable.toggle();
}@覆盖
保护无效onFinishInflate(){
    super.onFinishInflate();    //查找物品ID ..    Log.w(onFinishInflate,onFinishInflate);    //查找勾选的孩子
    INT childCount = getChildCount();
    的for(int i = 0; I< childCount ++我){
        视图V = getChildAt(I)
        如果(V的instanceof可勾选){
            mCheckable =(可勾选)V;
            打破;
        }
    }
}

自定义XML布局

 < CustomCheckableLists
    的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:layout_width =FILL_PARENT
    机器人:layout_height =机器人:ATTR /列表preferredItemHeight
    机器人:重力=center_vertical
      机器人:方向=横向
    >    <的TextView
    机器人:ID =@ + D / I
    机器人:layout_width =WRAP_CONTENT
    机器人:layout_height =WRAP_CONTENT
    机器人:文字=名
    机器人:知名度=隐形
    />    <的TextView
    机器人:ID =@ + ID / text1中
    机器人:layout_width =WRAP_CONTENT
    机器人:layout_height =WRAP_CONTENT
    机器人:文字=nuoo
    />    < CheckedTextView的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:ID =@ + ID / phonenu
    机器人:layout_width =FILL_PARENT
    机器人:layout_height =WRAP_CONTENT
    安卓:勾选=机器人:ATTR / textCheckMark
    机器人:重力=center_vertical
    机器人:paddingLeft =3DP
    机器人:paddingRight =6DP
    机器人:paddingTop =25dip
    />< / CustomCheckableLists>

联系人活动类

 的String [] =列新的String [] {
            ContactsContract.Contacts._ID,
            ContactsContract.Contacts.DISPLAY_NAME,
                ContactsContract.CommonDataKinds.Phone.NUMBER
    };    INT []为= INT新[] {
            R.id.id,
            R.id.text1,
            R.id.phonenu
    };    DataAdapter的=新SimpleCursorAdapter(这一点,R.layout.custom_checkable_item,光标,列于);
    listView.setAdapter(DataAdapter的);

任何帮助是AP preciated。先谢谢了。

修改

每当为任何名称,一个查询已经形成用户搜索返回搜索结果。
code以下

  searchNameOrNumber =(EditText上)findViewById(R.id.searchText);
    sea​​rchNameOrNumber.addTextChangedListener(新TextWatcher()
    {
        公共无效onTextChanged(CharSequence的搜索关键词,诠释开始,诠释之前,诠释计数){
            Log.w(文本搜索..,+搜索关键词);
            。dataAdapter.getFilter()过滤(searchterm.toString());
            //dataAdapter.notifyDataSetChanged();
        }        公共无效beforeTextChanged(CharSequence中,诠释开始,诠释计数,
                INT后){
        }
        公共无效afterTextChanged(编辑S){
        }
    });    dataAdapter.setFilterQueryProvider(新FilterQueryProvider(){
        公共光标runQuery(CharSequence的约束){
            Log.w(搜索查询..,constraint.toString());
            );
            返回getSearchedContacts(constraint.toString());
        }
    });
公共光标getSearchedContacts(字符串inputText的)
{
    Log.w(inputText的inputText的);
        URI URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
        的String [] =投影新的String [] {
                ContactsContract.Contacts._ID,
                ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
                   ContactsContract.CommonDataKinds.Phone.NUMBER
        };
        字符串选择= ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME +LIKE'%+的inputText +%';        光标人= getContentResolver()查询(URI,投影,选择,NULL,NULL);        INT INDEXNAME = people.getColumnIndex(StructuredName.DISPLAY_NAME);
        INT indexNumber = people.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
        INT idIdx = people.getColumnIndexOrThrow(PhoneLookup._ID);        如果(!people.moveToFirst())
        {
            Log.w(没有光标..,,无光标..,光标是空的。);
        }        做{
            字符串ID = people.getString(idIdx);
            字符串名称= people.getString(INDEXNAME);
            串号= people.getString(indexNumber);
            // 做工作...
        }而(people.moveToNext());        返回的人;
}


解决方案

您需要创建一个自定义的适配器和跟踪检查的项目有。你看到这种现象的原因是因为 SimpleCursorAdapter 是回收的意见,不知道如何处理的选中状态,只是设置文本标签,留下的选中状态,因为它以前。

要查看此行为的另一种方式是具有比项目一屏多了,查了一些然后滚动,你也会发现,随机项目将选中/取消当滚动。

您可以查看如何得到这个工作,这个答案一个完整的样本。

如果您在使用本为每次筛选你将必须清除检查位置的列表时间寻找呢。

I have a problem in my custom listview which seems to be showing wrong items selected when i search content of my list view. (check screenshots below you will understand)

  1. searched with name aa and selected two rows(AABBCCC and AABC)

  2. I have searched with Na but didn't select the rows (Jana and Nathan). But it is showing as selected.

  3. Removed all the search items, and i didn't select any rows after removing search. It is supposed to show two rows( AABBCC and AABC), but it is showing up the wrong row Jana.

I don't how to override the above behaviour. I have to make contact as checkable based on _rowid not the position.

Which class will keep track of the items selected in the list ? How to override the above behaviour??

It has two rows Name and number. I have customized my layout(code below) which implements checkable.

Search Name(EditText)        [Done Btn]
---------------------------------------
Contact_name_1         
Phone_no
---------------------------------------
Contact_name_2         
Phone_no2
---------------------------------------
Contact_name_3         
Phone_no3
---------------------------------------

Custom layout with checkable items..

public class CustomCheckableLists extends RelativeLayout implements Checkable {

 private Checkable mCheckable;

public CustomCheckableLists(Context context) {
    super(context);
}

public CustomCheckableLists(Context context, AttributeSet attrs)
{
    super(context,attrs);
}

public boolean isChecked() {
    return mCheckable == null ? false : mCheckable.isChecked();
    //return false;
}

public void setChecked(boolean checked) {
    if(mCheckable != null)
        mCheckable.setChecked(checked);


}

public void toggle() {
     if(mCheckable != null)
            mCheckable.toggle();
}

@Override
protected void onFinishInflate() {
    super.onFinishInflate();

    //Find items id..

    Log.w("onFinishInflate","onFinishInflate");

    // Find Checkable child
    int childCount = getChildCount();
    for (int i = 0; i < childCount; ++i) {
        View v = getChildAt(i);
        if (v instanceof Checkable) {
            mCheckable = (Checkable) v;
            break;
        }
    }
}

Custom XML Layout

<CustomCheckableLists
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:gravity="center_vertical" 
      android:orientation="horizontal"
    >

    <TextView 
    android:id="@+id/id"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="name" 
    android:visibility="invisible"
    />

    <TextView 
    android:id="@+id/text1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="nuoo" 
    />

    <CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/phonenu"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:checkMark="?android:attr/textCheckMark"
    android:gravity="center_vertical"
    android:paddingLeft="3dp"
    android:paddingRight="6dp"
    android:paddingTop="25dip"
    />

</CustomCheckableLists>

Contact Activity Class

    String[] columns = new String[] {
            ContactsContract.Contacts._ID,
            ContactsContract.Contacts.DISPLAY_NAME,
                ContactsContract.CommonDataKinds.Phone.NUMBER
    };

    int[] to = new int[] {
            R.id.id,
            R.id.text1,
            R.id.phonenu
    };

    dataAdapter = new SimpleCursorAdapter(this, R.layout.custom_checkable_item, cursor, columns, to);
    listView.setAdapter(dataAdapter);

any help is appreciated. Thanks in advance.

Edit

Whenever user searches for any name, a query has been formed to return the searched result. code below

 searchNameOrNumber = (EditText) findViewById(R.id.searchText);
    searchNameOrNumber.addTextChangedListener(new TextWatcher() 
    {
        public void onTextChanged(CharSequence searchterm, int start, int before, int count) {
            Log.w("Text Searched.. ", " " + searchterm);
            dataAdapter.getFilter().filter(searchterm.toString());
            //dataAdapter.notifyDataSetChanged();
        }

        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {
        }
        public void afterTextChanged(Editable s) {
        }
    });

    dataAdapter.setFilterQueryProvider(new FilterQueryProvider() {
        public Cursor runQuery(CharSequence constraint) {
            Log.w("Searched Query..,", constraint.toString());
            );


            return getSearchedContacts(constraint.toString());
        }
    });


public Cursor getSearchedContacts(String inputText)
{
    Log.w("inputText",inputText);
        Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
        String[] projection = new String[] {
                ContactsContract.Contacts._ID, 
                ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
                   ContactsContract.CommonDataKinds.Phone.NUMBER
        };
        String selection = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " like '%" + inputText + "%'";

        Cursor people = getContentResolver().query(uri, projection, selection, null, null);

        int indexName = people.getColumnIndex(StructuredName.DISPLAY_NAME);
        int indexNumber = people.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
        int idIdx = people.getColumnIndexOrThrow(PhoneLookup._ID);

        if(!people.moveToFirst())
        {
            Log.w("No Cursor.., ","No cursor.., Cursor is empty..");
        }

        do {
            String id = people.getString(idIdx);
            String name   = people.getString(indexName);
            String number = people.getString(indexNumber);
            // Do work...
        } while (people.moveToNext());

        return people;


}

解决方案

You need to create a custom Adapter and track the checked items there. The reason you're seeing this behavior is because the SimpleCursorAdapter is recycling the views, and doesn't know how to deal with the checked state, and just sets the text labels, leaving the checked state as it was before.

Another way to see this behavior is having more than a screenful of items, check some and then scroll and you would also notice that random items get checked/unchecked as you scroll.

You can view a complete sample of how to get this working in this answer.

If you're using this for searching then every time you filter you will have to clear the list of checked positions.

这篇关于可选中显示错误的项目中选择(使用simpleCursor +自定义布局)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆