Articles of android fragments

add()和replace()与Fragment的生命周期之间的区别

我的程序有6个片段:Fragment1,Fragment2,….-> Fragment6。 我使用add()和replace()语句在片段之间切换并跟踪它们的生命周期。 Fragment1 添加 Fragment2 添加 Fragment3 添加 Fragment4 添加 Fragment5 替换 Fragment6 log-cat显示了它们的生命周期(我在onCreate中有一些printf-points,onCreateView,onDestroyView,onDestroy用于跟踪) 标签 __ _ __ _ __ _ __ _ __ 文字 Fragment1_ _ __ _ ___ _onCreate Fragment1_ _ __ _ ___ _onCreateView Fragment1_ _ __ _ ___ _add Fragment2 Fragment2_ _ __ _ ___ _onCreate Fragment2_ _ __ _ […]

Android Reorder Fragment Backstack

我的导航抽屉中列出了许多页面/片段,用户可能经常在这些页面/片段之间切换,我希望它们在后台堆栈中以便他们可以导航回来,但我只想在后台堆栈中使用每个片段的一个实例用户不必按下疯狂的次数退出应用程序。 我无法弄清楚如何在没有删除页面的情况下有效地“重新排序”后台堆栈。 目前,当我更改页面时,我正在使用此代码更改片段并确保它仅在后面的堆栈中一次 if (mFragMgr == null) { mFragMgr = getSupportFragmentManager(); } String backStateName = fragmentDescriptor.name(); boolean fragmentPopped = mFragMgr.popBackStackImmediate(backStateName, 0); if (!fragmentPopped){ mFragMgr.beginTransaction() .remove((Fragment) mFragment) .replace(R.id.content_frame, (Fragment) mFragment) .addToBackStack(backStateName) .commit(); } 我在onBackPressed中使用此代码 @Override public void onBackPressed() { if (mFragMgr.getBackStackEntryCount() > 0) { mFragMgr.popBackStackImmediate(); } else { super.onBackPressed(); } } 这有效,但这意味着它删除了我不想删除的页面。 例: 当我的用户按照A > B […]

FragmentTransaction.replace()不起作用

我有一个ListFragment显示用户创建的项目列表。 我有一个ListView ,它的id设置为“@android:id / list”和一个ID为“@android:id / empty”的TextView 。 我有一个操作栏按钮来显示片段,以允许用户为列表创建更多条目。 这是onOptionsItemSelected()方法: @Override public boolean onOptionsItemSelected(MenuItem item) { Fragment frag = null; // Right now I only have code for the addCourse() fragment, will add more soon switch (item.getItemId()) { case R.id.addCourse: frag = new AddCourseFragment(); break; default: return super.onOptionsItemSelected(item); } // The support library is being […]

在方向更改时保存UI – 如果保留Fragment,则onSaveInstanceState无法按预期工作

使用compat lib v1(因为某些错误而不使用v2 | 3); 这个问题的一个变种。 我有一个片段,其UI具有各种控件,我希望在方向更改时保持其状态。 父方活动在方向改变时被销毁(请不要告诉我有关清单变化以避免活动娱乐!!!!)。 该片段调用setRetainInstance(true) 。 1)现在我的理解是,具有唯一ID的视图应该保留一些状态,例如方向更改。 鉴于此,我希望onCreateView|onActivityCreated有一个非null的bundle,但它是null。 2)无论如何,如果我在onSaveInstanceState保存状态(确保我调用super),我仍然在’onCreateView | onActivityCreated’中得到一个空包。 3)如果我不调用setRetainInstance(true)那么即使我没有`onSaveInstanceState’方法,我也会在onCreateView|onActivityCreated得到一个非null的包。 我的问题是,这是否按预期工作,我对生命周期的理解被打破了? 无论如何,我猜测对我来说最好的方法是保留片段,然后在片段中保持控件的状态。 提前致谢。 彼得。

是否可以将项目拖到RecyclerView之外?

当我将一个项目从另一个RecyclerView拖放到它上面时,我需要以某种方式通知RecyclerView 。 可能吗? 或者我应该使用经典的拖放框架 ? 带有蓝色项目的RecyclerView位于一个片段中,带有红色项目的RecyclerView位于另一个片段中。 我也尝试过使用ItemTouchHelper,但是在从RecyclerView外部移动项目时,不会调用ItemTouchHelper.Callback的onMove()方法。 private class CustomItemTouchCallback extends Callback { @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { return makeMovementFlags(UP|DOWN|START|END, 0); } @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { android.util.Log.d(TAG, “Move item from:” + viewHolder.getAdapterPosition() + ” to: ” + target.getAdapterPosition()); return true; } @Override public void onMoved(RecyclerView recyclerView, […]

Android FragmentTabHost – 尚未完全出炉?

我想看看是否有人使用新的Android API级别17附带的FragmentTabHost自定义选项卡。 我很高兴能够在我的ViewPager SherlockFragments中嵌入tabHost,但是我很难做一些简单的事情,例如将标签移动到底部或更改标签的布局。 有谁见过使用这个function的好例子? 这是我在Android文档中find的唯一示例,而且几乎没有任何描述它的用法。 它似乎也忽略了R.id.fragment1布局中定义的内容。 我想我的问题是,如果有人遇到过一个很好的教程:FragmentTabHost,或者如果他们知道如何a)将嵌套标签置于底部或b)更改所述标签的布局。 我已经尝试了所有常用的方法,但由于看起来XML布局文件被覆盖,我没有太多运气。 private FragmentTabHost mTabHost; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { setContentView(R.layout.fragment_tabs); mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost); mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent); mTabHost.addTab(mTabHost.newTabSpec(“simple”).setIndicator(“Simple”), FragmentStackSupport.CountingFragment.class, null); mTabHost.addTab(mTabHost.newTabSpec(“contacts”).setIndicator(“Contacts”), LoaderCursorSupport.CursorLoaderListFragment.class, null); mTabHost.addTab(mTabHost.newTabSpec(“custom”).setIndicator(“Custom”), LoaderCustomSupport.AppListFragment.class, null); mTabHost.addTab(mTabHost.newTabSpec(“throttle”).setIndicator(“Throttle”), LoaderThrottleSupport.ThrottledLoaderListFragment.class, null); return mTabHost; } 在做了一些研究后,似乎可能会在支持库中初始化FragmentTabHost时出现故障。 Google代码上的用户提供了以下建议: FragmentTabHost.java private void initFragmentTabHost(Context context, AttributeSet attrs) { TypedArray […]

碎片相互重叠

我有一个带有3个标签的操作栏,每个标签打开一个片段。 第三个选项卡“目录”有一个列表: 当我点击某个项目时,它会打开另一个片段,该片段不属于操作栏: public void onClick(View v) { switch (v.getId()) { case R.id.category1: Fragment cosmeticsFragment = new ActivityCosmetics(); FragmentTransaction transaction = getFragmentManager().beginTransaction(); transaction.replace(android.R.id.content, cosmeticsFragment); transaction.addToBackStack(null); transaction.setTransition(1); transaction.commit(); break; … 这就是它之后的样子: 从这一点来说,如果我转到其他选项卡然后返回目录选项卡,我会看到之前的2个片段相互重叠: 我该如何防止它发生?

刷新片段内的视图

我搜索了很多看起来像这个问题的问题,但是没有find我的答案。 我有一个活动,通过操作栏可以访问3个选项卡。 我通过添加3个片段来实现这一点,这些片段会扩展我扩展视图类的自定义视图。 在数据库更改的那一刻,我尝试通过调用invalidate()/ postinvalidate()刷新我的选项卡中的视图,但这不起作用。 调用片段的onCreateView就像我考虑的其他选项一样。 然而,当我转到另一个选项卡然后返回时,已经进行了更改,并且我的视图会按原样更新。 如何模拟更改为另一个选项卡时发生的相同事情? 会发生什么 我试图查看Fragment生命周期(试图调用onCreateView())来解决它,但它只是不想刷新/重绘它应该。 正确加载数据,因为当我更改为另一个选项卡时数据会更改。 我删除了一些代码,因为它不再相关。 我实现了Cursorloaders而不是我自己的Observer模式来通知更改。 这是我现在的主要活动。 问题是,如果我想重绘这些片段中的视图,我现在应该怎么做。 如果我应用fragmentObject.getView()。invalidate()它不起作用。 我遇到了和以前一样的问题,但现在我的Observer通知加载器正确实现了数据库中的更改。 public class ArchitectureActivity extends Activity implements LoaderManager.LoaderCallbacks { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ActionBar actionbar = getActionBar(); actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); ActionBar.Tab EditTab = actionbar.newTab().setText(“Edit”); ActionBar.Tab VisualizeTab = actionbar.newTab().setText(“Visualize”); ActionBar.Tab AnalyseTab = actionbar.newTab().setText(“Analyse”); Fragment editFragment = new EditFragment(); […]

尝试在空对象引用上调用虚方法’android.os.Handler android.support.v4.app.FragmentHostCallback.getHandler()’

我的应用程序包含4个片段作为使用FragmentPagerAdapter加载到父片段内的制表符。 问题是,当我运行应用程序并按下并重新打开应用程序时,我收到此错误日志: FATAL EXCEPTION: main java.lang.NullPointerException: Attempt to invoke virtual method ‘android.os.Handler android.support.v4.app.FragmentHostCallback.getHandler()’ on a null object reference at android.support.v4.app.FragmentManagerImpl.ensureExecReady(FragmentManager.java:1949) at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:1965) at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:620) at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:143) at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:513) … 父片段内的代码行是: viewPager.setAdapter(adapter); tabLayout.setupWithViewPager(viewPager); 和ViewPage和Adapter都不是空的! 我必须提到我的所有Fragment的生命周期都在管理中,并且在适配器内部发生了null问题!当我使用Activity作为父级而不是Fragment时,同样的适配器工作正常!

Android:Fragment无法获得活动

我有一个执行片段事务的活动 DetailFragment newFragment = new DetailFragment(); transaction.replace(R.id.mylist, newFragment); transaction.addToBackStack(null); transaction.commit(); 工作正常。 现在我在我的活动中知道了一个动态字符串,我需要在newFragment中的布局中替换它。 我以为我可以在transaction.commit()之后调用类似的东西 newFragment.setMyString(“my dynamic value”); 而在newFragment.java中我有 public void setMyString(String s) { TextView tv = (TextView) getActivity().findViewById(R.id.myobject); tv.setText(s); } 关键是getActivity()返回null。 如何获得查找布局元素所需的上下文? 编辑: 我尝试使用捆绑包来跟踪路线,因为这似乎是最干净的方式。 所以我改变了我的代码: Bundle b = new Bundle(); b.putString(“text”, “my dynamic Text”); DetailFragment newFragment = new DetailFragment(); transaction.replace(R.id.mylist, newFragment); transaction.addToBackStack(null); transaction.commit(); 我的片段onCreateView看起来像这样: public View […]