关于使用AutoCompleteTextView和CursorAdapter查询电话联系人并找出电话号码
发表于50 天前 ⁄ Android, Android开发 ⁄ 暂无评论 ⁄ 被围观 热度 154˚+
学习到这部分遇见很多的问题,看了很多人讲的关于这部分的文章同时结合自己的测试总结如下:
程序的目地是在AutoCompleteTextView里面输入联系人名同时自动找出建议的联系人,选取某个联系人后得到该联系人的电话号码。
这里关键是实现一个自己的XXXXXAdapter 继承自CursorAdapter。
要继承CursorAdapter类。必须实现(Override)的方法有:
一 先实现 public Cursor runQueryOnBackgroundThread(CharSequence constraint)
其中constraint就是输入的要查询的关键字,注意当选中输入框的时候,此方法就会被调用,此时constraint = null 如处理不当运行时会报错
这里的返回值Cursor.并将提供给方法public View newView( , ,)使用;
二 然后实现方法public View newView(Context context, Cursor cursor, ViewGroup parent),cursor是上一个方法产生的.这个方法里面需要构造一个在dropdown里显示的view(我把这个view理解为例表中每行显示内容的一个模型,这里可以通过LayoutInflater构造出需要的样式)。这个view作为返回值在bindView( )中还会用到。
三 再是实现方法public void bindView(View view, Context context, Cursor cursor) 。view就是第二步产生的。cursor是第一步产生的。这里就是把corsor里的数据绑定到view中对应的元素中去。注意此方法会多次频繁调用,所以不要有耗时的操作,不然会卡。
四 最后是 public CharSequence convertToString(Cursor cursor) 此方法是在我们选择某个联系人后会显示在AutoCompleteTextView中的内容。
AutoCompleteTextView在布局文件中
android:completionThreshold="1" 表示输入1个字符就显示出建议的联系人
android:completionHint="@string/strHint" 表示在建议例表最后显示的一句话,比如“输入*号给出全部联系人“
package my.chenpu.exsdk_05;
import android.app.Service;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class ContactsAdapter extends CursorAdapter {
private ContentResolver mContent;
public ContactsAdapter(Context context, Cursor c) {
super(context, c);
// TODO Auto-generated constructor stub
mContent = context.getContentResolver();
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// TODO Auto-generated method stub
Log.e("ContactsAdapter", "newView!!!");
// LayoutInflater inflater = LayoutInflater.from(context);
// LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
// TextView view = (TextView) inflater.inflate(android.R.layout.simple_dropdown_item_1line, parent, false);
// view.setText(cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)));
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Service.LAYOUT_INFLATER_SERVICE);
View view = (View) inflater.inflate(R.layout.ex05_09_cursoradapterview, null);
TextView text = (TextView) view.findViewById(R.id.textinline);
ImageView image = (ImageView) view.findViewById(R.id.viewinline);
text.setText(cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)));
image.setImageResource(R.drawable.min);
return view;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
// TODO Auto-generated method stub
Log.e("ContactsAdapter", "bindView!!!");
// ((TextView) view).setText(
// cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)));
TextView text = (TextView) view.findViewById(R.id.textinline);
text.setText(cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)));
}
@Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
// TODO Auto-generated method stub
Log.e("ContactsAdapter", "runQueryOnBackgroundThread()!!!");
super.runQueryOnBackgroundThread(constraint);
if(getFilterQueryProvider() != null)
{
Log.e("ContactsAdapter", "getFilterQueryProvider()!!!");
return getFilterQueryProvider().runQuery(constraint);
}
StringBuilder buffer = null;
String[] args = null;
Log.e("ContactsAdapter", "|" + constraint.toString() + "|");
if(constraint != null)
{
buffer = new StringBuilder();
buffer.append("UPPER(");
buffer.append(ContactsContract.Contacts.DISPLAY_NAME);
buffer.append(") GLOB ?");
args = new String[]{
constraint.toString().toUpperCase() + "*" //匹配以constraint开头的所有联系人名
};
}
return mContent.query(ContactsContract.Contacts.CONTENT_URI,
null, buffer == null? null : buffer.toString(),
args, null);
}
//当选则某项后输入的位置显示的东西。
@Override
public CharSequence convertToString(Cursor cursor) {
// TODO Auto-generated method stub
return cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
}
}
以上就是对CursorAdapter的实现。其中的newView()方法很是让我郁闷了很久, 网上找了很久才大概了解了LayoutInflater的主要目地就是把一个布局文件导入到代码中来,下面//线的几行是不同的使用方法。
我的方法是自己写了个ex05_09_cursoradapterview.xml ,里面就是很简单的左边一个TextView显示联系人名,右边一个ImageView用于显示一个小图标。关于这部分网上很多查查就有了。
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// TODO Auto-generated method stub
Log.e("ContactsAdapter", "newView!!!");
// LayoutInflater inflater = LayoutInflater.from(context);
// LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
// TextView view = (TextView) inflater.inflate(android.R.layout.simple_dropdown_item_1line, parent, false);
// view.setText(cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)));
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Service.LAYOUT_INFLATER_SERVICE);
View view = (View) inflater.inflate(R.layout.ex05_09_cursoradapterview, null);
TextView text = (TextView) view.findViewById(R.id.textinline);
ImageView image = (ImageView) view.findViewById(R.id.viewinline);
text.setText(cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)));
image.setImageResource(R.drawable.min);
return view;
}
android.R.layout.simple_dropdown_item_1line
位置:mydroid/frameworks/base/core/res/res/layout/simple_dropdown_item_1line.xml
<?xml version="1.0" encoding="utf-8"?>
<!--
/* //device/apps/common/assets/res/any/layout/simple_spinner_item.xml
**
** Copyright 2008, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
style="?android:attr/dropDownItemStyle" mce_style="?android:attr/dropDownItemStyle"
android:textAppearance="?android:attr/textAppearanceLargeInverse"
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:ellipsize="marquee" />
最后还有程序中使用ContactsContract,我看的书写的是Contacts,似乎是2.0后这个就不建议使用了。这里还有个查找联系人后如何找到属于此人的全部电话号码的问题。
这里提供一个链接 http://hi.baidu.com/wudaovip/blog/item/d7f166df13a8241c495403e7.html
package my.chenpu.exsdk_05;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.Contacts.People;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AutoCompleteTextView;
import android.widget.TextView;
public class ex05_09 extends Activity {
private AutoCompleteTextView myAutoCompleteTextView;
private TextView myTextView;
private Cursor contactCursor;
private ContactsAdapter myContactsAdapter;
//无用了
public static final String[] PEOPLE_PROJECTION = new String[]{
ContactsContract.Contacts._ID, ContactsContract.Contacts.PHOTO_ID,
ContactsContract.Contacts.CONTENT_TYPE, ContactsContract.Contacts.CONTACT_STATUS_LABEL,
ContactsContract.Contacts.DISPLAY_NAME
};
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.ex05_09);
Log.e("ex05_09", "onCreate!!!");
myAutoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.myAutoCompleteTextView);
myTextView = (TextView) findViewById(R.id.myTextView0902);
ContentResolver content = getContentResolver();
contactCursor = content.query(ContactsContract.Contacts.CONTENT_URI,
null, null, null, null);
myContactsAdapter = new ContactsAdapter(this, contactCursor);
myAutoCompleteTextView.setAdapter(myContactsAdapter);
myAutoCompleteTextView.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
String _id;
Cursor phcursor;
Cursor c = myContactsAdapter.getCursor();
c.moveToPosition(position);
String number = "";
if(c.getInt(c.getColumnIndexOrThrow(ContactsContract.Contacts.HAS_PHONE_NUMBER)) != 0)
{
_id = c.getString(c.getColumnIndexOrThrow(ContactsContract.Contacts._ID));
phcursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + _id, null, null);
while(phcursor.moveToNext())
{
number += phcursor.getString(phcursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
number += " , ";
}
}
else
number = "无输入电话!";
myTextView.setText(c.getString(c.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)) +
"的电话是:" + number);
}
});
}
}
Cursor c = DBHelper.query();
for(c.moveToFirst(); ! c.isAfterLast(); c.moveToNext()){
int id = c.getInt(0);
String ty = c.getString(1);
showDialog(“共有”+data_total+“条,id=”+id+“,类型=”+ty);
}
分享到:
相关推荐
在Android UI组件中,`Filter`主要用在`Adapter`类中,如`ArrayAdapter`或`CursorAdapter`,用于实现搜索框(SearchView)的实时搜索功能,即用户输入关键词后,列表视图会根据关键词动态过滤出匹配的项。...
1. 在适配器(如ArrayAdapter或CursorAdapter)类中实现`Filterable`接口: ```java public class MyAdapter extends ArrayAdapter<String> implements Filterable { // ... } ``` 2. 重写`getFilter()`方法并创建...
- 在Java代码中,为`AutoCompleteTextView`设置数据源,通常是一个适配器(如ArrayAdapter或CursorAdapter),该适配器持有待推荐的数据集。 - 通过`setAdapter()`方法,将适配器绑定到`AutoCompleteTextView`上,...
`Adapter`可以是任何实现了`android.widget.Adapter`接口的对象,例如`ArrayAdapter`、`CursorAdapter`等。开发者需要在`Adapter`中定义数据结构,并提供方法获取与输入内容匹配的子集。 2. **Filter**:`Filter`...
如果默认的ArrayAdapter不能满足需求,开发者可以自定义适配器,继承BaseAdapter或 CursorAdapter,覆盖getFilter()方法以实现更复杂的过滤逻辑。 5. 设置触发自动完成的阈值: 通过setThreshold(int threshold)...
- Android的Spinner默认使用ArrayAdapter或者CursorAdapter,但它们并不直接支持筛选功能。因此,我们需要创建一个自定义适配器,继承自BaseAdapter或ArrayAdapter,并重写其`getFilter()`方法来实现过滤逻辑。 2....
- 提供自动补全功能,通过`ArrayAdapter`或`CursorAdapter`实现。 - 处理空查询,当用户清空搜索框时,恢复原始数据列表。 - 添加清除图标,允许用户快速清空搜索框。 总结,`SearchView`在Android应用中是必不...
实现`getFilter()`方法并返回一个自定义的Filter,这样在用户输入时,系统会自动调用`filter.filter(CharSequence constraint)`方法,过滤数据并更新ListView。 7. **布局设计**:在XML布局文件中,将ListView和...
2. **Adapter的实现**:在"AutocompleteTest"中,我们可能会看到自定义的Adapter,如ArrayAdapter或CursorAdapter。Adapter是Android中连接数据源与视图的关键桥梁,它将数据转换成可显示的视图项。自定义Adapter...
2. CursorAdapter:如果你的数据来源于数据库,使用CursorAdapter可以更高效地处理数据,因为它可以直接与数据库查询结果交互。 五、进阶技巧 1. 添加过滤器接口:为Adapter实现Filterable接口,可以使用标准的过滤...
使用`CursorAdapter`与ListView结合,可以轻松地显示数据库内容。 ```java SQLiteCursor cursor = db.query("table_name", columns, selection, selectionArgs, groupBy, having, orderBy); // 使用CursorAdapter...
数据源可以是ArrayList、ArrayAdapter、CursorAdapter等,通常我们会根据实际需求选择。例如,如果数据存储在内存中,可以使用ArrayList;如果数据来自数据库或网络,则可能需要使用CursorAdapter或自定义的Adapter...
- CursorAdapter和SimpleCursorAdapter适用于从SQLite数据库获取数据。 - 自定义适配器可以根据需求实现更复杂的数据显示和数据处理逻辑。 4. **触发事件**: - `onItemClickListener`:当用户从下拉列表中选择...
AutoCompleteTextView继承自EditText,主要通过`setAdapter()`方法连接数据源,这个数据源通常是实现了`Adapter`接口的对象,比如ArrayAdapter或CursorAdapter。设置好适配器后,当用户在文本框输入字符时,会触发...
- `AutoCompleteTextView` 使用适配器(如`ArrayAdapter`、`CursorAdapter`等)来绑定数据源。`MyAutoCompleteTextview`可能实现了自己的适配器类,以满足特定的数据结构和展示方式。 - 在源码中寻找适配器的初始...
要使用 `Filterable`,你需要在自定义的适配器(如 `ArrayAdapter` 或 `CursorAdapter`)中实现 `getFilter()` 方法。在这个方法内,你需要创建一个 `Filter` 对象,并重写它的 `performFiltering()` 和 `...
数据源通常通过`ArrayAdapter`、`CursorAdapter`或其他自定义适配器与`AutoCompleteTextView`关联。 以下是一个简单的`AutoCompleteTextView`实现步骤: 1. 在布局文件中添加`AutoCompleteTextView`: ```xml ...
这个数据源通常由一个`Adapter`实现,如`ArrayAdapter`、`CursorAdapter`或`SimpleAdapter`。`Adapter`的作用是将数据转换为可以在UI上展示的视图,比如将字符串数组转换为可滚动的列表项。 ### 3. 设置Adapter 在...