I have created a MainActivity like TabActivity (only like) and added four Fragments
to it. At one time only one can be displayed. So when any one tab(image
) is clicked I hide all other fragment and show the fragment associated with the tab. I am successful in achieving it. I have found two solution to do the same work but I want to know which one is efficient and which I prefer
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);
}
}
}
see the showFragment()
function in MainActivity. it can do the same work by two different ways
By hiding all fragment and show the fragment which you want to show.
private void showFragment(int x)
{
for(int j = 0; j < 4; j++)
{
getFragmentManager().beginTransaction().hide(frag[j]).commit();
}
getFragmentManager().beginTransaction().show(frag[x]).commit();
}
Detaching all activity and attach the fragment which you want to show. In this method i have to add 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();
}
According to my thinking , the second method is efficient but I want to know your opinion about this.
it is my Supposition / Understanding (may be wrong)
When we hide all fragment but show our desire one. These fragments hide but take space/memory. while when we attach it will Recreate with the last state save and don't take space before recreating.
The detach
method removes the fragment from the UI, but its state
is maintained by the FragmentManager
. This means you can reuse this fragment
by calling the attach
method, with a modified ViewHierarchy
Why aren't you simply using a ViewPager
? And both methods are pretty much equal, no significant difference is there. Would you expect there to be one? You are holding a reference to all Fragments in one array. You are not efficiently recycling Fragments
like a FragmentStatePagerAdapter
would for a ViewPager
you are just constantly holding the reference to all of them. How you hide and show the Fragments makes no difference all the Fragments
are sill constantly in memory.
And you don't need to perform a FragmentTransaction
for every single Fragment
. If you really want to improve performance, than replace all Fragments
in one single FragmentTransaction
like this:
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
for(int j=0; j < 4; j++) {
transaction.hide(...);
}
transaction.show(...);
transaction.commit();
That you perform 5 FragmentTransactions
here:
for(int j=0;j<4;j++) {
if(j !=x)
{
getFragmentManager().beginTransaction().detach(frag[j]).commit();
}
}
getFragmentManager().beginTransaction().attach(frag[x]).commit();
Instead of combining all of that into one is surely a much bigger drag on performance than the difference between detach()
/attach()
and hide()
/show()
.
But for the record: using detach()
and attach()
instead of hide()
and show()
would be slightly better memory-wise because those two methods allow for the view hierarchy of unused Fragments
to be destroyed.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments