Android - 自定义AutoCompleteTextView CursorAdaptor - 建议行为

时间:2012-05-01 00:56:37

标签: android autocompletetextview android-cursoradapter

我正在尝试实施自定义AutoCompleteTextView,用于从显示联系人姓名,电话号码类型和电话号码的建议列表中选择联系人的电话号码。我创建了一个自定义CursorAdapter,它为每个建议定义和设置我的Layout和TextViews,并通过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 here enter image description here

我已经阅读了我在这里和其他地方可以找到的每个问题,但似乎无法弄清楚这一点。我是Android开发的新手,所以如果我的错误很简单,我会提前道歉。提前谢谢!

2 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分: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");
}

}

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