自动补全功能是app比较友好的功能之一,但利用AutoCompleteTextView自动补全文本框控件完成起来并不简单,因为其中涉及到AutoCompleteTextView填充数据的适配器,与AutoCompleteTextView的监听器。同时还需要利用ContentResolver去查找设备的通讯录,当然,这与《【Android】利用安卓的数据接口、多媒体处理编写内存卡Mp3播放器app》(点击打开链接)中遍历MP3与《【Android】Sqlite数据库增删改查》(点击打开链接)中遍历Sqlite数据库是一样的。下面举一个小例子,说明AutoCompleteTextView的使用:
如上图,假设在用户手机中有3个联系人,现在有一个能自动补全的文本框,输入完名字,自动显示其在通讯录的电话。如果没有则给出相应的信息。
制作过程如下:
1、首先res\values\strings.xml字体文件,没什么好说:
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">自动补全联系人与寻找其电话</string> <string name="action_settings">Settings</string> <string name="textView1">姓名:</string> </resources>
2、之后是res\layout\activity_main.xml中的布局修改。一个垂直的线性布局中间放一个水平的线性布局,使TextView1与自动完成的文本框处于一行。之后一个显示结果的TextView2赋予id,此处的autoCompleteTextView1设定android:completionThreshold="1",是指用户输入1个字符就开始给出补全信息了。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/textView1" android:textSize="24sp" /> <AutoCompleteTextView android:id="@+id/autoCompleteTextView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:completionThreshold="1" /> </LinearLayout> <TextView android:id="@+id/textView2" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="24sp" /> </LinearLayout>
3、在AndroidManifest.xml申请读取联系人的权限
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.autocomplete" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <uses-permission android:name="android.permission.READ_CONTACTS" /><!-- 要求读取通讯录 --> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.autocomplete.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
4、MainActivity.java才是本app的重点,里面包含autoCompleteTextView自动文本框的适配器,用来填充数据的。数据是通过ContentResolver去查安卓设备中的联系人表查出来的姓名信息。之后,MainActivity本身实现TextWatcher接口,用来作为autoCompleteTextView自动文本框的监听器,当前用户选择自动补全的选项或者自己输入数据,都会给触发TextWatcher监听。根据联系人查询电话的时候,是需要同时对安卓中固有的两张表进行操作,一张是用户设备中的联系人姓名表,一张是与联系人姓名表同id排列的联系人电话表。具体代码具体如下:
package com.autocomplete; import android.net.Uri; import android.os.Bundle; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.Contacts; import android.support.v4.widget.CursorAdapter; import android.text.Editable; import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AutoCompleteTextView; import android.widget.FilterQueryProvider; import android.widget.Filterable; import android.widget.TextView; import android.app.Activity; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; //autoCompleteTextView自动文本框的适配器 class ContactListAdapter extends CursorAdapter implements Filterable { private ContentResolver resolver; private String[] columns = new String[] { Contacts._ID, Contacts.DISPLAY_NAME };// 一会儿,游标查询出来的表就两列,一列是id,一列是联系人姓名 public ContactListAdapter(Context context, Cursor c, int flags) { // 调用父类构造方法,此处ContactListAdapter(Context context, Cursor // c)方法已经过时,多出了一个参数flags // 其实都没有什么用,flags扔个0给它就OK super(context, c, flags); resolver = context.getContentResolver();// 初始化ContentResolver } // 这里要自己形成一个下拉菜单 @Override public void bindView(View view, Context arg1, Cursor cursor) { ((TextView) view).setText(cursor.getString(1)); } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { LayoutInflater inflater = LayoutInflater.from(context); TextView view = (TextView) inflater.inflate( android.R.layout.simple_dropdown_item_1line, parent, false); view.setText(cursor.getString(1));// 各项项的文字,就是游标查询出来的,联系人姓名那一列 return view; } @Override public CharSequence convertToString(Cursor cursor) { return cursor.getString(1); } @Override public Cursor runQueryOnBackgroundThread(CharSequence constraint) { FilterQueryProvider filter = getFilterQueryProvider(); if (filter != null) { return filter.runQuery(constraint); } // 这里是指明游标的查询的表,与查询结果列 Uri uri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode(constraint.toString())); return resolver.query(uri, columns, null, null, null); } } public class MainActivity extends Activity implements TextWatcher { private AutoCompleteTextView autoCompleteTextView1; private TextView textView2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 注册组件 autoCompleteTextView1 = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView1); textView2 = (TextView) findViewById(R.id.textView2); // 构造autoCompleteTextView的适配器 ContentResolver contentResolver = getContentResolver(); String[] colmuns = new String[] { Contacts._ID, Contacts.DISPLAY_NAME }; Cursor cursor = contentResolver.query(Contacts.CONTENT_URI, colmuns, null, null, null); ContactListAdapter contactListAdapter = new ContactListAdapter(this, cursor, 0); // 指明autoCompleteTextView的适配器与监听器 autoCompleteTextView1.setAdapter(contactListAdapter); autoCompleteTextView1.addTextChangedListener(this); } // 根据联系人的姓名查询电话 private String getQueryData(String name) { String phoneNum = ""; // 查联系人姓名这张表,有无用户输入的姓名 ContentResolver contentResolver1 = getContentResolver(); String[] colmuns1 = new String[] { Contacts._ID, Contacts.DISPLAY_NAME }; Cursor cursor1 = contentResolver1.query(Contacts.CONTENT_URI, null, null, null, null); for (cursor1.moveToFirst(); !(cursor1.isAfterLast()); cursor1 .moveToNext()) { String contactsName = cursor1.getString(cursor1 .getColumnIndex(colmuns1[1])); // 如果有,则开始查联系人电话这张表 if (name.equals(contactsName)) { int id = cursor1.getInt(cursor1.getColumnIndex(colmuns1[0])); ContentResolver contentResolver2 = getContentResolver(); String[] colmuns2 = new String[] { Phone.CONTACT_ID, Phone.NUMBER }; // 查询的联系人电话这张表时候,加入一个条件,就查目录联系人姓名那列数据中的id // 由于联系人电话这张表与联系人姓名这张表是同id的 // 查询参数放在第三个参数这个位置 Cursor cursor2 = contentResolver2.query(Phone.CONTENT_URI, null, colmuns2[0] + "=" + id, null, null); if (cursor2.moveToNext()) {// 如果Cursor中有数据,要把初始位置为0的Cursor下拉一位才能拿到数据 phoneNum = cursor2.getString(cursor2 .getColumnIndex(colmuns2[1])); } } } return phoneNum;// 查到就返回相应的电话,没查到就扔回0 } // autoCompleteTextView自动文本框的监听器,果断是等信息完完整整地摆到文本框才是查找 @Override public void afterTextChanged(Editable arg0) { String name = autoCompleteTextView1.getText() + ""; String phoneNum = getQueryData(name); if (phoneNum.equals("")) { textView2.setText("无此联系人!"); } else { textView2.setText("电话为:" + phoneNum); } } @Override public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub } @Override public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub } }
版权声明:本文为博主原创文章,未经博主允许不得转载。