温馨提示:本文翻译自stackoverflow.com,查看原文请点击:java - How to inflate fragment's layout in AppCompatActivity.onCreate()?
android android-fragments java optimization

java - 如何在AppCompatActivity.onCreate()中膨胀片段的布局?

发布于 2020-04-10 17:02:18

我创建了一个简单的应用程序来学习片段。它由一个带有三个菜单项的bottomNavigationView以及一个FrameLayout组成,该FrameLayout充当片段的容器,并占据了其余空间。选择一个项目可通过以下方式在FrameLayout中切换片段:

getSupportFragmentManager().beginTransaction().replace(R.id.fragmentContainer,selectedFragment).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).commit();

当我运行该应用程序时,我注意到片段之间的过渡非常缓慢。Profiler透露这是由于每次布局膨胀引起的。因此,我将片段的onCreateView()方法修改为仅膨胀一次,然后返回已经膨胀的布局。

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if(ui == null)
            inflateLayout(inflater, container);
        return ui;

    }

这解决了部分问题,因为第一次转换仍然很慢。我想在活动中为片段UI充气,但这导致了一个错误:片段未附加到上下文。所以我只是在主要活动的onCreate()中的所有片段之间切换:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    BottomNavigationView nav = findViewById(R.id.bottom_nav);
    homeFragment = new HomeFragment();
    favFragment = new FavFragment();
    starFragment = new StarFragment();
    nav.setSelectedItemId(R.id.home);
    getSupportFragmentManager().beginTransaction().replace(R.id.fragmentContainer, starFragment).commit();
    getSupportFragmentManager().beginTransaction().replace(R.id.fragmentContainer, favFragment).commit();
    getSupportFragmentManager().beginTransaction().replace(R.id.fragmentContainer, homeFragment).commit();
    nav.setOnNavigationItemSelectedListener(listener);
}

这使事情变得更好,但是StarFragment中包含的recyclerView仍然在“真实”事务(由侦听器启动)之后创建viewHolders,单个viewHolder花费20ms的时间(我将在后面讨论原因)。

我的问题是:如何快速处理片段之间的事务?我想做对的事情还是有更好的方法?

查看更多

提问者
xsw2_2wsx
被浏览
77
Reaz Murshed 2020-02-02 00:42

我不确定您的布局有多复杂,但是,如果数据加载器(RecyclerView从数据库中读取值,网络调用)是非线程的,则在片段的布局中加载UI元素应该不会花费很多时间

您实际上不必在onCreate活动功能中执行所有片段事务单击底部导航栏中的项目时,只需按需加载片段(或执行片段事务)。您正在onCreate函数中创建片段的实例,这非常好,这样,每次在片段之间切换时,就不会创建片段类的新实例。

我不确定是否可以更好地优化片段的初始加载,但是,您可以考虑使用,ViewPager以便在第一次加载片段之后就一直加载片段。

这是有关如何ViewPager使用底部导航栏添加的很好的教程希望对您有所帮助!