android – getActivity().findViewById返回null,从片段onActivityCreated调用

我正在跟着 contacts provider lesson on retrieving contacts,并用碎片显示它们.作为参考,我已将API级别设置为16(Android 4.1).

我主要遵循本教程的信,有一些显着的例外.例如,我从mypackage.R而不是android.R导入.

我的问题是在我的ListContactsFragment中的onActivityCreated处理程序中:

public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    // Initializes the loader
    getLoaderManager().initLoader(0,null,this);
    // Gets the ListView from the View list of the parent activity

    View mContactsListView = 
                    getActivity().findViewById(R.layout.contacts_list_view);
    mContactsList = (ListView) mContactsListView;

    // Gets a CursorAdapter
    mCursorAdapter = new SimpleCursorAdapter(
            getActivity(),R.layout.contacts_list_item,FROM_COLUMNS,TO_IDS,0);
    // Sets the adapter for the ListView
    mContactsList.setAdapter(mCursorAdapter);

    // Set the item click listener to be the current fragment.
    mContactsList.setonItemClickListener(this);
}

查看mContactsListView为null,意味着findViewById无效.

我的父活动是由eclipse创建的认的.为此,我做了两件事:

>用android.support.v4.app.FragmentActivity替代导入android.app.Activity,以防止如果没有发生ClasscastException.
将我的片段导入XML.

我的activity_list_contacts.xml如下所示:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".ListContactsActivity" >

    <fragment android:name="mypackage.ListContactsFragment"
              android:id="@+id/contacts_list_view"
              android:layout_width="match_parent"
              android:layout_height="match_parent" />

</RelativeLayout>

匹配活动,以防万一:

public class ListContactsActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list_contacts);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.list_contacts,menu);
        return true;
    }
}

和contacts_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_width="match_parent"
          android:layout_height="match_parent"/>

所以我的问题是,我做错了findViewById找不到我的看法?

我尝试过的东西(其中大部分都是接受的答案,几乎看起来像这样一个重复的问题):

>阅读我从单词中复制和粘贴的文档.
>试图getView().findViewById()建议in this question.这也返回null.
>使用findViewById(R.id.contacts_list_view);而是按照this answer的建议.这不返回null;相反,它会导致一个ClassCastException,因为android.support.v4.app.NoSaveStateFrameLayout无法转换为android.widget.ListView.
>我读到有时创建的片段回调在附加到活动之前发生.所以,我将处理程序添加到onAttach方法,如下所示:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    View mContactsListView = activity.findViewById(R.id.contacts_list_view);
    mContactsList = (ListView) mContactsListView;

    // Gets a CursorAdapter
    mCursorAdapter = new SimpleCursorAdapter(
            getActivity(),0);
    // Sets the adapter for the ListView
    mContactsList.setAdapter(mCursorAdapter);

    // Set the item click listener to be the current fragment.
    mContactsList.setonItemClickListener(this);
}

你猜到了 – 仍然是空的.

所以在这一点上我有点迷失了.我有两个问题:

>我做错了什么(如果我还没有提供足够的话请在评论中请求额外的信息)?
>最好将适配器设置放在onAttach中,或教程说明的地方.

解决方法

我按照 developer.android.com的教程,遇到了同样的问题.

最后我注意到在这一部分:

// Gets the ListView from the View list of the parent activity
    mContactsList = (ListView) getActivity().findViewById(R.layout.contact_list_view);

它似乎试图找到一个视图,但传递一个布局ID作为参数.

View | android reference说:

View IDs need not be unique throughout the tree,but it is good practice to ensure that they are at least unique within the part of the tree you are searching.

所以,我将contacts_list_view.xml中的ListView id更改为唯一的:

<?xml version="1.0" encoding="utf-8"?>
<ListView ...
android:id="@+id/contacts_listview_a_unique_id_here"
... />

然后尝试找到它:

mContactsList = (ListView) getActivity().findViewById(R.id.contacts_listview_a_unique_id_here);

它在(onActivityCreated回调)中有效.

>关于投放异常:
正如hierarchyviewer所示,树是这样的:

所以如果你发现viewById通过视图的根元素,像在that post那样,它将返回NoSaveStateFrameLayout,这不是你想要的子ListView.

相关文章

这篇“android轻量级无侵入式管理数据库自动升级组件怎么实现...
今天小编给大家分享一下Android实现自定义圆形进度条的常用方...
这篇文章主要讲解了“Android如何解决字符对齐问题”,文中的...
这篇文章主要介绍“Android岛屿数量算法怎么使用”的相关知识...
本篇内容主要讲解“Android如何开发MQTT协议的模型及通信”,...
本文小编为大家详细介绍“Android数据压缩的方法是什么”,内...