关于切屏时重叠问题,办法的核心是给每个fragment都设置一个tag,方法是transaction.add(R.id.content, messageFragment,"message");
这样在竖屏切横屏的时候用findFragmentByTag("message")
去拿fragment,这样fragment就不会都为空了。
if(meFragment == null){
meFragment = new MeFragment();
transaction.add(R.id.framelayout_content, meFragment);
}
这种写法在重建的时候有问题
meFragment = getFragmentManager().findFragmentByTag(tag);
然后如果null才meFragment = new MeFragment();
完整Demo
package com.example.fragmentdemo;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.TextView;
import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.graphics.Color;
/**
* 项目的主Activity,所有的Fragment都嵌入在这里。
*
* @author guolin
*/
public class MainActivity extends Activity implements OnClickListener {
/**
* 用于展示消息的Fragment
*/
private MessageFragment messageFragment;
/**
* 用于展示联系人的Fragment
*/
private ContactsFragment contactsFragment;
/**
* 用于展示动态的Fragment
*/
private NewsFragment newsFragment;
/**
* 用于展示设置的Fragment
*/
private SettingFragment settingFragment;
/**
* 消息界面布局
*/
private View messageLayout;
/**
* 联系人界面布局
*/
private View contactsLayout;
/**
* 动态界面布局
*/
private View newsLayout;
/**
* 设置界面布局
*/
private View settingLayout;
/**
* 在Tab布局上显示消息图标的控件
*/
private ImageView messageImage;
/**
* 在Tab布局上显示联系人图标的控件
*/
private ImageView contactsImage;
/**
* 在Tab布局上显示动态图标的控件
*/
private ImageView newsImage;
/**
* 在Tab布局上显示设置图标的控件
*/
private ImageView settingImage;
/**
* 在Tab布局上显示消息标题的控件
*/
private TextView messageText;
/**
* 在Tab布局上显示联系人标题的控件
*/
private TextView contactsText;
/**
* 在Tab布局上显示动态标题的控件
*/
private TextView newsText;
/**
* 在Tab布局上显示设置标题的控件
*/
private TextView settingText;
/**
* 用于对Fragment进行管理
*/
private FragmentManager fragmentManager;
/**
* 保存当前显示的是第几页
*/
private int currentPage = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("neo", "onCreate");
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
if(null != savedInstanceState){
currentPage = savedInstanceState.getInt("neo");
}
// 初始化布局元素
initViews();
fragmentManager = getFragmentManager();
//在FragmentManager里面根据Tag去找相应的fragment. 用户屏幕发生旋转,重新调用onCreate方法。否则会发生重叠
messageFragment = (MessageFragment) fragmentManager.findFragmentByTag("message");
contactsFragment = (ContactsFragment) fragmentManager.findFragmentByTag("contacts");
newsFragment = (NewsFragment) fragmentManager.findFragmentByTag("news");
settingFragment = (SettingFragment) fragmentManager.findFragmentByTag("setting");
// 第一次启动时选中第0个tab
setTabSelection(currentPage);
}
/**
* 在这里获取到每个需要用到的控件的实例,并给它们设置好必要的点击事件。
*/
private void initViews() {
messageLayout = findViewById(R.id.message_layout);
contactsLayout = findViewById(R.id.contacts_layout);
newsLayout = findViewById(R.id.news_layout);
settingLayout = findViewById(R.id.setting_layout);
messageImage = (ImageView) findViewById(R.id.message_image);
contactsImage = (ImageView) findViewById(R.id.contacts_image);
newsImage = (ImageView) findViewById(R.id.news_image);
settingImage = (ImageView) findViewById(R.id.setting_image);
messageText = (TextView) findViewById(R.id.message_text);
contactsText = (TextView) findViewById(R.id.contacts_text);
newsText = (TextView) findViewById(R.id.news_text);
settingText = (TextView) findViewById(R.id.setting_text);
messageLayout.setOnClickListener(this);
contactsLayout.setOnClickListener(this);
newsLayout.setOnClickListener(this);
settingLayout.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.message_layout:
// 当点击了消息tab时,选中第1个tab
setTabSelection(0);
currentPage = 0;
break;
case R.id.contacts_layout:
// 当点击了联系人tab时,选中第2个tab
setTabSelection(1);
currentPage = 1;
break;
case R.id.news_layout:
// 当点击了动态tab时,选中第3个tab
setTabSelection(2);
currentPage = 2;
break;
case R.id.setting_layout:
// 当点击了设置tab时,选中第4个tab
setTabSelection(3);
currentPage = 3;
break;
default:
break;
}
}
/**
* 根据传入的index参数来设置选中的tab页。
*
* @param index
* 每个tab页对应的下标。0表示消息,1表示联系人,2表示动态,3表示设置。
*/
private void setTabSelection(int index) {
// 每次选中之前先清楚掉上次的选中状态
clearSelection();
// 开启一个Fragment事务
FragmentTransaction transaction = fragmentManager.beginTransaction();
// 先隐藏掉所有的Fragment,以防止有多个Fragment显示在界面上的情况
hideFragments(transaction);
//Log.i("neo", "消息为空? "+messageFragment+"--联系人为空? "+contactsFragment+"-- 动态为空? "+newsFragment+"-- 设置为空? "+settingFragment);
switch (index) {
case 0:
// 当点击了消息tab时,改变控件的图片和文字颜色
messageImage.setImageResource(R.drawable.message_selected);
messageText.setTextColor(Color.WHITE);
//messageFragment = (MessageFragment) fragmentManager.findFragmentByTag("message");
if (messageFragment == null) {
// 如果MessageFragment为空,则创建一个并添加到界面上
messageFragment = new MessageFragment();
transaction.add(R.id.content, messageFragment,"message");
} else {
// 如果MessageFragment不为空,则直接将它显示出来
transaction.show(messageFragment);
}
break;
case 1:
// 当点击了联系人tab时,改变控件的图片和文字颜色
contactsImage.setImageResource(R.drawable.contacts_selected);
contactsText.setTextColor(Color.WHITE);
// contactsFragment = (ContactsFragment) fragmentManager.findFragmentByTag("contacts");
if (contactsFragment == null) {
// 如果ContactsFragment为空,则创建一个并添加到界面上
contactsFragment = new ContactsFragment();
transaction.add(R.id.content, contactsFragment,"contacts");
} else {
// 如果ContactsFragment不为空,则直接将它显示出来
transaction.show(contactsFragment);
}
break;
case 2:
// 当点击了动态tab时,改变控件的图片和文字颜色
newsImage.setImageResource(R.drawable.news_selected);
newsText.setTextColor(Color.WHITE);
// newsFragment = (NewsFragment) fragmentManager.findFragmentByTag("news");
if (newsFragment == null) {
// 如果NewsFragment为空,则创建一个并添加到界面上
newsFragment = new NewsFragment();
transaction.add(R.id.content, newsFragment,"news");
} else {
// 如果NewsFragment不为空,则直接将它显示出来
transaction.show(newsFragment);
}
break;
case 3:
default:
// 当点击了设置tab时,改变控件的图片和文字颜色
settingImage.setImageResource(R.drawable.setting_selected);
settingText.setTextColor(Color.WHITE);
// settingFragment = (SettingFragment) fragmentManager.findFragmentByTag("setting");
if (settingFragment == null) {
// 如果SettingFragment为空,则创建一个并添加到界面上
settingFragment = new SettingFragment();
transaction.add(R.id.content, settingFragment,"setting");
} else {
// 如果SettingFragment不为空,则直接将它显示出来
transaction.show(settingFragment);
}
break;
}
transaction.commit();
}
/**
* 清除掉所有的选中状态。
*/
private void clearSelection() {
messageImage.setImageResource(R.drawable.message_unselected);
messageText.setTextColor(Color.parseColor("#82858b"));
contactsImage.setImageResource(R.drawable.contacts_unselected);
contactsText.setTextColor(Color.parseColor("#82858b"));
newsImage.setImageResource(R.drawable.news_unselected);
newsText.setTextColor(Color.parseColor("#82858b"));
settingImage.setImageResource(R.drawable.setting_unselected);
settingText.setTextColor(Color.parseColor("#82858b"));
}
/**
* 将所有的Fragment都置为隐藏状态。
*
* @param transaction
* 用于对Fragment执行操作的事务
*/
private void hideFragments(FragmentTransaction transaction) {
if (messageFragment != null) {
transaction.hide(messageFragment);
}
if (contactsFragment != null) {
transaction.hide(contactsFragment);
}
if (newsFragment != null) {
transaction.hide(newsFragment);
}
if (settingFragment != null) {
transaction.hide(settingFragment);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putInt("neo",currentPage);
super.onSaveInstanceState(outState);
Log.i("neo", "onSaveInstanceState");
}
}
其他项目源码样板
AndroidFire-master
public class MainActivity extends BaseActivity {
@Bind(R.id.tab_layout)
CommonTabLayout tabLayout;
private String[] mTitles = {"首页", "美女","视频","关注"};
private int[] mIconUnselectIds = {
R.mipmap.ic_home_normal,R.mipmap.ic_girl_normal,R.mipmap.ic_video_normal,R.mipmap.ic_care_normal};
private int[] mIconSelectIds = {
R.mipmap.ic_home_selected,R.mipmap.ic_girl_selected, R.mipmap.ic_video_selected,R.mipmap.ic_care_selected};
private ArrayList<CustomTabEntity> mTabEntities = new ArrayList<>();
private NewsMainFragment newsMainFragment;
private PhotosMainFragment photosMainFragment;
private VideoMainFragment videoMainFragment;
private CareMainFragment careMainFragment;
private static int tabLayoutHeight;
/**
* 入口
* @param activity
*/
public static void startAction(Activity activity){
Intent intent = new Intent(activity, MainActivity.class);
activity.startActivity(intent);
activity.overridePendingTransition(R.anim.fade_in,
com.jaydenxiao.common.R.anim.fade_out);
}
@Override
public int getLayoutId() {
return R.layout.act_main;
}
@Override
public void initPresenter() {
}
@Override
public void initView() {
//此处填上在http://fir.im/注册账号后获得的API_TOKEN以及APP的应用ID
UpdateKey.API_TOKEN = AppConfig.API_FIRE_TOKEN;
UpdateKey.APP_ID = AppConfig.APP_FIRE_ID;
//如果你想通过Dialog来进行下载,可以如下设置
// UpdateKey.DialogOrNotification=UpdateKey.WITH_DIALOG;
UpdateFunGO.init(this);
//初始化菜单
initTab();
}
@Override
public void onCreate(Bundle savedInstanceState) {
//切换daynight模式要立即变色的页面
ChangeModeController.getInstance().init(this,R.attr.class);
super.onCreate(savedInstanceState);
//初始化frament
initFragment(savedInstanceState);
tabLayout.measure(0,0);
tabLayoutHeight=tabLayout.getMeasuredHeight();
//监听菜单显示或隐藏
mRxManager.on(AppConstant.MENU_SHOW_HIDE, new Action1<Boolean>() {
@Override
public void call(Boolean hideOrShow) {
startAnimation(hideOrShow);
}
});
}
/**
* 初始化tab
*/
private void initTab() {
for (int i = 0; i < mTitles.length; i++) {
mTabEntities.add(new TabEntity(mTitles[i], mIconSelectIds[i], mIconUnselectIds[i]));
}
tabLayout.setTabData(mTabEntities);
//点击监听
tabLayout.setOnTabSelectListener(new OnTabSelectListener() {
@Override
public void onTabSelect(int position) {
SwitchTo(position);
}
@Override
public void onTabReselect(int position) {
}
});
}
/**
* 初始化碎片
*/
private void initFragment(Bundle savedInstanceState) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
int currentTabPosition = 0;
if (savedInstanceState != null) {
newsMainFragment = (NewsMainFragment) getSupportFragmentManager().findFragmentByTag("newsMainFragment");
photosMainFragment = (PhotosMainFragment) getSupportFragmentManager().findFragmentByTag("photosMainFragment");
videoMainFragment = (VideoMainFragment) getSupportFragmentManager().findFragmentByTag("videoMainFragment");
careMainFragment = (CareMainFragment) getSupportFragmentManager().findFragmentByTag("careMainFragment");
currentTabPosition = savedInstanceState.getInt(AppConstant.HOME_CURRENT_TAB_POSITION);
} else {
newsMainFragment = new NewsMainFragment();
photosMainFragment = new PhotosMainFragment();
videoMainFragment = new VideoMainFragment();
careMainFragment = new CareMainFragment();
transaction.add(R.id.fl_body, newsMainFragment, "newsMainFragment");
transaction.add(R.id.fl_body, photosMainFragment, "photosMainFragment");
transaction.add(R.id.fl_body, videoMainFragment, "videoMainFragment");
transaction.add(R.id.fl_body, careMainFragment, "careMainFragment");
}
transaction.commit();
SwitchTo(currentTabPosition);
tabLayout.setCurrentTab(currentTabPosition);
}
/**
* 切换
*/
private void SwitchTo(int position) {
LogUtils.logd("主页菜单position" + position);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
switch (position) {
//首页
case 0:
transaction.hide(photosMainFragment);
transaction.hide(videoMainFragment);
transaction.hide(careMainFragment);
transaction.show(newsMainFragment);
transaction.commitAllowingStateLoss();
break;
//美女
case 1:
transaction.hide(newsMainFragment);
transaction.hide(videoMainFragment);
transaction.hide(careMainFragment);
transaction.show(photosMainFragment);
transaction.commitAllowingStateLoss();
break;
//视频
case 2:
transaction.hide(newsMainFragment);
transaction.hide(photosMainFragment);
transaction.hide(careMainFragment);
transaction.show(videoMainFragment);
transaction.commitAllowingStateLoss();
break;
//关注
case 3:
transaction.hide(newsMainFragment);
transaction.hide(photosMainFragment);
transaction.hide(videoMainFragment);
transaction.show(careMainFragment);
transaction.commitAllowingStateLoss();
break;
default:
break;
}
}
/**
* 菜单显示隐藏动画
* @param showOrHide
*/
private void startAnimation(boolean showOrHide){
final ViewGroup.LayoutParams layoutParams = tabLayout.getLayoutParams();
ValueAnimator valueAnimator;
ObjectAnimator alpha;
if(!showOrHide){
valueAnimator = ValueAnimator.ofInt(tabLayoutHeight, 0);
alpha = ObjectAnimator.ofFloat(tabLayout, "alpha", 1, 0);
}else{
valueAnimator = ValueAnimator.ofInt(0, tabLayoutHeight);
alpha = ObjectAnimator.ofFloat(tabLayout, "alpha", 0, 1);
}
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
layoutParams.height= (int) valueAnimator.getAnimatedValue();
tabLayout.setLayoutParams(layoutParams);
}
});
AnimatorSet animatorSet=new AnimatorSet();
animatorSet.setDuration(500);
animatorSet.playTogether(valueAnimator,alpha);
animatorSet.start();
}
/**
* 监听全屏视频时返回键
*/
@Override
public void onBackPressed() {
if (JCVideoPlayer.backPress()) {
return;
}
super.onBackPressed();
}
/**
* 监听返回键
*
* @param keyCode
* @param event
* @return
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
moveTaskToBack(false);
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//奔溃前保存位置
LogUtils.loge("onSaveInstanceState进来了1");
if (tabLayout != null) {
LogUtils.loge("onSaveInstanceState进来了2");
outState.putInt(AppConstant.HOME_CURRENT_TAB_POSITION, tabLayout.getCurrentTab());
}
}
@Override
protected void onResume() {
super.onResume();
UpdateFunGO.onResume(this);
}
@Override
protected void onStop() {
super.onStop();
UpdateFunGO.onStop(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
ChangeModeController.onDestory();
}
}
优化hideAllFragment的方式(未解决重叠)
上面两个样板都是 先hide所有的fragment,再show,这样并不好。可以标记当前的fragment,显示下一个fragment时候仅仅隐藏当前的(old)fragment,RTVCenter中轮播图的显示也是此方式。
public class MainActivity extends BaseActivity {
private LearnFragment learnFragment;
private YoungFragment youngFragment;
private JokeFragment jokeFragment;
private SuperBoonFragment superFragment;
private Fragment oldFragment;
@Bind(R.id.bottomBar)
BottomBar mBottomBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
initActionbar();
setAppAbout();
initBottom();
initFragmentContent();
}
/**
* 设置中间内容页
*/
private void initFragmentContent() {
learnFragment = new LearnFragment();
getSupportFragmentManager().beginTransaction().add(R.id.fragment_content, learnFragment).commit();
oldFragment = learnFragment;
}
/**
* 设置底部按钮
*/
private void initBottom() {
mBottomBar.setOnTabSelectListener(new OnTabSelectListener() {
@Override
public void onTabSelected(@IdRes int tabId) {
switch (tabId) {
case R.id.menu_learn: //学习
setActTitle(R.string.menu_learn_msg);
toFragment(learnFragment);
break;
case R.id.menu_joke: //开心
checkNet(1);
break;
case R.id.menu_young: //美女
checkNet(2);
break;
case R.id.menu_super: //超级福利
checkNet(3);
break;
default:
setActTitle(R.string.menu_learn_msg);
toFragment(learnFragment);
break;
}
}
});
}
/**
* 检查网络,并跳转
*/
private void checkNet(final int position) {
if (NetStatusUtil.isWifi(MainActivity.this)) {
goFragment(position);
} else {
final MaterialDialog mMaterialDialog = new MaterialDialog(this);
mMaterialDialog.setTitle("提示");
mMaterialDialog.setMessage("您当前不是WIFI状态,访问会消耗大量的流量,您确定要访问吗?");
mMaterialDialog.setPositiveButton("没事儿拼了", new View.OnClickListener() {
@Override
public void onClick(View v) {
goFragment(position);
mMaterialDialog.dismiss();
}
});
mMaterialDialog.setNegativeButton("还是不看了", new View.OnClickListener() {
@Override
public void onClick(View v) {
mMaterialDialog.dismiss();
showToast("(*^__^*) 没事去读书学习吧");
mBottomBar.selectTabWithId(R.id.menu_learn);
}
});
mMaterialDialog.show();
}
}
private void goFragment(int position) {
switch (position) {
case 1://开心
{
setActTitle(R.string.menu_joke_msg);
if (jokeFragment == null) {
jokeFragment = new JokeFragment();
}
toFragment(jokeFragment);
break;
}
case 2: //美女
{
setActTitle(R.string.menu_young_msg);
if (youngFragment == null) {
youngFragment = new YoungFragment();
}
toFragment(youngFragment);
break;
}
case 3: //超级福利
{
setActTitle(R.string.menu_super_msg);
if (superFragment == null) {
superFragment = new SuperBoonFragment();
}
toFragment(superFragment);
break;
}
default:
break;
}
}
/**
* 切换Fragment
*
* @param to 下一个Fragment页面
*/
private void toFragment(Fragment to) {
if (to == oldFragment) return;
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction().setCustomAnimations(android
.R.anim.fade_in, android.R.anim.fade_out);
if (!to.isAdded()) { // 先判断是否被add过
transaction.hide(oldFragment).add(R.id.fragment_content, to).commit(); // 隐藏当前的fragment,add下一个到Activity中
} else {
transaction.hide(oldFragment).show(to).commit(); // 隐藏当前的fragment,显示下一个
}
oldFragment = to;
}
private void setActTitle(int res) {
mActionTitle.setText(getString(res));
}
private long time = 0;
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (System.currentTimeMillis() - time <= 2000) {
finish();
} else {
time = System.currentTimeMillis();
Toast.makeText(getApplicationContext(), R.string.exit_app, Toast.LENGTH_SHORT).show();
}
return true;
}
return super.onKeyDown(keyCode, event);
}
}
参考:
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2017/0415/7830.html