平常我们写一个完整流程,比如做个转账,第一个页面输入金额,第二个确认金额,第三个展示结果,那么按平常做法是不是要写三个activity来分别写每个页面,这时activity栈就会放入三个activity进去,如果页面越多那么activiy栈层层叠放,我们想做页面跳转起来就麻烦了。
现在我们就用一个activity+三fragment个来实现这三个页面。大体流程就是这样
首先贴上代码
public class LoginActivity extends AppCompatActivity implements CallBack {
public static final int TOFRAG_LOGIN = 0x01;
public static final int TOFRAG_NEXT = 0x02;
public static final int TOFRAG_RESULT = 0x03;
public static final int TOFRAG_BACK = 0x99;
private Fragment newFragment;// 当前fragment
private FragmentManager fm;// fragment管理器
private int level;// 当前fragment的等级
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
StatusBarCompat.compat(this);
setContentView(R.layout.activity_common);
init();
}
public void init() {
// TODO Auto-generated method stub
Bundle bundle = new Bundle();
bundle.putInt(CommDictAction.TO_FRAG, TOFRAG_LOGIN);
callback(bundle);
}
@Override
public Bundle callback(Bundle args) {
// TODO Auto-generated method stub
if (args != null && args.containsKey(CommDictAction.TO_FRAG)) {
int to_frag = args.getInt(CommDictAction.TO_FRAG);
switch (to_frag) {
case TOFRAG_LOGIN:
if (newFragment == null) {
switchFragment(LoginFragment.newInstance(args), 1);
} else {
if (newFragment instanceof LoginFragment) {
} else {
switchFragment(LoginFragment.newInstance(args), 1);
}
}
break;
case TOFRAG_NEXT:
switchFragment(NextFragment.newInstance(args), 2);
break;
case TOFRAG_RESULT:
switchFragment(ResultFragment.newInstance(args), 3);
break;
case TOFRAG_BACK:
onBackPressed();
break;
}
}
return null;
}
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
if (level == 3) {
level = 2;
fm.popBackStackImmediate(level + "",
FragmentManager.POP_BACK_STACK_INCLUSIVE);
level--;
newFragment = fm.findFragmentByTag(level + "");
} else if (level == 2) {
fm.popBackStackImmediate(level + "",
FragmentManager.POP_BACK_STACK_INCLUSIVE);
level--;
newFragment = fm.findFragmentByTag(level + "");
} else if (level == 1) {
finish();
} else {
finish();
}
}
/**
* 添加fragment的方法
*
* @param newFrag
* 当前fragment
*
* @param mlevel
* 当前fragment在栈中的位置
*/
private void switchFragment(BaseFragment newFrag, int mlevel) {
if (fm == null) {
fm = getSupportFragmentManager();
}
FragmentTransaction ft = fm.beginTransaction();// 对于每一次切换fragment都必须获取一个新的ft
if (mlevel == 1) {
ft.setCustomAnimations(R.anim.anim_duration_0,
R.anim.anim_duration_0);
} else {
ft.setCustomAnimations(R.anim.slide_right_in,
R.anim.slide_left_out, R.anim.slide_left_in,
R.anim.slide_right_out);
}
if (newFragment != null) {// 隐藏上一个fragment
ft.hide(newFragment);
}
level = mlevel;
newFragment = newFrag;
ft.add(R.id.fragment, newFragment, level + "");
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(level + "");
ft.commit();
}
这里activity实现了一个CallBack的接口,接口代码如下,是为了方便fragment之间的数据传递,在fragment中可以通过该回调接口进行fragment的跳转
public interface CallBack {
/**
* 回调方法
*
* @param args
* 传递的参数?
* @return bundle
*/
public Bundle callback(Bundle args);
}
我的xml文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/bg_color"
android:fitsSystemWindows="true" >
<FrameLayout
android:id="@id/fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout></RelativeLayout>
如果类似交易很多,activity只需要一个xml就可以了,只是不同fragment之间要配置不同xml。
回到我们的activity中:
callback():
init()方法中调用了callback()方法,初始化一个fragment,该方法也是实现fragment之间跳转的控制器,在不同fragment中可以调用callBack.callback(bundle);来处理跳转到哪个fragment。
switchFragment()方法:
该方法是控制fragment隐藏,显示,动画以及出入栈的控制。ft.setCustomAnimations()是给fragment之间跳转设置跳转动画,也就是fragment进入和退出的动画。ft.hide(newFragment)必须调用,隐藏上一次的fragment,否则页面会出现fragment重叠的现象。ft.add()指定页面上放置fragment的位置,并且设置一个target,也就是level。这里选择add而没有用replace,因为replace是不会保存上一次fragment,每次返回后,都会重新new一个新的fragment。ft.addToBackStack()加入到fragment的回退栈,在处理返回的时候会用到。
onBackPressed()方法:
这里就是处理返回了,popBackStackImmediate()fragment的出栈方法,它会传出要出栈的target,也就是我们上面定义的level。值得注意的是如果当前栈中有1,2,3,4个fragment,我们popBackStackImmediate(2),那么会将2,3,4三个fragment都弹出栈去。
在fragment中要怎么处理跳转了,就这样
public void login() {
Bundle bundle = new Bundle();
bundle.putString("name", et_name.getText().toString());
bundle.putInt(CommDictAction.TO_FRAG, LoginActivity.TOFRAG_NEXT);
callBack.callback(bundle);
}
ok,其实fragment在activity中管理很灵活,你还可以加入viewpager做一个仿微信的主页面。
附上代码:
http://download.youkuaiyun.com/detail/gaopin_xianlu/9706355