5

我正在尝试实现自定义 AutoCompleteTextView,以便从显示联系人姓名、电话号码类型和电话号码的建议列表中选择联系人的电话号码。我创建了一个自定义 CursorAdapter,它为每个建议定义和设置我的布局和 TextView,并根据用户通过 runQueryOnBackgroundThread 输入的文本查询联系人。我遇到了一个问题,其中输入的前两个值的建议似乎正确(例如“ab”建议“abcd”和“abyz”),但除此之外的任何内容(例如“abc”建议“abyz”)。For the latter, when the "abyz" suggestion is selected, the values for "abcd" are returned.

主要活动的代码:

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”的值。这是两个屏幕截图,显示了我要描述的内容:

在此处输入图像描述在此处输入图像描述

我已经阅读了在这里和其他地方可以找到的所有问题,但似乎无法弄清楚这一点。我对Android开发相当陌生,所以如果我的错误很简单,我提前道歉。提前致谢!

4

2 回答 2

2

I seem to have answered my own question after more research. Moving the setting of the views for my textViews from the newView function to the bindView function seems to have done the trick, which I think makes sense...

@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);
}
于 2012-05-03T03:34:25.733 回答
0

您的适配器中已经有公共 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");
}

}

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

于 2014-11-30T16:26:08.233 回答