我关注contacts provider lesson on retrieving contacts并使用片段显示它们。作为参考,我已将API级别设置为16(Android 4.1)。
除了一些值得注意的例外,我大部分都遵循了本教程。例如,我从mypackage.R
而不是android.R
导入。
我的问题出在我onActivityCreated
的{{1}}处理程序中:
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
无效。
我的父活动是eclipse创建的默认活动。对此,我做了两件事:
findViewById
替换为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>
和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
。这也会返回null。getView().findViewById()
代替this answer建议。这不会返回null;相反,它导致findViewById(R.id.contacts_list_view);
导致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);
}
或教程所说的位置。答案 0 :(得分:11)
我按照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
作为参数。
视图ID在整个树中不一定是唯一的,但最好确保它们在您正在搜索的树的部分内至少是唯一的。
所以,我将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
回调中)。
findViewById
传递视图的根元素,就像在that post中一样,它将返回NoSaveStateFrameLayout
,而不是您想要的子ListView
。答案 1 :(得分:2)
getActivity().findViewById()
在Activity
的视图层次结构中查找您提供的ID作为参数。可能ListView
由您的片段的onCreateView
返回。如果要在片段视图层次结构上执行findViewById
,则必须调用getView().findViewById()
。在这种情况下,由于您要延长ListFragment
,以检索ListView
,与ListActivity
一样,您必须使用getListView();
与ListActivity
的另一个类比是xml文件(ListView
)
android:id="@android:id/list"
的id
答案 2 :(得分:1)
请注意,ListFragment
有一个getListView()
方法可以返回ListView
窗口小部件实例。
开发人员文档:ListFragment.getListView
答案 3 :(得分:0)
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mContactsList = (ListView) getActivity().findViewById(android.R.id.list);//(R.layout.fragment_contact_list);
mCursorAdapter = new SimpleCursorAdapter(getActivity(), R.layout.contact_item_list,null, FROM_COLUMNS, TO_IDS, 0);
mContactsList.setAdapter(mCursorAdapter);
mContactsList.setOnItemClickListener(this);
getLoaderManager().initLoader(0,null,this);
}
希望它有所帮助,Android开发人员指南包含这样的&#34; bug&#34;这样我们就可以熟悉api。