This android tutorial shows how to swap two fragments. The goal was to re-use the fragment instances when rotating, no new fragment instances are re-created when rotating. There is also two layouts : one for portrait mode and one for landscape mode. In portrait mode, the second panel is below the first panel. In landscape mode, the second panel is on the right of the first panel. The support android library has been used.
Initial | After Swap | |
---|---|---|
Portrait | ||
Landscape |
Layout for portrait mode :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:baselineAligned="false">
<FrameLayout
android:id="@+id/container1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
</FrameLayout>
<FrameLayout
android:id="@+id/container2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
</FrameLayout>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:baselineAligned="false">
<FrameLayout
android:id="@+id/container1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
</FrameLayout>
<FrameLayout
android:id="@+id/container2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
</FrameLayout>
</LinearLayout>
Layout for landscape mode :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:baselineAligned="false">
<FrameLayout
android:id="@+id/container1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
</FrameLayout>
<FrameLayout
android:id="@+id/container2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
</FrameLayout>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:baselineAligned="false">
<FrameLayout
android:id="@+id/container1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
</FrameLayout>
<FrameLayout
android:id="@+id/container2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
</FrameLayout>
</LinearLayout>
FragmentSwappingActivity : in the activity we try to find the fragment instances in each container. If the fragment is not found, it is instantiated and loaded inside the container.
package org.michenux.fragswapping;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
public class FragmentSwappingActivity extends FragmentActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FragmentManager fm = getSupportFragmentManager();
Fragment frag1 = fm.findFragmentById(R.id.container1);
if ( frag1 == null ) {
frag1 = Panel1Fragment.newInstance();
FragmentHelper.initFragment( frag1, R.id.container1, fm);
}
Fragment frag2 = fm.findFragmentById(R.id.container2);
if ( frag2 == null ) {
frag2 = Panel2Fragment.newInstance();
FragmentHelper.initFragment( frag2, R.id.container2, fm);
}
}
}
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
public class FragmentSwappingActivity extends FragmentActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FragmentManager fm = getSupportFragmentManager();
Fragment frag1 = fm.findFragmentById(R.id.container1);
if ( frag1 == null ) {
frag1 = Panel1Fragment.newInstance();
FragmentHelper.initFragment( frag1, R.id.container1, fm);
}
Fragment frag2 = fm.findFragmentById(R.id.container2);
if ( frag2 == null ) {
frag2 = Panel2Fragment.newInstance();
FragmentHelper.initFragment( frag2, R.id.container2, fm);
}
}
}
The FragmentHelper class :
package org.michenux.fragswapping;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
public class FragmentHelper {
public static void initFragment( Fragment frag, int container, FragmentManager fm ) {
FragmentTransaction ft = fm.beginTransaction();
ft.add(container, frag);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.commit();
}
public static void swapFragment( int container1, int container2, FragmentManager fm ) {
Fragment f1 = fm.findFragmentById(container1);
Fragment f2 = fm.findFragmentById(container2);
FragmentTransaction ft = fm.beginTransaction();
ft.remove(f1);
ft.remove(f2);
ft.commit();
fm.executePendingTransactions();
ft = fm.beginTransaction();
ft.add(container1, f2);
ft.add(container2, f1);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}
}
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
public class FragmentHelper {
public static void initFragment( Fragment frag, int container, FragmentManager fm ) {
FragmentTransaction ft = fm.beginTransaction();
ft.add(container, frag);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.commit();
}
public static void swapFragment( int container1, int container2, FragmentManager fm ) {
Fragment f1 = fm.findFragmentById(container1);
Fragment f2 = fm.findFragmentById(container2);
FragmentTransaction ft = fm.beginTransaction();
ft.remove(f1);
ft.remove(f2);
ft.commit();
fm.executePendingTransactions();
ft = fm.beginTransaction();
ft.add(container1, f2);
ft.add(container2, f1);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}
}
The Panel1Fragment class: Nothing interesting in this class except the call to the swap.
package org.michenux.fragswapping;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
public class Panel1Fragment extends Fragment {
private static int countInstance = 1 ;
public static Panel1Fragment newInstance() {
Panel1Fragment frag = new Panel1Fragment();
Bundle args = new Bundle();
args.putInt("instanceNumber", countInstance);
frag.setArguments(args);
countInstance++ ;
return frag;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View mainView = inflater.inflate(R.layout.panel1, container, false);
int instanceNumber = getArguments().getInt("instanceNumber");
TextView txtView = (TextView) mainView.findViewById(R.id.panel1Number);
txtView.setText("instance number: "+instanceNumber);
Button oButton = (Button) mainView.findViewById(R.id.button1);
oButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentHelper.swapFragment(R.id.container1, R.id.container2, getFragmentManager());
}
});
return mainView;
}
}
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
public class Panel1Fragment extends Fragment {
private static int countInstance = 1 ;
public static Panel1Fragment newInstance() {
Panel1Fragment frag = new Panel1Fragment();
Bundle args = new Bundle();
args.putInt("instanceNumber", countInstance);
frag.setArguments(args);
countInstance++ ;
return frag;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View mainView = inflater.inflate(R.layout.panel1, container, false);
int instanceNumber = getArguments().getInt("instanceNumber");
TextView txtView = (TextView) mainView.findViewById(R.id.panel1Number);
txtView.setText("instance number: "+instanceNumber);
Button oButton = (Button) mainView.findViewById(R.id.button1);
oButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentHelper.swapFragment(R.id.container1, R.id.container2, getFragmentManager());
}
});
return mainView;
}
}
Layout for Panel1Fragment.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/panel1Text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Panel1" />
<TextView
android:id="@+id/panel1Number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Swap" >
</Button>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/panel1Text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Panel1" />
<TextView
android:id="@+id/panel1Number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Swap" >
</Button>
</LinearLayout>
I don’t post the Panel2Fragment source code. It is quite identical to the Panel1Fragment except it has no button.
In a future post, i will show how to do a master-detail view with fragments with the same constraint: re-using fragment instances.
In a future post, i will show how to do a master-detail view with fragments with the same constraint: re-using fragment instances.
0 commentaires:
Enregistrer un commentaire