如何通过切换片段来避免每次创建Fragment对象?

时间:2017-09-13 18:25:58

标签: android android-fragments android-activity fragment

我在应用程序中只有一个活动有4个片段,这些片段是切换到底部标签菜单。因此,它一直是屏幕上4个片段中的一个。看起来很简单,但我问自己为什么通过切换片段,每次都必须重新创建新的Fragment对象?这是来自android文档:

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
// Replace the contents of the container with the new fragment
ft.replace(R.id.your_placeholder, new FooFragment());
// or ft.add(R.id.your_placeholder, new FooFragment());
// Complete the changes added above
ft.commit();

我可以尝试自己存储对片段的引用,每次都选择就绪对象,但是我找到了这种片段使用方式的例子,所以它可能有问题吗?

3 个答案:

答案 0 :(得分:1)

您可以在ViewPager中设置片段,只需切换ViewPager页面。

试试这个:

    viewPager = (ViewPager) findViewById(R.id.viewpager);
    FragmentAdapter adapter = new FragmentAdapter(getSupportFragmentManager());
    adapter.addFragment(new ExplorerFragment(), "Fragment1", false);
    adapter.addFragment(new NotificationFragment(), "Fragment2", false);
    adapter.addFragment(new HistoryFragment(), "Fragment3", false);
    adapter.addFragment(new AccountFragment(), "Fragment4", false);
    viewPager.setAdapter(adapter);

    bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            int id = item.getItemId();
            switch (id){
                case R.id.action_explorer:
                    viewPager.setCurrentItem(0);
                    final Menu bottomMenu = bottomNavigationView.getMenu();
                    final MenuItem targetMenuItem = bottomMenu.getItem(0);
                    targetMenuItem.setChecked(true);
                    break;
                case R.id.action_notification:
                    viewPager.setCurrentItem(1);
                    final Menu bottomMenu1 = bottomNavigationView.getMenu();
                    final MenuItem targetMenuItem1 = bottomMenu1.getItem(1);
                    targetMenuItem1.setChecked(true);
                    break;
                case R.id.action_history:
                    viewPager.setCurrentItem(2);
                    final Menu bottomMenu2 = bottomNavigationView.getMenu();
                    final MenuItem targetMenuItem2 = bottomMenu2.getItem(2);
                    targetMenuItem2.setChecked(true);
                    break;
                case R.id.action_account:
                    viewPager.setCurrentItem(3);
                    final Menu bottomMenu4 = bottomNavigationView.getMenu();
                    final MenuItem targetMenuItem4 = bottomMenu4.getItem(3);
                    targetMenuItem4.setChecked(true);
                    break;
                case R.id.action_search:
                    break;
            }
            return true;
        }
    });

Edit1:如何创建NonSwipeableViewPager:

public class NonSwipeableViewPager extends ViewPager {

    public NonSwipeableViewPager(Context context) {
        super(context);
        setMyScroller();
    }

    public NonSwipeableViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        setMyScroller();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        // Never allow swiping to switch between pages
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // Never allow swiping to switch between pages
        return false;
    }

    //down one is added for smooth scrolling

    private void setMyScroller() {
        try {
            Class<?> viewpager = ViewPager.class;
            Field scroller = viewpager.getDeclaredField("mScroller");
            scroller.setAccessible(true);
            scroller.set(this, new MyScroller(getContext()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public class MyScroller extends Scroller {
        public MyScroller(Context context) {
            super(context, new DecelerateInterpolator());
        }

        @Override
        public void startScroll(int startX, int startY, int dx, int dy, int duration) {
            super.startScroll(startX, startY, dx, dy, 350 /*1 secs*/);
        }
    }
}

然后在您的XML中:

<com.project.Components.NonSwipeableViewPager
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@id/bottom_navigation"/>

答案 1 :(得分:1)

创建所有片段并使用它或将片段对象作为单例进行制作。

Singleton示例:

.gitignore

使用class MyFragment extends Fragment{ private static MyFragment instance; public static MyFragment getInstance(){ if(instance == null) instance = new MyFragment(); return instance; } }

创建对象片段

现在它不会每次都创建新的对象。

答案 2 :(得分:0)

您可以在替换时为片段添加TAG,然后使用FragmentManager的{​​{1}} {<1}}检索它:

findFragmentByTag