ListFragment运行时异常';android.R.id.list';丢失的
编辑2013年1月16日:问题已解决!两天前,我发布了该应用程序的更新版本,并使用ListFragment运行时异常';android.R.id.list';丢失的,android,android-listfragment,android-fragmentactivity,Android,Android Listfragment,Android Fragmentactivity,编辑2013年1月16日:问题已解决!两天前,我发布了该应用程序的更新版本,并使用android:id=“@android:id/list”正确地识别了列表视图,正如我最初所做的那样。实际上,抛出的异常是误导性的,与实际问题无关 真正的解决方法是,当我执行Sean的建议,通过将null传递到ViewGroup来扩大ListFragment视图时。我没有从新版本中收到相同的异常,新版本已经被足够多的设备下载,可以安全地说这个问题已经解决。然而,我确实感谢劳伦斯的评论和回答,并将继续阅读他是如何实例
android:id=“@android:id/list
”正确地识别了列表视图,正如我最初所做的那样。实际上,抛出的异常是误导性的,与实际问题无关
真正的解决方法是,当我执行Sean的建议,通过将null
传递到ViewGroup
来扩大ListFragment
视图时。我没有从新版本中收到相同的异常,新版本已经被足够多的设备下载,可以安全地说这个问题已经解决。然而,我确实感谢劳伦斯的评论和回答,并将继续阅读他是如何实例化碎片的。虽然他提出了将null传递给视图充气器的建议,但肖恩实际上是第一个这样做的人,因为他的解决方案似乎已经解决了这个问题,因此将相应地授予赏金。我将更新这一点如果我学习/阅读更多关于劳伦斯的优秀答案所建议的片段实例化的不同方法,我将在未来发布一篇文章。太糟糕了,我不能分割赏金
编辑2013年1月14日:ListView
相关的XML
文件按照@LawrenceChoy的要求定位
编辑2013年1月13日:我发布了我的应用程序的更新版本,并根据比尚的建议使用了android:id=“@+id/android:list
而不是android:id=“@android:id/list”
,然而,我仍然收到随机异常,即我的Fragment activity没有id属性为“android.R.id.list”的列表视图,即使该活动没有任何列表视图。添加了LGE phone的另一个例外
编辑2013年1月9日:尽管比山给出了答案,但我希望能得到更多解释,解释一下为什么他的解决方案可能会阻止这种异常。进一步阅读后,我认为这是因为在使用自定义列表视图时,应该使用+符号。然而,我希望得到确认,我是正确的,或者得到澄清,特别是考虑到两者似乎都在许多不同的设备和模拟器上工作。在大约20分钟内提出悬赏,以寻求关于此事的可靠来源/答案。谢谢
在play store最近更新后,我在野外的一些设备上发现了一些非常奇怪的行为
在我的新版本中,我有一个FragmentActivity
(称为TabsStyled),它使用FragmentStatePagerAdapter
来管理多个片段。我总共有4个片段,其中2个片段扩展了ListFragment
,并且列表视图由LoaderManager
和CursorLoader
填充,所有这些都来自support.v4
库。另外两个片段没有列表视图
,也没有扩展列表片段
我在多台设备以及AVD上进行了广泛的测试,从未遇到任何缺少android.R.id.list的运行时异常
然而,在发布后,FragmentaActivity出现了一些ACRA崩溃“您的内容必须有一个id属性为“android.R.id.list”的ListView”
。TabsStyled.class是管理ListFragments的FragmentActivity
,它本身没有任何“ListView”。这对我来说似乎很奇怪,因为我认为如果抛出这个异常,它应该是一个ListFragments,而不是“父”FragmentActivity
这是堆栈跟踪的顶部,我很乐意根据请求提供任何额外的代码或信息,而不是将所有内容都粘贴到这里
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myapp.hiddenforsecurity/com.myapp.hiddenforsecurity.TabsStyled}:
java.lang.RuntimeException: Your content must have a ListView whose id attribute is 'android.R.id.list'
pastebin上的完整堆栈跟踪如下:
包含ListView的每个ListFragments
的XML(每个ListFragments
的单独的ListView
在单独的XML中):
试试这个
<ListView android:id="@+id/android:list"
android:choiceMode="singleChoice"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="45" />
我已经将android:id=“@android:id/list”
替换为android:id=“@+id/android:list”
只是一种预感,但请尝试在不使用ViewGroup的情况下为ListFragment扩展自定义视图。所以在你的列表中
View logv = inflater.inflate(R.layout.listroot, container, false);
到
我无法用您提供的代码重现您的问题,因为我没有上面列出的任何设备。我的第一个想法是,它可能与初始化片段的方式有关。请参阅下面我修改过的nFragmentAdapter
类。我已将getItem()
更改为以不同的方式初始化片段:
碎片适配器:
以及相应的MyListFragment:
公共类MyListFragment扩展ListFragment实现LoaderManager.LoaderCallbacks{
myCursorAdapter mAdapter;
字符串orderBy=DBAdapter.activityDateTime+“DESC”;
静态最终字符串[]activityQuery=新字符串[]{DBAdapter.activityRowID,DBAdapter.activityReason,DBAdapter.activityDateTime};
字符串内容;
公共视图(){
getLoaderManager().restartLoader(0,null,this);
}
@凌驾
CreateView上的公共视图(布局、充气机、视图组容器、捆绑包保存状态){
Bundle args=getArguments();
如果(args!=null)
content=args.getString(“content”);
视图logv=充气机充气(R.layout.listroot,null);
返回logv;
}
@凌驾
已创建ActivityState上的公共无效(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
mAdapter=newmycursoradapter(getActivity(),null);
setListAdapter(mAdapter);
getLoaderManager().initLoader(0,nul
<ListView android:id="@+id/android:list"
android:choiceMode="singleChoice"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="45" />
View logv = inflater.inflate(R.layout.listroot, container, false);
View logv = inflater.inflate(R.layout.listroot, null);
class nFragmentAdapter extends FragmentStatePagerAdapter {
public nFragmentAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
@Override
public Fragment getItem(int position) {
Fragment f = null;
Bundle args = new Bundle();
args.putString("content", TabsStyled.CONTENT[position
% TabsStyled.CONTENT.length]);
switch (position) {
case 0:
f = Fragment.instantiate(TabsStyled.this,
ReviewFragment.class.getName(), args);
break;
case 1:
f = Fragment.instantiate(TabsStyled.this,
MyListFragment.class.getName(), args);
break;
case 2:
f = Fragment.instantiate(TabsStyled.this,
SmartFragment.class.getName(), args);
break;
case 3:
f = Fragment.instantiate(TabsStyled.this,
MyListFragment.class.getName(), args);
break;
case 4:
f = Fragment.instantiate(TabsStyled.this,
f.getClass.getName(), args);
break;
case 5:
f = Fragment.instantiate(TabsStyled.this,
f.getClass.getName(), args);
break;
case 6:
f = Fragment.instantiate(TabsStyled.this,
f.getClass.getName(), args);
break;
}
return f;
}
@Override
public int getCount() {
return TabsStyled.CONTENT.length;
}
@Override
public CharSequence getPageTitle(int position) {
return TabsStyled.CONTENT[position % TabsStyled.CONTENT.length].toUpperCase();
}
}
public class MyListFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> {
myCursorAdapter mAdapter;
String orderBy = DBAdapter.activityDateTime + " DESC";
static final String[] activityQuery = new String[] { DBAdapter.activityRowID, DBAdapter.activityReason, DBAdapter.activityDateTime };
String content;
public void refreshView() {
getLoaderManager().restartLoader(0, null, this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Bundle args = getArguments();
if(args != null)
content = args.getString("content");
View logv = inflater.inflate(R.layout.listroot, null);
return logv;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mAdapter = new myCursorAdapter(getActivity(), null);
setListAdapter(mAdapter);
getLoaderManager().initLoader(0, null, this);
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(getActivity().getApplicationContext(), myListProvider.activity_URI, activityQuery, null, null, orderBy);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
mAdapter.swapCursor(data);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
public class myCursorAdapter extends CursorAdapter {
private final LayoutInflater mInflater;
public myCursorAdapter(Context context, Cursor c) {
super(context, c, 0);
mInflater = LayoutInflater.from(context);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
TextView logleft = (TextView) view.findViewById(R.id.logleft);
logleft.setText(cursor.getString(cursor.getColumnIndex(DBAdapter.activityDateTime)));
TextView logcenter = (TextView) view.findViewById(R.id.logcenter);
logcenter.setText(cursor.getString(cursor.getColumnIndex(DBAdapter.activityReason)));
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = null;
view = mInflater.inflate(R.layout.vlist, parent, false);
return view;
}
}
}