我正在关注contacts provider lesson on retrieving contacts并使用 fragment 显示它们。作为引用,我将API级别设置为16(Android 4.1)。
我主要按照本教程进行介绍,但有一些值得注意的异常(exception)。例如,我从mypackage.R
而不是android.R
导入。
我的问题是在onActivityCreated
中的ListContactsFragment
处理程序中:
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,
null,
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);
}
View mContactsListView
为空,表示findViewById
不起作用。我的父 Activity 是eclipse创建的默认 Activity 。为此,我做了两件事:
import android.app.Activity
替换为android.support.v4.app.FragmentActivity
,以防止如果不这样做就发生ClasscastException
。 我的
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>
匹配 Activity ,以防万一:
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
找不到我的 View ,我做错了什么?我尝试过的事情(这些问题中的大多数都是可以接受的答案,几乎看起来像是与此问题的重复):
getView().findViewById()
作为建议的in this question。这也将返回null。 findViewById(R.id.contacts_list_view);
代替this answer建议。这不会返回null;它不会返回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(),
R.layout.contacts_list_item,
null,
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);
}
您猜对了-仍然为空。
所以在这一点上我有点迷茫。我有两个问题:
onAttach
或本教程说的地方。 最佳答案
我遵循developer.android.com上的教程,遇到了同样的问题。
最后,我注意到这一部分:
// Gets the ListView from the View list of the parent activity
mContactsList = (ListView) getActivity().findViewById(R.layout.contact_list_view);
似乎试图找到
View
,但是将Layout id
传递为参数。View | android reference说:
因此,我将
ListView id
中的contacts_list_view.xml
更改为唯一的:<?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所示,树是这样的:
因此,如果
findViewById
传递了 View 的根元素,例如that post,它将返回NoSaveStateFrameLayout
,而不是您想要的子ListView
。