Android 可检查显示所选的错误项目(使用simpleCursor+;自定义布局)

Android 可检查显示所选的错误项目(使用simpleCursor+;自定义布局),android,listview,Android,Listview,我的自定义listview中有一个问题,当我搜索列表视图的内容时,它似乎显示了错误的所选项目。(查看下面的屏幕截图,您将了解) 使用名称aa搜索并选择两行(AABBCCC和AABC) 我用Na搜索过,但没有选择行(Jana和Nathan)。但它显示为选中状态 删除了所有搜索项,删除搜索后我没有选择任何行。它应该显示两行(AABBCC和AABC),但它显示的是错误的行Jana 我不知道如何克服上述行为。我必须根据rowid而不是职位进行联系。 哪个类将跟踪列表中选定的项目?如何覆盖上述行为???

我的自定义listview中有一个问题,当我搜索列表视图的内容时,它似乎显示了错误的所选项目。(查看下面的屏幕截图,您将了解)

  • 使用名称aa搜索并选择两行(AABBCCC和AABC)

  • 我用Na搜索过,但没有选择行(Jana和Nathan)。但它显示为选中状态

  • 删除了所有搜索项,删除搜索后我没有选择任何行。它应该显示两行(AABBCC和AABC),但它显示的是错误的行Jana

  • 我不知道如何克服上述行为。我必须根据rowid而不是职位进行联系。

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

    它有两行名称和编号。 我已经定制了我的布局(下面的代码),它实现了checkable

    Search Name(EditText)        [Done Btn]
    ---------------------------------------
    Contact_name_1         
    Phone_no
    ---------------------------------------
    Contact_name_2         
    Phone_no2
    ---------------------------------------
    Contact_name_3         
    Phone_no3
    ---------------------------------------
    
    带有可检查项的自定义布局..

    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;
            }
        }
    }
    
    感谢您的帮助。提前谢谢

    编辑

    <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>
    
    每当用户搜索任何名称时,都会形成一个查询以返回搜索结果。 代码如下

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

    您需要创建一个自定义适配器并在那里跟踪选中的项。您看到这种行为的原因是,
    SimpleCursorAdapter
    正在回收视图,不知道如何处理选中状态,只设置文本标签,保持选中状态与以前一样

    查看此行为的另一种方式是使用多个项目屏幕,选中一些项目,然后滚动,您还会注意到在滚动时随机项目会被选中/取消选中

    您可以查看如何使其工作的完整示例

    如果您使用此选项进行搜索,则每次筛选时都必须清除选中位置的列表

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