如何在 Android for Android api 11+ 的列表视图中显示联系人

Posted

技术标签:

【中文标题】如何在 Android for Android api 11+ 的列表视图中显示联系人【英文标题】:how to display contacts in a listview in Android for Android api 11+ 【发布时间】:2013-08-14 11:52:19 【问题描述】:

很抱歉,如果这看起来像一百万次相同的问题...但谷歌搜索没有结果,只是一堆过时的教程使用 managedQuery 和其他已弃用的解决方案...

我浏览了android developer training for retrieving a contact list,但教程不完整,甚至下载示例代码也无济于事,因为示例代码用于更高级的联系人列表操作(搜索等)

无论如何,没有理由不应该有一个简单的解决方案,所以我希望有人能在这里回答,因为我确信这已经完成了一百万次,而且我确信还有几十个其他的刚开始的 android 开发人员会很感激这一点。

据我所知,我已按照教程进行操作,但没有显示任何联系人。我认为最重要的是TO_IDS 是一个指向android.R.id.text1 的整数数组。我很困惑这应该如何以某种方式提取一系列联系人姓名。

另外,我很困惑为什么当最终目标是显示列表视图时需要文本视图...在本教程中,我们有 mContactsList 这是一个列表视图...但是我们使用适配器填充列表视图指向R.layout.contact_list_item,它只是由TO_IDS(整数数组)填充的文本视图。

mContactsList = (ListView) getActivity().findViewById(R.layout.contact_list_view);
mCursorAdapter = new SimpleCursorAdapter(
            getActivity(),
            R.layout.contact_list_item,
            null,
            FROM_COLUMNS, TO_IDS,
            0);
mContactList.setAdapter(mCursorAdapter);

我做错了什么,如何在列表视图中简单地显示联系人列表?

编辑:添加我的代码:

在我的片段类中:

public class MyFragment extends Fragment implements
    LoaderManager.LoaderCallbacks<Cursor>

private static final String[] FROM_COLUMNS = ContactsContract.Contacts.DISPLAY_NAME_PRIMARY ;
private static final int[] TO_IDS = android.R.id.text1;
ListView mContactList;
private SimpleCursorAdapter mCursorAdapter;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    return inflater.inflate(R.layout.contact_list_view,container,false);


@Override
public void onActivityCreated(Bundle savedInstanceState)
    super.onActivityCreated(savedInstanceState);
    mContactsList = (ListView) getActivity().findViewById(R.layout.contact_list_view);
    mCursorAdapter = new SimpleCursorAdapter(
            getActivity(),
            R.layout.contact_list_item,
            null,
            FROM_COLUMNS, TO_IDS,
            0);
    mContactList.setAdapter(mCursorAdapter);



@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) 
    return null;


@Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) 



@Override
public void onLoaderReset(Loader<Cursor> cursorLoader) 



在我的 activity_main.xml 中:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:orientation="vertical">

    <fragment
            android:id ="@+id/contactListFragment"
            android:layout_
            android:layout_
            android:layout_weight="1"
            android:name="preamble.myapp.MyFragment"/>
</LinearLayout>

在我的contact_list_view xml中:

<?xml version="1.0" encoding="utf-8"?>
<ListView   xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@android:id/list"
            android:layout_
            android:layout_/>

在我的contact_list_item xml中

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@android:id/text1"
            android:layout_
            android:layout_/>

最后是contact_list_layout xml:

我在contact_list_layout.xml 中输入了什么?这只是一个空的&lt;LinearLayout&gt;?教程中不清楚如何处理这个 xml。它说这个 XML 是片段,但如果它是片段,为什么我们在 contact_list_view.xml 中已经定义了一个 listview

【问题讨论】:

FROM_COLUMNS, TO_IDS, 将数据库列映射到文本视图 ID(在每个列表项中),请参阅 SimpleCursorAdapter。有些东西需要加载光标数据才能使用它,而那不在你的代码 sn-p @zapl 我添加了一些代码来向您展示我的FROM_COLUMNSTO_IDS...我注意到我没有contact_list_layout.xml 而我有@987654341 @...你能告诉我contact_list_layout.xml 的结构吗?您可以查看我的 xml 文件吗?我有一种感觉,我只是想念一些东西,一旦我发现它会起作用。该教程没有显示contact_list_layout.xml是如何编写的,所以也许这就是我犯错的地方? @zapl 我在mContactList.setAdapter(mCursorAdapter);得到一个空指针异常 @zapl 好的,我发现了我的一个问题。我的mContactsList 引用了我认为从未实例化的listview,我相信mContactsList 也引用了尚未创建的布局。这导致了一个空指针...我假设我必须在我缺少的 contact_list_layout.xml 中创建它们...你知道我需要做什么吗? 【参考方案1】:

ListView 中显示联系人姓名的精简示例。 在Fragment 下方扩展了ListFragment,它具有默认布局。你不需要指定你自己的。列表项的布局也取自 Android 的默认布局 (android.R.layout.simple_list_item_1),即每个项目的简单单行文本。

import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract.Contacts;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;
import android.support.v4.widget.SimpleCursorAdapter;

public class ContactListFragment extends ListFragment implements LoaderCallbacks<Cursor> 

    private CursorAdapter mAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

        // create adapter once
        Context context = getActivity();
        int layout = android.R.layout.simple_list_item_1;
        Cursor c = null; // there is no cursor yet
        int flags = 0; // no auto-requery! Loader requeries.
        mAdapter = new SimpleCursorAdapter(context, layout, c, FROM, TO, flags);
    

    @Override
    public void onActivityCreated(Bundle savedInstanceState) 
        super.onActivityCreated(savedInstanceState);

        // each time we are started use our listadapter
        setListAdapter(mAdapter);
        // and tell loader manager to start loading
        getLoaderManager().initLoader(0, null, this);
    

    // columns requested from the database
    private static final String[] PROJECTION = 
        Contacts._ID, // _ID is always required
        Contacts.DISPLAY_NAME_PRIMARY // that's what we want to display
    ;

    // and name should be displayed in the text1 textview in item layout
    private static final String[] FROM =  Contacts.DISPLAY_NAME_PRIMARY ;
    private static final int[] TO =  android.R.id.text1 ;

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) 

        // load from the "Contacts table"
        Uri contentUri = Contacts.CONTENT_URI;

        // no sub-selection, no sort order, simply every row
        // projection says we want just the _id and the name column
        return new CursorLoader(getActivity(),
                contentUri,
                PROJECTION,
                null,
                null,
                null);
    

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) 
        // Once cursor is loaded, give it to adapter
        mAdapter.swapCursor(data);
    

    @Override
    public void onLoaderReset(Loader<Cursor> loader) 
        // on reset take any old cursor away
        mAdapter.swapCursor(null);
    

【讨论】:

谢谢帮了大忙,你能告诉我我们如何以与上述相同的方式显示电子邮件和号码以及联系人姓名吗? @JagdeepSingh 不确定如何获取所有数据,但据我所知,电子邮件包含在ContactsContract.Data 表中。可能足以更改该表的 URI 并将电子邮件 + 电话号码列添加到投影中。此外,您需要一个带有 3 个文本字段的自定义列表项布局,用于 FROM>TO 映射或扩展完整的 CursorAdapter,因为简单的布局不允许在 1 个文本字段中显示 3 列。

以上是关于如何在 Android for Android api 11+ 的列表视图中显示联系人的主要内容,如果未能解决你的问题,请参考以下文章

Qt 中的qserialplot 串口通信功能如何在qt for android用?或者用Qt如何实现android版本的串口通信功能?

python-for-android

如何在 Firefox for Android 中检测 Android 的版本号?

Kotlin for Android使用教程(一)

ANDROID:如何在 for 循环中设置按钮?

Android:如何在 SharedPreferences for android 中存储字符串数组