简体   繁体   English

显示片段时只有 Switch.setChecked 不起作用?

[英]Only Switch.setChecked doesn't work when fragment is shown?

Okey, so first i have an activity好的,所以首先我有一个活动

public class MainActivity extends FragmentActivity
{
    private FragmentA a;
    private FragmentB b;
    private FragmentC c;
    private HomeFragment mHomeFragment;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.home_activity_layout);
     FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.fragment_container, mHomeFragment) // replace flContainer
                .addToBackStack(null)
                .commit();

    ...
    }

i use some lazy initialiser, and i keep my object a, b, c and mHomeFragment inside my activity object,我使用了一些懒惰的初始化程序,并将对象 a、b、c 和 mHomeFragment 保存在我的活动对象中,

i have a button inside 'b' that calles the MainActivity to call 'c' and a button inside 'c' that calles the MainActivity to call 'b'我在“b”中有一个按钮,它调用 MainActivity 来调用“c”,“c”中有一个按钮,它调用 MainActivity 来调用“b”

and some other buttons to call 'a' wich is not that important和其他一些按钮来调用“a”,这并不重要

Well now inside my FragmentB i have some custom views,现在在我的 FragmentB 中,我有一些自定义视图,

  public CustomView(Context cnx, SettingsViewElement e, FragmentA fragment)
    {
    super(cnx);
    inflate(cnx, R.layout.my_layout,this);
    parent = fragment; // i use it later in my onCheckedChangeListener to tell him the the switch has been checked 
    condition = parent.getCondition();

    titleTv = this.findViewById(R.id.title_tv);
    switch  = this.findViewById(R.id.switch);
    if(condition){
    switch.setChecked(true);
    titleTv.setTitle("i am depressed af :(");

    }



my question is :我的问题是:

why my switch doesn't turn checked even if my titleTv is updating the title ??为什么即使我的 titleTv 正在更新标题,我的开关也不会被选中?

i did some tests and my OnCreated() is called each time i call replace() in my fragment transaction.我做了一些测试,每次我在片段事务中调用 replace() 时都会调用我的 OnCreated()。

my fragment re-instantiate the views and then will add them to a linearLayout after inflating layout.我的片段重新实例化视图,然后在膨胀布局后将它们添加到线性布局。

Also, if i don't keep my fragments reference in my MainActivity and then re-instantiate it every time.另外,如果我不将片段引用保留在 MainActivity 中,然后每次都重新实例化它。 here : the switch.setChecked will work , but the backStack will be huge and dumb此处:switch.setChecked 将起作用,但 backStack 将是巨大而笨拙的

example : stack = 'b' -> 'c' -> 'b' -> 'c' normaly when the user click twice return button he'll be back to homeFragment, he doesn't need to empty the stack by itself.例如:stack = 'b' -> 'c' -> 'b' -> 'c' 通常当用户点击两次返回按钮时,他会回到 homeFragment,他不需要自己清空堆栈。

and even if i override @onBackPressed() and re-instantiate the fragments each time hoping the android sdk will free the space.即使我每次都覆盖 @onBackPressed() 并重新实例化片段,希望 android sdk 能够释放空间。

i will have to do it manually each time i want to add a new fragment in my design , it will be aa wheel re-invention.每次我想在我的设计中添加一个新片段时,我都必须手动完成,这将是轮子的重新发明。

and : IT DOES NOT EXPLAIN WHY THE Switch.setChecked() doesnt work even if the condition is true and the other views are updating (textView is updating it's text)并且:即使条件为真并且其他视图正在更新(textView 正在更新它的文本),它也没有解释为什么Switch.setChecked() 不起作用

Update : Apparently,更新:显然,

if the fragment is being re-used and the onCreate() is called for the seconde time, (the reference for the fragment is being kept somewhere and fragment is being attached for a seconde time) here the setChecked will not take an effect, only some other view updates如果片段被重用并且 onCreate() 被第二次调用,(片段的引用被保存在某处并且片段被附加了第二次)这里 setChecked 不会生效,只有其他一些视图更新

meanwhile, it will only work if it's being called for the first time the fragment is being created,同时,它仅在第一次创建片段时被调用时才有效,

Solution : updating the views in the OnResume() methode解决方案:更新 OnResume() 方法中的视图

If someone has an explanation for this, please go ahead如果有人对此有解释,请继续

Views save and restore (some) of there state in the course of saveInstanceState/restoreInstance cycle, but unfortunatrly the checked state (and also visibility etc) are not covered by that.视图在 saveInstanceState/restoreInstance 循环过程中保存和恢复(一些)那里的状态,但不幸的是,检查状态(以及可见性等)不包括在内。 So you'll have implement onSaveInstanceState etc. for your fragment and save/restore the checked state yourself.因此,您将为片段实现 onSaveInstanceState 等,并自己保存/恢复检查状态。

EDIT编辑

From your question it is not apparent what view switch actually is so I cannot give you actual code.从你的问题来看,实际上什么视图switch并不明显,所以我不能给你实际的代码。 But have a look at the implementation of CheckedTextView and check out the implementation of onSaveInstanceState() and onRestoreInstanceState() .但是看看CheckedTextView的实现并检查onSaveInstanceState()onRestoreInstanceState() You'll see that they save and restore the checked state (it's quite a lot of code with the SavedState class but in the end it is pretty simple).您会看到它们保存和恢复选中状态(SavedState 类的代码相当多,但最后它非常简单)。 What you need to do, is to implement those two methods for your custom view (also creating your own SavedState inner class) and save/restore the checked state of your switch view.您需要做的是为您的自定义视图实现这两种方法(同时创建您自己的 SavedState 内部类)并保存/恢复切换视图的选中状态。

A completely different and better approach would be to use a ViewModel for your fragment that holds the state, but that's a different story that would require lots of changes to your complete implementation.一种完全不同且更好的方法是将ViewModel用于保存状态的片段,但这是一个不同的故事,需要对完整实现进行大量更改。

Update : Apparently,更新:显然,

if the fragment is being re-used and the onCreate() is called for the seconde time, (the reference for the fragment is being kept somewhere and fragment is being attached for a seconde time) here the setChecked will not take an effect, only some other view updates如果片段被重用并且 onCreate() 被第二次调用,(片段的引用被保存在某处并且片段被附加了第二次)这里 setChecked 不会生效,只有其他一些视图更新

meanwhile, it will only work if it's being called for the first time the fragment is being created,同时,它仅在第一次创建片段时被调用时才有效,

Solution : updating the views in the OnResume() methode解决方案:更新 OnResume() 方法中的视图

If someone has an explanation for this, please go ahead如果有人对此有解释,请继续

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM