- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
当方向改变时,应用会遇到这些问题:
有效的方法:在旋转屏幕之前,一切都按我希望的方式工作。
EditActivity 目的:编辑集合和项目字段。
此 Activity 以编程方式创建的 fragment :
初始布局:FragmentA 位于 FragmentB 之上,每个都有自己的 FrameLayouts。
当用户单击 FragmentB 的 ListView 项目时:将 FragmentA 替换为 FragmentC 以允许用户编辑该项目的字段。现在 FragmentC 位于 FragmentB 之上。
这似乎是一个非常简单的概念: Activity 的顶部用于编辑整个集合的属性或编辑集合中的单个项目。我觉得我在布局方面没有做任何奇妙的事情,所以我有点困惑,手机(模拟器)的简单旋转会导致这些问题,而我正费尽心机地尝试修复这些问题。
为什么 Android Fragment Guide example对我不起作用:他们的例子很像我正在做的,但他们的细节 fragment 要么在新 Activity 中打开,要么在当前 Activity 中的自己的框架中打开,他们不做任何 fragment 交换,所以我不能了解他们将如何使用 onSaveIstanceState 来保留可见的 fragment ,然后在 onCreate 中使用该信息来重新创建方向更改之前的 UI。
编辑:通过将 listfragment 放入 XML 中解决了一个问题,这解决了永久旋转的“加载...”问题。
最佳答案
已解决。哦,我走过的兔子洞……无论如何,如果您遇到这样的问题,需要考虑以下几点:
onSaveInstanceState(Bundle outState)
中编写任何代码。onSaveInstanceState
中处理后台堆栈或在 Activity 的 onCreate
中处理它。replace
而不是 `add' - 这可能是我遇到麻烦的根源之一。if(savedInstanceState == null)
,如果是,那么我知道该 Activity 之前没有因配置更改而被拆除,所以在这里,我构建了应该在 Activity 启动时立即显示的 fragment 。以编程方式在别处激活的其他 fragment (即,晚于 Activity 的 onCreate()
),它们不属于 if
,它们属于 其他
:else onSaveInstanceState != null
我知道这个东西不为 null 的原因只有一个,因为系统在 onSaveInstanceState(Bundle outState)
中创建了一个名为 outState 的 bundle 并 hucked它在 Activity 的 onCreate
方法中,我现在可以在其中获取我的 grubbies。所以在这里我知道一些事情:
onCreate
中创建的 fragment 仍然是 Activity 的一部分(我没有分离或销毁它们),但是,我不能对于通过用户的操作赋予生命的 fragment 的相同声明,这些 fragment 当前可能会或可能不会(在方向也就是配置更改时)附加到 Activity 。if-this-thing-is-attached
子句的好地方。我最初搞砸的一件事是我没有给所有以编程方式添加的 fragment 一个标签;给所有以编程方式添加的 fragment 标签。然后,我可以通过 savedInstanceState.containsKey(MY_FRAG_TAG)
和 getFragmentManager().findFragmentByTag(MY_FRAG_TAG)
所以这是 Activity 的 onCreate(简化):
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit);
// ...omitted code...
if(savedInstanceState == null){
// create fragment for collection edit buttons
editCollection = FragmentA.newInstance(someVariable);
// programmatically add fragment to ViewGroup
getFragmentManager().beginTransaction().replace(R.id.edit_topFrame, editCollection, EDIT_COLLECTIONS_TAG).commit();
}
// else there be stuff inside the savedInstanceState bundle
else{
// fragments that will always be in the savedInstanceState bundle
editCollectionFragment = (FragmentA)getFragmentManager().findFragmentByTag(EDIT_COLLECTIONS_TAG);
// fragments that may not be in the bundle
if(savedInstanceState.containsKey(EDIT_ITEM_TAG)){
editItemFragment = (FragmentC)getFragmentManager().getFragment(savedInstanceState, EDIT_ITEM_TAG);
}
}
// This fragment is NOT programmatically added, ie, it is statically found in an XML file.
// Hence, the system will take care of preserving this fragment on configuration changes.
listFrag = (ListViewFragment)getFragmentManager().findFragmentById(R.id.ListFragment);
// create adapter
adapter = new EditCursorAdapter(this, null);
// set list fragment adapter
listFrag.setListAdapter(adapter);
// prepare the loader
getLoaderManager().initLoader(LOADER_ID, null, this);
}
Activity 的列表 fragment 监听器,其中 FragmentC 被替换为 FragmentA:
// listfragment listener
@Override
public void listFragListener(Cursor cursor) {
// checking backstack size
Log.d(TAG, SCOPE +"backstack size: "+getFragmentManager().getBackStackEntryCount());
// With each listview click there should be only one item in the backstack.
getFragmentManager().popBackStack();
// create new fragment
editItemFragment = FragmentC.newInstance(cursor);
// programmatically add new fragment
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.edit_topFrame, editItemFragment, EDIT_ITEM_TAG);
ft.addToBackStack("pop all of these"); // was testing different ways of popping
ft.commit();
// interesting: this reports the same value as the first log in this method.
// ...clearly addToBackStack(null).commit() doesn't populate the backstack immediately?
Log.d(TAG, SCOPE +"backstack size: "+getFragmentManager().getBackStackEntryCount());
}
而 onSaveInstanceState 就像一只松鸦一样赤裸:
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
总结:我的 Activity 完全按照我想要的方式运行。
现在,如果我有一个 bunch 添加的 fragment ,那么我可能会以更编程的方式处理它们,而不是通过硬编码 if(savedInstanceState.contains(*hard coded key* )
。我对此进行了一些测试,但无法证明其有效性,但是对于外面的人来说,这可能会激发您可以做什么的想法:
创建一个私有(private)的添加 fragment 集:
// Collection of Frag Tags
private Set<String> AddedFragmentTagsSet = new HashSet<String>();
在 onAttachFragment
中执行如下操作:
@Override
public void onAttachFragment(Fragment fragment) {
super.onAttachFragment(fragment);
// logging which fragments get attached and when
Log.d(TAG, SCOPE +"attached fragment: " +fragment.toString());
// NOTE: XML frags have not frigg'n tags
// add attached fragment's tag to set of tags for attached fragments
AddedFragmentTagsSet.add(fragment.getTag());
// if a fragment has become detached remove its tag from the set
for(String tag : AddedFragmentTagsSet){
if(getFragmentManager().findFragmentByTag(tag).isDetached()){
AddedFragmentTagsSet.remove(tag);
}
Log.d(TAG, SCOPE +"contents of AddedFragmentTagsSet: " +tag);
}
}
然后在 Activity 的 onCreate
和 savedInstanceState
子句中:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit);
// ...omitted code...
if(savedInstanceState == null){
// create fragment for collection edit buttons
editCollection = FragmentA.newInstance(someVariable);
// programmatically add fragment to ViewGroup
getFragmentManager().beginTransaction().replace(R.id.edit_topFrame, editCollection, EDIT_COLLECTIONS_TAG).commit();
}
// else there be stuff inside the savedInstanceState bundle
else{
// fragments that will always be in the savedInstanceState bundle
editCollectionFragment = (FragmentA)getFragmentManager().findFragmentByTag(EDIT_COLLECTIONS_TAG);
//////////// find entries that are common to AddedFragmentTagsSet & savedInstanceState's set of keys ///////////
Set<String> commonKeys = savedInstanceState.keySet();
commonKeys.retainAll(AddedFragmentTagsSet);
for(String key : commonKeys){
editItemFragment = FragmentC)getFragmentManager().getFragment(savedInstanceState, key);
}
}
}
...但这未经测试,仅用于激发创意;在试图弄清楚我的 Activity 对配置更改的处理有什么问题时,我确实在这个方向上跌跌撞撞,并认为它可能会为合适的人带来成果;虽然最终,显然,这次我找到了一种更简单的方法来解决我的问题。
关于android - backstack 中的配置更改 fragment 现在共享 FrameLayout 后?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16740721/
我有一个像这样的 fragment 栈 F1 -> F2 -> F3 -> F4 -> F5 现在我需要删除 F2、F3、F4 fragment 。 我需要如果我从 F5 fragment 按下后退按
我需要帮助来理解以下场景的工作原理以及如何实现结果。 我有一个名为 ShoppingCart 的类。它有一个名为 addItemsToShoppingCartFromPreviousOrder 的方法
我有一个包含 ViewPager 的 fragment 。这个 ViewPager 显然是由其他 Fragments 填充的。 我的问题是,ViewPager 中的 Fragment 是否有任何方法(
所以我正在实现一个 FragmentActivity 并尝试添加一个 fragment ,但是我遇到了多个问题。我以前做过这个,实际上我使用的代码与上一个项目(它工作的地方)相同,但由于某种原因它在这
Closed. This question needs details or clarity。它当前不接受答案。
我想将 Android X fragment (androidx.fragment.app.Fragment) 转换为 Android native fragment (android.app.Fra
假设我有一个包含 10 列文本类型 (20) 的 SQLite 表。 ListFragment 将从数据库中提取 4 列并使用 SimpleCursorAdapter 显示在列表中。 选择后,List
我有一个对话框 fragment ,我为延迟初始化创建了一个类。当我显示对话框时,它显示正常。但是,当我关闭对话框时,它崩溃的原因是: fragment 与 fragment 管理器无关。 我也尝试过
我想在 View 分页器更改为 fragment 时刷新该 fragment 。 package com.mcivisoft.rcbeam; import android.os.Bundle; imp
我有一个名为的 Activity MainActivity 我在容器 R.id.mainContainer 中添加了 fragment “BenefitFragment”。 在 BenefitFrag
所以我有这个 ClientListView,效果很好,可以显示客户,我可以单击一个客户并在右侧获取他们的详细信息(在我的第二个 fragment 中)。由此处的布局定义: 这很好用,但后来我
我试过这段代码,但点击第一个 fragment 中的按钮并没有改变第二个 fragment 中的字符串值。 这是第一个 fragment 的 kotlin 文件。它有两个按钮,点击它们可以更改字符串值
我有以下情况:我打开 fragment A 和目标,通过按钮的单击事件转到 fragment B。当我在 fragment B 中并点击后退按钮(为了返回 fragment A) 我想将一些参数传递给
我制作了一个 NavigationDrawer fragment ,其中包含 Home、Settings、Feedback 等项目。 home 项在点击 home 时应该打开,home 是在应用程序启
我正在一个接一个地替换 2 个 fragment ,两个 fragment 都有不同的选项菜单。当我替换第二个 fragment 时,它也显示第一个 fragment 的菜单。 setHasOptio
我有问题: android.app.Fragment$InstantiationException: Unable to instantiate fragment ${packageName}.${a
我正在研究 fragment 转换。当我用第二个 fragment 替换第一个 fragment 时,它出现在第一个 fragment 的下方。我希望它移动到第一个 fragment 之上。我该怎么做
我在抽屉导航里总共有 12 个 fragment 。每个 fragment 都有 volley 方法。每个 fragment 都显示自己的 Volley 响应,除了 position = 1 和 po
我在我的 Activity 中使用了两个 fragment 。最初我将向 Activity 添加一个 fragment 。然后在第一个 fragment 中使用监听器我想用第二个 fragment 替
我正在实现一个“fragments-101”程序,当相应的按钮被点击时我会替换一个 fragment 。然而,下面的事情发生了: 为什么会这样?为什么初始 fragment 没有被完全替换?MainA
我是一名优秀的程序员,十分优秀!