概述
- 时下APP主流主界面Tab切换框架之一 --- Fragment 的搭建。
- Fragment作为内容区域:MainActivity只作为一个调度器,支配Fragment的显示和隐藏,使得管理的控件事件等不需放在MainActivity中造成代码冗长,便于复用及后期维护。
- 解决 ' 切换Tab反复初始化Fragment影响性能、增加流量消耗 ' 问题。
- 解决 ' 横竖屏切换导致内容重叠 ' 问题。
- 源码:https://github.com/tyyecec/EczomFrame
// RadioButton抽取style
// RadioButton选择器
// 在onCreate()中getActivity()得到上下文bfContext
// 在onCreateView()中initView()
// 在onActivityCreated()中initData()
// 由子类实现不同的视图效果
public abstract View initView();
// 子类需联网请求数据时重写
public void initData() { }
public class EFragment extends BaseFragment {
private TextView textView;
@Override
public View initView() {
textView = new TextView(bfContext);
textView.setGravity(Gravity.CENTER);
textView.setTextSize(70);
return textView;
}
@Override
public void initData() {
super.initData();
textView.setText("E");
}
}
// 各Fragment实例
private EFragment eFragment;
private CFragment cFragment;
private ZFragment zFragment;
private OFragment oFragment;
private MFragment mFragment;
private void initFragment() {
eFragment = new EFragment();
cFragment = new CFragment();
zFragment = new ZFragment();
oFragment = new OFragment();
mFragment = new MFragment();
}
private void initListener() {
rgTab.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
Fragment fragment = null;
switch (i) {
case R.id.rb_e:
fragment = eFragment;
break;
case R.id.rb_c:
fragment = cFragment;
break;
case R.id.rb_z:
fragment = zFragment;
break;
case R.id.rb_o:
fragment = oFragment;
break;
case R.id.rb_m:
fragment = mFragment;
break;
}
// 切换对应Fragment
switchFragment(cacheFragment, fragment);
}
});
// 默认选择E
rgTab.check(R.id.rb_e);
}
由于replace()会导致每次切换Tab都重新初始化Fragment,造成性能上的影响及流量的多余消耗。此次,采用add() + hide() + show()的方式实现Fragment只初始化一次。
// 当前Fragment缓存
private Fragment cacheFragment;
private void switchFragment(Fragment nowFragment, Fragment toFragment) {
if (nowFragment != toFragment) {
// 缓存即将切换的Fragment,以便下一次对比判断
cacheFragment = toFragment;
// 开启事物
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
// 判断即将切换的Fragment是否add过
if (!toFragment.isAdded()) {
// 初始无缓存,需判断
if (nowFragment != null) {
// 隐藏当前Fragment
ft.hide(nowFragment);
}
// 添加即将切换的Fragment,并提交事物
ft.add(R.id.fl_main, toFragment).commit();
} else {
// 初始无缓存,需判断
if (nowFragment != null) {
// 隐藏当前Fragment
ft.hide(nowFragment);
}
// 显示即将切换的Fragment,并提交事物
ft.show(toFragment).commit();
}
}
}
// AndroidManifest.xml中配置configChanges属性,禁止切换时重新加载Activity
package com.eczom.eczomframe.activity;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import com.eczom.eczomframe.R;
public class WelcomeActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
//2s后进入主界面
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
startActivity(new Intent(WelcomeActivity.this,MainActivity.class));
finish();
}
},2000);
}
}
package com.eczom.eczomframe.activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.widget.RadioGroup;
import com.eczom.eczomframe.R;
import com.eczom.eczomframe.fragment.CFragment;
import com.eczom.eczomframe.fragment.EFragment;
import com.eczom.eczomframe.fragment.MFragment;
import com.eczom.eczomframe.fragment.OFragment;
import com.eczom.eczomframe.fragment.ZFragment;
import butterknife.BindView;
import butterknife.ButterKnife;
public class MainActivity extends FragmentActivity {
@BindView(R.id.rg_tab)
RadioGroup rgTab;
// 各Fragment实例
private EFragment eFragment;
private CFragment cFragment;
private ZFragment zFragment;
private OFragment oFragment;
private MFragment mFragment;
// 当前Fragment缓存
private Fragment cacheFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
initFragment();
initListener();
}
private void initFragment() {
// 初始化各Fragment
eFragment = new EFragment();
cFragment = new CFragment();
zFragment = new ZFragment();
oFragment = new OFragment();
mFragment = new MFragment();
}
private void initListener() {
// 监听RadioGroup选择事件
rgTab.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
Fragment fragment = null;
switch (i) {
case R.id.rb_e:
fragment = eFragment;
break;
case R.id.rb_c:
fragment = cFragment;
break;
case R.id.rb_z:
fragment = zFragment;
break;
case R.id.rb_o:
fragment = oFragment;
break;
case R.id.rb_m:
fragment = mFragment;
break;
}
// 切换对应Fragment
switchFragment(cacheFragment, fragment);
}
});
// 默认选择E
rgTab.check(R.id.rb_e);
}
private void switchFragment(Fragment nowFragment, Fragment toFragment) {
if (nowFragment != toFragment) {
// 缓存即将切换的Fragment,以便下一次对比判断
cacheFragment = toFragment;
// 开启事物
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
// 判断即将切换的Fragment是否add过
if (!toFragment.isAdded()) {
// 初始无缓存,需判断
if (nowFragment != null) {
// 隐藏当前Fragment
ft.hide(nowFragment);
}
// 添加即将切换的Fragment,并提交事物
ft.add(R.id.fl_main, toFragment).commit();
} else {
// 初始无缓存,需判断
if (nowFragment != null) {
// 隐藏当前Fragment
ft.hide(nowFragment);
}
// 显示即将切换的Fragment,并提交事物
ft.show(toFragment).commit();
}
}
}
}
最终效果