替换片段的有效方法

时间:2014-07-22 10:24:08

标签: android fragment

我创建了一个 MainActivity ,如TabActivity(仅限于),并为其添加了四个Fragments。有一次只能显示一个。因此,当单击任何一个选项卡image)时,我会隐藏所有其他片段并显示与该选项卡关联的片段。我成功地实现了它。我找到了两个解决方案来做同样的工作,但我想知道哪个是有效的,哪个更喜欢

MainActivity.class

public class MainActivity extends Activity //implements FragmentDelegate, FragmentManager.OnBackStackChangedListener
{
    private final String TAG = "Main";
    public LinearLayout tab1,tab2,tab3,tab4;
    public ImageView img1,img2,img3,img4;

    Fragment[] frag = new Fragment[4];

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.practicing);

        init();
    }   

    @SuppressLint("NewApi")
    private void showFragment(int x)
    {
        for(int j = 0; j < 4; j++)
        {
            //getFragmentManager().beginTransaction().hide(frag[j]).commit();
            if(j !=x )
            {
                getFragmentManager().beginTransaction().detach(frag[j]).commit();
            }
        }
        //getFragmentManager().beginTransaction().show(frag[x]).commit();
        getFragmentManager().beginTransaction().attach(frag[x]).commit();
    }
    private void init()
    {
        tab1 = (LinearLayout) findViewById(R.id.tab1);
        tab2 = (LinearLayout) findViewById(R.id.tab2);
        tab3 = (LinearLayout) findViewById(R.id.tab3);
        tab4 = (LinearLayout) findViewById(R.id.tab4);
        img1 = (ImageView)findViewById(R.id.tab_img1);
        img2 = (ImageView)findViewById(R.id.tab_img2);
        img3 = (ImageView)findViewById(R.id.tab_img3);
        img4 = (ImageView)findViewById(R.id.tab_img4); 

        frag[0] = new Article();
        frag[1] = new Forum();
        frag[2] = new Medias();
        frag[3] = new Profile();

        for(int i = 0; i < 4; i++)
        {
            getFragmentManager().beginTransaction().add(R.id.container, frag[i])
            //.addToBackStack(null)
            .commit();
        }   
        showFragment(0);
    }

    public void selectFrag(View view) 
    {
        if (view == findViewById(R.id.tab1)) 
        {           
            img1.setBackgroundResource(R.drawable.articles_on);
            img2.setBackgroundResource(R.drawable.forum_off);
            img3.setBackgroundResource(R.drawable.video_off);
            img4.setBackgroundResource(R.drawable.profile_off);

            showFragment(0);
        } 
        else if(view == findViewById(R.id.tab2)) 
        {
            img1.setBackgroundResource(R.drawable.articles_off);
            img2.setBackgroundResource(R.drawable.forum_on);
            img3.setBackgroundResource(R.drawable.video_off);
            img4.setBackgroundResource(R.drawable.profile_off);

            showFragment(1);
        }
        else if(view == findViewById(R.id.tab3))
        {
            img1.setBackgroundResource(R.drawable.articles_off);
            img2.setBackgroundResource(R.drawable.forum_off);
            img3.setBackgroundResource(R.drawable.video_on);
            img4.setBackgroundResource(R.drawable.profile_off);
        }
        else if(view == findViewById(R.id.tab4))
        {
            img1.setBackgroundResource(R.drawable.articles_off);
            img2.setBackgroundResource(R.drawable.forum_off);
            img3.setBackgroundResource(R.drawable.video_off);
            img4.setBackgroundResource(R.drawable.profile_on);

            showFragment(3);
        }
    }
}

查看MainActivity中的showFragment()功能。它可以通过两种不同的方式完成同样的工作

  1. 隐藏所有片段并显示您想要显示的片段。

        private void showFragment(int x)
        {
            for(int j = 0; j < 4; j++)
            {
                getFragmentManager().beginTransaction().hide(frag[j]).commit();
            }
            getFragmentManager().beginTransaction().show(frag[x]).commit();
        }
    
  2. 分离所有活动并附加要显示的片段。在这种方法中,我必须添加SuppressLint("NewApi")。 ..

    @SuppressLint("NewApi")
    private void showFragment(int x)
    {
        for(int j = 0; j < 4; j++)
        {
            if(j != x)
            {
                getFragmentManager().beginTransaction().detach(frag[j]).commit();
            }
        }
        getFragmentManager().beginTransaction().attach(frag[x]).commit();
    }
    
  3. 根据我的想法,第二种方法是有效的,但我想知道你对此的看法。

    这是我的假设/理解(可能是错误的)

    当我们隐藏所有片段但显示我们的欲望时。这些片段隐藏但占用空间/内存。当我们附加它时,将重新创建最后一个状态保存,并且在重新创建之前不要占用空间。

    detach方法会从用户界面中删除该片段,但state会保留其FragmentManager。这意味着您可以通过调用fragment方法重新使用此attach,并修改ViewHierarchy

1 个答案:

答案 0 :(得分:1)

为什么不是简单地使用ViewPager?两种方法都非常相同,没有显着差异。你希望有一个吗?您正在对一个数组中的所有片段进行引用。您没有像Fragments那样有效地回收FragmentStatePagerAdapter ViewPager,而是Fragments您只是不断地持有对所有这些内容的引用。你如何隐藏和显示碎片没有任何区别所有FragmentTransaction都是不断记忆的。

您无需为每个Fragment执行Fragments。如果您真的想提高效果,请在一个FragmentTransaction中替换所有FragmentManager manager = getFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); for(int j=0; j < 4; j++) { transaction.hide(...); } transaction.show(...); transaction.commit(); ,如下所示:

FragmentTransactions

你在这里执行5 for(int j=0;j<4;j++) { if(j !=x) { getFragmentManager().beginTransaction().detach(frag[j]).commit(); } } getFragmentManager().beginTransaction().attach(frag[x]).commit();

detach()

而不是将所有这些合并为一个肯定会比attach() / hide()show() / detach()之间的差异大得多。

但是对于记录:使用attach()hide()而不是show()Fragments稍微好一些内存,因为这两种方法允许视图层次结构未使用的{{1}}将被销毁。