是否可以刷新片段的视图

Posted

技术标签:

【中文标题】是否可以刷新片段的视图【英文标题】:Is it possible to refresh the view of a Fragment 【发布时间】:2012-04-10 23:06:40 【问题描述】:

以编程方式更改了我的应用程序的locale,如下所示:

Resources res = context.getResources();

 DisplayMetrics dm = res.getDisplayMetrics();
 android.content.res.Configuration conf = res.getConfiguration();
 conf.locale = new Locale("cn");
 res.updateConfiguration(conf, dm);

在此之后,我想刷新我当前显示的片段视图以使用新的区域设置显示。

所以,我首先得到当前片段(这是backstack中的最新片段):

BackStackEntry latestEntry=fragMgr.getBackStackEntryAt(fragMgr.getBackStackEntryCount()-1);
String str=latestEntry.getName();
Fragment fragment=fragMgr.findFragmentByTag(str);

得到当前显示的片段后,我想刷新它的视图,但是怎么做呢?在Android中

【问题讨论】:

您的意思是使视图无效吗? @blackbelt,不,我的意思是刷新,就像它在网页上的工作方式一样,如果您从网页中选择一种语言,页面就会刷新。 【参考方案1】:

您可以像下面这样简单地分离和附加片段

    Fragment currentFragment = getFragmentManager().findFragmentByTag("FRAGMENT");
    FragmentTransaction fragTransaction = getFragmentManager().beginTransaction();
    fragTransaction.detach(currentFragment);
    fragTransaction.attach(currentFragment);
    fragTransaction.commit();

这将刷新视图并且区域设置将改变

【讨论】:

但是我怎样才能将一些数据发送到片段?我现在在顶部看到一个空白视图。 如何将数据发送到片段?你应该使用 fragment.setArguments(Bundle extras);传递数据的方法。并且当您刷新片段时,数据将保持不变,因此您不会有任何问题。 是的,我这样做了,但 MyFragment 类没有调用 Fragment 生命周期。 这似乎只适用于以编程方式附加到活动的片段。对于已由 Activity 的 XML 布局文件实例化的片段,只有 onActivityCreated 会在 Activity 恢复时调用,因此片段仍显示旧的本地化。 帮助避免未来用户出现问题的快速说明:在此处的 google 组中:groups.google.com/forum/#!topic/android-platform/QlkLMsncDwg Dianne Hackborn 指出,在 FragmentTransaction 中分离 Fragment 不会调用 onAttach()onDetach()对于那个Fragment。因此,不要依赖这些生命周期方法来刷新视图。【参考方案2】:

您可以创建一个侦听器,当区域设置更改时将调用该侦听器。然后这将删除片段,并重新添加片段。然后应该选择您的新语言环境。

【讨论】:

监听器应该在哪里创建?你能更具体地说明一下如何做吗? 创建您自己的界面,由您的活动实现。然后在 onAttach() 中使用您的片段注册侦听器。更改语言环境时,调用接口中的方法,并删除/重新添加片段【参考方案3】:

我终于找到了解决办法! 只需在 UI 线程中运行视图更新代码

示例 -

 getActivity().runOnUiThread(new Runnable() 
            @Override
            public void run() 
                user_arrayList.add(name);
                adapter.notifyDataSetChanged();
                tv_total_users.setText("Total Users : "+user_arrayList.size());
            
        );

尝试了将近 4-5 小时终于找到了这个解决方案!

【讨论】:

即使问题是 2 岁......恕我直言,这是你能做的最糟糕的事情。你真的应该使用onCreateonResume【参考方案4】:

最终对我有用的解决方案是在 Kotlin 中:

        val manager = requireActivity().supportFragmentManager
        
        manager.beginTransaction().let 
            it.detach(this)
            it.commit()
        
        manager.executePendingTransactions()
        manager.beginTransaction().let 
            it.attach(this)
            it.commit()
        

请注意我是如何在在单独的事务中分离和重新附加片段的。 From the Android docs:

由于 FragmentTransaction 被视为单个原子操作集,因此在同一事务中对同一片段实例的分离和附加调用有效地相互抵消,从而避免破坏和立即重新创建片段的 UI。使用单独的事务,如果使用 commit(),则由 executePendingOperations() 分隔,如果要分离然后立即重新附加片段。

【讨论】:

以上是关于是否可以刷新片段的视图的主要内容,如果未能解决你的问题,请参考以下文章

刷新片段内的视图

如何刷新片段上的列表视图

从列表视图中删除一行后刷新片段

片段中的 notifyDataSetChanged() 不刷新列表视图

无法从 ViewPager 中的另一个片段刷新/更新片段中的列表视图

是否可以在片段中手动调用 onCreateView?