安卓 - 自定义AutoCompleteTextView CursorAdapter - 建议行为

5
我正在尝试实现一个自定义的AutoCompleteTextView,用于从建议列表中选择联系人电话号码,并显示联系人姓名、电话号码类型和电话号码。 我创建了一个自定义的CursorAdapter,为每个建议定义和设置了我的布局和TextView,并通过runQueryOnBackgroundThread根据用户输入的文本查询联系人。 我遇到的问题是,对于前两个输入值(例如“ab”建议“abcd”和“abyz”),建议似乎是正确的,但对于任何超出此范围的值(例如“abc”建议“abyz”),建议就不正确了。 对于后者,当选择“abyz”建议时,会返回“abcd”的值。

主活动的代码:

final ContactInfo cont = new ContactInfo(ctx);
    Cursor contacts = cont.getContacts2(null);
    startManagingCursor(contacts);

    ContactsAutoCompleteCursorAdapter adapter = new ContactsAutoCompleteCursorAdapter(this, contacts);
    mPersonText.setAdapter(adapter);
    mPersonText.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
            long arg3) {
            Cursor cursor = (Cursor) arg0.getItemAtPosition(arg2);
            String number = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
            mPersonNum.setText(number);
        }
    });

以下是返回所有联系人光标的联系人类代码:

public Cursor getContacts2(String where)
{
    Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
    String[] projection = new String[] {
            ContactsContract.CommonDataKinds.Phone._ID,
            ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
            ContactsContract.CommonDataKinds.Phone.TYPE,
            ContactsContract.CommonDataKinds.Phone.NUMBER};

    Cursor people = ctx.getContentResolver().query(uri, projection, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " COLLATE LOCALIZED ASC");

    return people;
}

我的CursorAdapter代码:

public class ContactsAutoCompleteCursorAdapter extends CursorAdapter implements Filterable {

private TextView mName, mType, mNumber;
private ContentResolver mContent;

public ContactsAutoCompleteCursorAdapter(Context context, Cursor c) {
    super(context, c);
    mContent = context.getContentResolver();
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {

    final LayoutInflater mInflater = LayoutInflater.from(context);
    final View ret = mInflater.inflate(R.layout.contacts_auto_list, null);

    mName = (TextView) ret.findViewById(R.id.name);
    mType = (TextView) ret.findViewById(R.id.phonetype);
    mNumber = (TextView) ret.findViewById(R.id.phonenum);

    return ret;
}

@Override
public void bindView(View view, Context context, Cursor cursor) {

    int nameIdx = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
    int typeIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
    int numberIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);

    String name = cursor.getString(nameIdx);
    int type = cursor.getInt(typeIdx);
    String number = cursor.getString(numberIdx);

    mName.setText(name);
    if (type == 1) {mType.setText("Home");}
    else if (type == 2) {mType.setText("Mobile");}
    else if (type == 3) {mType.setText("Work");}
    else {mType.setText("Other");}
    mNumber.setText(number);

}

@Override
public String convertToString(Cursor cursor) {
    int nameCol = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
    String name = cursor.getString(nameCol);
    return name;
}

@Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
    // this is how you query for suggestions
    // notice it is just a StringBuilder building the WHERE clause of a cursor which is the used to query for results
    if (getFilterQueryProvider() != null) { return getFilterQueryProvider().runQuery(constraint); }

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

    return mContent.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection, 
            "UPPER(" + ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + ") LIKE '" + constraint.toString().toUpperCase() + "%'", null, 
            ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
}

如上所述,当用户在AutoCompleteTextView中输入“ab”时,建议的内容为“abcd”和“abyz”,但是当用户输入“abc”时,建议的内容只有“abyz”。在这种情况下,如果用户选择“abyz”,则会返回“abcd”的值。以下是两个截图,展示了我试图描述的内容:

enter image description hereenter image description here

我已经阅读了这里和其他地方能够找到的所有问题,但似乎无法解决这个问题。我对Android开发还比较新,因此如果我的错误很简单,请提前谅解。谢谢!

2个回答

2

经过更多的研究,我似乎已经回答了自己的问题。将textViews视图设置从newView函数移动到bindView函数似乎已经解决了问题,这样做似乎是有道理的...

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {

    final LayoutInflater mInflater = LayoutInflater.from(context);
    final View ret = mInflater.inflate(R.layout.contacts_auto_list, null);

    return ret;
}

@Override
public void bindView(View view, Context context, Cursor cursor) {

    int nameIdx = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
    int typeIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
    int numberIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);

    String name = cursor.getString(nameIdx);
    int type = cursor.getInt(typeIdx);
    String number = cursor.getString(numberIdx);

    mName = (TextView) view.findViewById(R.id.name);
    mType = (TextView) view.findViewById(R.id.phonetype);
    mNumber = (TextView) view.findViewById(R.id.phonenum);

    mName.setText(name);
    if (type == 1) {mType.setText("Home");}
    else if (type == 2) {mType.setText("Mobile");}
    else if (type == 3) {mType.setText("Work");}
    else {mType.setText("Other");}
    mNumber.setText(number);
}

0

你的适配器中已经有了public Cursor runQueryOnBackgroundThread函数,因此你不需要在活动中再次调用游标。

你不需要使用getContacts2函数。

活动

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.sms_send);

    Cursor contacts = null;

    mAdapter= new ContactsAutoCompleteCursorAdapter(this, contacts);
    mTxtPhoneNo = (AutoCompleteTextView) findViewById(R.id.mmWhoNo);
    mTxtPhoneNo.setAdapter(mAdapter);

    mTxtPhoneNo.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {
            // TODO Auto-generated method stub
            Cursor cursor = (Cursor) arg0.getItemAtPosition(arg2);
            String number = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
            mTxtPhoneNo.setText(number);

        }
    });


}

适配器

public class ContactsAutoCompleteCursorAdapter extends CursorAdapter implements Filterable {

private TextView mName, mType, mNumber;
private ContentResolver mContent;

public ContactsAutoCompleteCursorAdapter(Context context, Cursor c) {
    super(context, c);
    mContent = context.getContentResolver();
}




@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {

    final LayoutInflater mInflater = LayoutInflater.from(context);
    final View ret = mInflater.inflate(R.layout.custcontview, null);

    return ret;
}

@Override
public void bindView(View view, Context context, Cursor cursor) {

    int nameIdx = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
    int typeIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
    int numberIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);

    String name = cursor.getString(nameIdx);
    int type = cursor.getInt(typeIdx);
    String number = cursor.getString(numberIdx);

    mName = (TextView) view.findViewById(R.id.ccontName);
    mType = (TextView) view.findViewById(R.id.ccontType);
    mNumber = (TextView) view.findViewById(R.id.ccontNo);

    mName.setText(name);
    if (type == 1) {mType.setText("Home");}
    else if (type == 2) {mType.setText("Mobile");}
    else if (type == 3) {mType.setText("Work");}
    else {mType.setText("Other");}
    mNumber.setText(number);
}


@Override
public String convertToString(Cursor cursor) {
    int nameCol = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
    String name = cursor.getString(nameCol);
    return name;
}




@Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
    // this is how you query for suggestions
    // notice it is just a StringBuilder building the WHERE clause of a cursor which is the used to query for results



if (constraint==null)
    return null;

    if (getFilterQueryProvider() != null) { return getFilterQueryProvider().runQuery(constraint); }

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

    return mContent.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection, 
            "UPPER(" + ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + ") LIKE '%" + constraint.toString().toUpperCase() + "%' or UPPER(" + ContactsContract.CommonDataKinds.Phone.NUMBER + ") LIKE '%" + constraint.toString().toUpperCase() + "%' ", null, 
            ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
}

}

我也在查询中添加了电话号码搜索查询


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接