选项卡内的片段
Posted
技术标签:
【中文标题】选项卡内的片段【英文标题】:Fragments inside tabs 【发布时间】:2013-07-09 20:27:06 【问题描述】:我正在创建具有两个选项卡的菜单。每个选项卡都有三个显示内容的片段。我虽然这很简单,但在试验和谷歌搜索之后,我发现我错了。
我设法为第一个选项卡创建了片段。但是,当我切换到其他选项卡并返回时,我收到以下错误消息并且应用程序崩溃:
07-11 16:49:57.829: E/androidRuntime(20009): FATAL EXCEPTION: main
07-11 16:49:57.829: E/AndroidRuntime(20009): android.view.InflateException: Binary XML file line #8: Error inflating class fragment
07-11 16:49:57.829: E/AndroidRuntime(20009): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:697)
07-11 16:49:57.829: E/AndroidRuntime(20009): at android.view.LayoutInflater.rInflate(LayoutInflater.java:739)
07-11 16:49:57.829: E/AndroidRuntime(20009): at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
07-11 16:49:57.829: E/AndroidRuntime(20009): at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
07-11 16:49:57.829: E/AndroidRuntime(20009): at com.machinedata.ui.feedback.UsersFragment.onCreateView(UsersFragment.java:16)
07-11 16:49:57.829: E/AndroidRuntime(20009): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:828)
07-11 16:49:57.829: E/AndroidRuntime(20009): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1032)
07-11 16:49:57.829: E/AndroidRuntime(20009): at android.app.BackStackRecord.run(BackStackRecord.java:622)
07-11 16:49:57.829: E/AndroidRuntime(20009): at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1382)
07-11 16:49:57.829: E/AndroidRuntime(20009): at android.app.FragmentManagerImpl$1.run(FragmentManager.java:426)
07-11 16:49:57.829: E/AndroidRuntime(20009): at android.os.Handler.handleCallback(Handler.java:605)
07-11 16:49:57.829: E/AndroidRuntime(20009): at android.os.Handler.dispatchMessage(Handler.java:92)
07-11 16:49:57.829: E/AndroidRuntime(20009): at android.os.Looper.loop(Looper.java:137)
07-11 16:49:57.829: E/AndroidRuntime(20009): at android.app.ActivityThread.main(ActivityThread.java:4507)
07-11 16:49:57.829: E/AndroidRuntime(20009): at java.lang.reflect.Method.invokeNative(Native Method)
07-11 16:49:57.829: E/AndroidRuntime(20009): at java.lang.reflect.Method.invoke(Method.java:511)
07-11 16:49:57.829: E/AndroidRuntime(20009): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:978)
07-11 16:49:57.829: E/AndroidRuntime(20009): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:745)
07-11 16:49:57.829: E/AndroidRuntime(20009): at dalvik.system.NativeStart.main(Native Method)
07-11 16:49:57.829: E/AndroidRuntime(20009): Caused by: java.lang.IllegalArgumentException: Binary XML file line #8: Duplicate id 0x7f0b0013, tag null, or parent id 0xffffffff with another fragment for com.machinedata.ui.UserListFragment
07-11 16:49:57.829: E/AndroidRuntime(20009): at android.app.Activity.onCreateView(Activity.java:4252)
07-11 16:49:57.829: E/AndroidRuntime(20009): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:673)
现在我的选项卡本身就是片段,它们被动态放置到屏幕上。然后这些片段膨胀 xml 文件,其中静态放置了片段。经过一番谷歌搜索后,我发现将片段放在片段中有点棘手。
getChildFragmentManager 在 API 级别 17 中工作,但我想将 API 级别保持在 14 中。无论如何要创建这种菜单结构吗?我需要为标签创建单独的活动吗?
这是显示标签的我的活动:
public class FeedbackActivity extends Activity implements UserListFragment.OnItemClickedListener
private ToplistsFragment toplist;
private UsersFragment users;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
setContentView(R.layout.feedback_screen);
//create tabs for dashboard and graphs
ActionBar.Tab tab1 = actionBar.newTab().setText(R.string.feedbackUsers);
ActionBar.Tab tab2 = actionBar.newTab().setText(R.string.feedbackToplist);
toplist = new ToplistsFragment();
users = new UsersFragment();
tab2.setTabListener(new MyTabsListener(toplist));
tab1.setTabListener(new MyTabsListener(users));
actionBar.addTab(tab1);
actionBar.addTab(tab2);
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo)
// TODO Auto-generated method stub
super.onCreateContextMenu(menu, v, menuInfo);
@Override
public boolean onCreateOptionsMenu(Menu menu)
// TODO Auto-generated method stub
return super.onCreateOptionsMenu(menu);
@Override
public boolean onOptionsItemSelected(MenuItem item)
// TODO Auto-generated method stub
Log.v("log","ID: " + item.getItemId() + " " + item.getTitle());
switch (item.getItemId())
case android.R.id.home:
Intent intent = new Intent(this, ModeSelectActivity.class);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
@Override
public void onUserItemClick(AdapterView<?> parent, View v, int position, long id, UserData user)
//wite your activity code here
Log.v("log", "name: " + user.getName());
//tablistener
class MyTabsListener implements ActionBar.TabListener
public Fragment fragment;
public MyTabsListener(Fragment fragment)
this.fragment = fragment;
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft)
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft)
ft.replace(R.id.feedback_fragcontainer, fragment);
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft)
ft.remove(fragment);
它的 xml 文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="vertical" >
<LinearLayout
android:id="@+id/feedback_fragcontainer"
android:layout_
android:layout_
android:orientation="vertical" />
</LinearLayout>
以及tab-fragment的xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="horizontal"
android:baselineAligned="false">
<fragment
android:id="@+id/feedbackuserListFragment"
android:layout_
android:layout_weight="1"
android:layout_
class="com.machinedata.ui.UserListFragment" >
</fragment>
<fragment
android:id="@+id/feedbackSessionListFragment"
android:layout_
android:layout_weight="1"
android:layout_
class="com.machinedata.ui.feedback.SessionListFragment" >
<!-- Preview: layout=@layout/details -->
</fragment>
<fragment
android:id="@+id/feedbackDetailsFragment"
android:layout_
android:layout_weight="0.5"
android:layout_
class="com.machinedata.ui.feedback.DetailsFragment" >
<!-- Preview: layout=@layout/details -->
</fragment>
</LinearLayout>
老实说,我不确定重复 id 的错误消息是什么意思,或者是什么原因造成的。基本上,我正在寻找一种解决方案来创建我描述的菜单结构或修复我当前的实现的方法。
【问题讨论】:
该布局似乎不是UsersFragment
的onCreateView()
正在膨胀的内容。堆栈跟踪抱怨膨胀 <fragment>
元素的问题,并且您在此处发布的布局不包含此内容。你确定onCreateView()
正在膨胀正确的布局吗?
使用支持库developer.android.com/reference/android/support/v4/app/…中的片段代替“正常”片段
忘记添加选项卡的 xml 文件。 Activity 应该增加 feedback_screen.xml 并且 UsersFragment (tab) 应该增加 feedbackusers_tab.xml。
【参考方案1】:
支持包中也提供了嵌套片段功能(在 API 级别 17 上实现)。从android.support.v4.app.Fragment
扩展您的片段而不是android.app.Fragment
。并将您的父活动替换为android.support.v4.app.FragmentActivity
。
【讨论】:
以上是关于选项卡内的片段的主要内容,如果未能解决你的问题,请参考以下文章
ViewPager2 selectCurrentItem - 选择选项卡,但在此选项卡内放置错误的片段