Fragment切替機能の迅速な実現
28340 ワード
1.はじめにの1つのappトップページは通常 ViewPager、例えば微信、利点はジェスチャー操作がもっと便利で、公式はFragmentPagerAdapterを提供して私たちがデータのロードを実現するのに便利です(Fragmentは怠惰なロードの方式を使って、資源を浪費しないようにします)、劣勢はあなたの最初のFragmentの中ですでにViewPagerを使用して、2つの層が一緒に事件が衝突することができます.しかも操作も友好的ではありません. FragmentManager、例えばトップバーは、ViewPagerの組み合わせFragmentを使用する問題に対して、FragmentManagerを使用してFragmentの表示と非表示を制御し、怠惰なロードの問題を考慮する必要はありませんが、スライドはサポートされません.
よく使われる機能である以上、自然に分離し、次回の重複作業を避けるために、本稿では主にこの機能の実現を紹介する.
2.最初の案最初のスキームは、ActivityのベースクラスMultiFragmentActivityを定義し、ベースクラスでFragmentを切り替えるロジックを実現し、その機能を実現しようとするActivityがベースクラスを継承すれば切替機能を実現できる.MultiFragmentActivity.JAvaソースコード、この実装はもっと簡単に使用できますが、問題があります.プロジェクト全体で同じベースクラスを実現して類似または同じ機能を達成することができます.もちろん、MultiFragmentActivityをプロジェクトのベースクラスから継承し、MultiFragmentActivityを継承することができますが、この機能をLibraryに置くことができます.後で使いやすくなると、継承方式を採用できないという問題に直面します. 継承を少なくし、組合せを多用することによる問題は結合性が高く、機能を分離するのに不便であるため、組合せの方法で再設計し、ヘルプクラスFragmentHelperを定義することにした.ActivityはFragmentHelperを持ってFragmentの切り替えを完了することができ、エージェントの切り替えロジックはFragmentHelperによって処理される.
3.インタフェースの定義まずFragmentOperatorインタフェースを定義し、このインタフェースFragmentHelper接続を介してActivity を保持する
4.コアメソッド tagをタグとしてfragmentを追加し、 の重複作成を回避する.
5.ActivityにFragmentを表示する Activityで使用する場合はshowFragmentメソッドを呼び出すだけで
6.最適化 Activityが回収すると、前回の状態 が記録される.
7.使用
8.ソースコード
Activity + Fragment
の形式で展示され、Fragmentの表示と非表示を制御するには基本的に2つの実現方法がある.2.最初の案
3.インタフェースの定義
interface FragmentOperator {
/**
* fragment id
*
* @return id
*/
int getFragmentContainerId();
/**
* fragment
*
* @param showItem fragment pos
* @return fragment
*/
Fragment makeFragment(int showItem);
/**
* ,
*
* @return FragmentTransaction
*/
void beginTransaction(FragmentTransaction transaction);
/**
*
*
* @param selectImage item
*/
void syncSelectState(int selectImage);
/**
*
*
* @param showItem item
* @return false
*/
boolean whenShowSameFragment(int showItem);
/**
*
*
* @param showItem item
* @return false
*/
boolean whenShowNotSameFragment(int showItem);
}
//
public static abstract class SimpleFragmentOperator implements FragmentOperator {
@Override
public boolean whenShowNotSameFragment(int showItem) {
return true;
}
@Override
public boolean whenShowSameFragment(int showItem) {
return false;
}
@Override
public void syncSelectState(int selectImage) {
}
@Override
public void beginTransaction(FragmentTransaction transaction) {
}
}
4.コアメソッド
private static final String FRAGMENT_ATG = "FragmentHelper";
private static final String ITEM_HIDE = "mHideItem";
private static final String ITEM_SHOW = "mShowItem";
private FragmentOperator operator;
private Fragment mCurrentFragment;
private FragmentManager mFragmentManager;
private int mShowItem, mHideItem;
private int mExactlyItem = 0;
/**
* fragment, fragment
*
* @param hideItem fragment
* @param showItem fragment
* @param isOnCreate OnCreate , false
*/
private void performSelectItem(int hideItem, int showItem, boolean isOnCreate) {
// tag
String currentTag = getFragmentTag(hideItem);
// fragment
FragmentTransaction transaction = mFragmentManager.beginTransaction();
operator.beginTransaction(transaction);
// , , ,
if (mFragmentManager.getFragments() == null) {
mShowItem = showItem;
mExactlyItem = showItem;
mCurrentFragment = operator.makeFragment(showItem);
transaction.add(operator.getFragmentContainerId(), mCurrentFragment, getFragmentTag(showItem))
.show(mCurrentFragment);
} else {
// , , fragment ,
if (isOnCreate && mFragmentManager.getFragments() != null) {
for (Fragment fragment : mFragmentManager.getFragments()) {
transaction.hide(fragment);
}
} else {
// ,
Fragment lastFragment = mFragmentManager.findFragmentByTag(currentTag);
if (lastFragment != null) {
transaction.hide(lastFragment);
}
}
// tag
String toTag = getFragmentTag(showItem);
// find Fragment
mCurrentFragment = mFragmentManager.findFragmentByTag(toTag);
if (mCurrentFragment != null) {
//
transaction.show(mCurrentFragment);
} else {
// fragment
mCurrentFragment = operator.makeFragment(showItem);
if (mCurrentFragment != null) {
transaction.add(operator.getFragmentContainerId(), mCurrentFragment, toTag);
}
}
}
//
operator.syncSelectState(showItem);
// fragment item
mHideItem = hideItem;
mShowItem = showItem;
transaction.commitAllowingStateLoss();
}
5.ActivityにFragmentを表示する
/**
* fragment
*
* @param showItem item
*/
public void showFragment(int showItem) {
showFragment(showItem, false);
}
/**
* fragment
*
* @param showItem item
* @param isOnCreate
*/
private void showFragment(int showItem, boolean isOnCreate) {
if (showItem == mShowItem) {
if (operator.whenShowSameFragment(showItem)) {
performSelectItem(mExactlyItem, showItem, isOnCreate);
mExactlyItem = showItem;
}
} else {
performSelectItem(mExactlyItem, showItem, isOnCreate);
mExactlyItem = showItem;
}
}
6.最適化
public void restoreFragmentHelper(Bundle save) {
if (save != null) {
mHideItem = save.getInt(ITEM_HIDE, 0);
mShowItem = save.getInt(ITEM_SHOW, 0);
}
performSelectItem(mHideItem, mShowItem, true);
}
public void onSaveInstanceState(Bundle outState) {
outState.putInt(ITEM_HIDE, mHideItem);
outState.putInt(ITEM_SHOW, mShowItem);
}
7.使用
public class HomePageActivity extends BaseReaperActivity {
private FragmentHelper fragmentHelper;
private FragmentHelper.SimpleFragmentOperator operator = new FragmentHelper.SimpleFragmentOperator() {
@Override
public int getFragmentContainerId() {
return R.id.home_container;
}
@Override
public Fragment makeFragment(int showItem) {
Fragment fragment = null;
switch (showItem) {
case 0:
fragment = HomeVideoFunFragment.newInst();
break;
case 1:
fragment = HomeFunnyFragment.newInst();
break;
case 2:
fragment = HomeBeautyFragment.newInst();
break;
case 3:
fragment = HomeMineFragment.newInst();
break;
}
return fragment;
}
@Override
public void beginTransaction(FragmentTransaction transaction) {
super.beginTransaction(transaction);
Logger.e("beginTransaction");
}
@Override
public void syncSelectState(int selectImage) {
for (int i = 0; i < mBotTabsTv.size(); i++) {
mBotTabsTv.get(i).setSelected(selectImage == i);
}
}
@Override
public boolean whenShowNotSameFragment(int showItem) {
JCVideoPlayer.releaseAllVideos();
return super.whenShowNotSameFragment(showItem);
}
};
@Override
public void onInitViews(View view, Bundle saveData) {
super.onInitViews(view, saveData);
fragmentHelper = new FragmentHelper(getSupportFragmentManager(), operator);
fragmentHelper.showFragment(2);
}
@OnClick({R.id.home_recommend, R.id.home_album, R.id.home_search, R.id.home_mine})
public void click(View v) {
int tag = Integer.parseInt(v.getTag().toString());
fragmentHelper.showFragment(tag);
}
@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
fragmentHelper.onSaveInstanceState(outState);
}
@Override
public void onInitViews(View view, Bundle saveData) {
super.onInitViews(view, saveData);
fragmentHelper = new FragmentHelper(getSupportFragmentManager(), operator);
fragmentHelper.showFragment(2);
}
}
8.ソースコード
/**
* Project : CommonLib
* Package : com.march.lib.core.common
* CreateAt : 2016/11/5
* Describe : Fragment
*
* @author chendong
*/
public class FragmentHelper {
interface FragmentOperator {
/**
* fragment id
*
* @return id
*/
int getFragmentContainerId();
/**
* fragment
*
* @param showItem fragment pos
* @return fragment
*/
Fragment makeFragment(int showItem);
/**
* ,
*
* @return FragmentTransaction
*/
void beginTransaction(FragmentTransaction transaction);
/**
*
*
* @param selectImage item
*/
void syncSelectState(int selectImage);
/**
*
*
* @param showItem item
* @return false
*/
boolean whenShowSameFragment(int showItem);
/**
*
*
* @param showItem item
* @return false
*/
boolean whenShowNotSameFragment(int showItem);
}
public static abstract class SimpleFragmentOperator implements FragmentOperator {
@Override
public boolean whenShowNotSameFragment(int showItem) {
return true;
}
@Override
public boolean whenShowSameFragment(int showItem) {
return false;
}
@Override
public void syncSelectState(int selectImage) {
}
@Override
public void beginTransaction(FragmentTransaction transaction) {
}
}
private static final String FRAGMENT_ATG = "FragmentHelper";
private static final String ITEM_HIDE = "mHideItem";
private static final String ITEM_SHOW = "mShowItem";
private FragmentOperator operator;
private Fragment mCurrentFragment;
private FragmentManager mFragmentManager;
private int mShowItem, mHideItem;
private int mExactlyItem = 0;
public void restoreFragmentHelper(Bundle save) {
if (save != null) {
mHideItem = save.getInt(ITEM_HIDE, 0);
mShowItem = save.getInt(ITEM_SHOW, 0);
}
performSelectItem(mHideItem, mShowItem, true);
}
public void onSaveInstanceState(Bundle outState) {
outState.putInt(ITEM_HIDE, mHideItem);
outState.putInt(ITEM_SHOW, mShowItem);
}
public FragmentHelper(FragmentManager mFragmentManager, FragmentOperator operator) {
this.mFragmentManager = mFragmentManager;
this.mFragmentManager = mFragmentManager;
this.operator = operator;
}
/**
* fragment
*
* @param showItem item
*/
public void showFragment(int showItem) {
showFragment(showItem, false);
}
/**
* fragment,
*
* @param showItem item
* @param isOnCreate
*/
private void showFragment(int showItem, boolean isOnCreate) {
if (showItem == mShowItem) {
if (operator.whenShowSameFragment(showItem)) {
performSelectItem(mExactlyItem, showItem, isOnCreate);
mExactlyItem = showItem;
}
} else {
performSelectItem(mExactlyItem, showItem, isOnCreate);
mExactlyItem = showItem;
}
}
/**
* fragment'
*
* @return fragment
*/
public Fragment getCurrentFragment() {
return mCurrentFragment;
}
/**
* fragment, fragment
*
* @param hideItem fragment
* @param showItem fragment
* @param isOnCreate OnCreate , false
*/
private void performSelectItem(int hideItem, int showItem, boolean isOnCreate) {
// tag
String currentTag = getFragmentTag(hideItem);
// fragment
FragmentTransaction transaction = mFragmentManager.beginTransaction();
operator.beginTransaction(transaction);
// , , ,
if (mFragmentManager.getFragments() == null) {
mShowItem = showItem;
mExactlyItem = showItem;
mCurrentFragment = operator.makeFragment(showItem);
transaction.add(operator.getFragmentContainerId(), mCurrentFragment, getFragmentTag(showItem))
.show(mCurrentFragment);
} else {
// , , fragment ,
if (isOnCreate && mFragmentManager.getFragments() != null) {
for (Fragment fragment : mFragmentManager.getFragments()) {
transaction.hide(fragment);
}
} else {
// ,
Fragment lastFragment = mFragmentManager.findFragmentByTag(currentTag);
if (lastFragment != null) {
transaction.hide(lastFragment);
}
}
// tag
String toTag = getFragmentTag(showItem);
// find Fragment
mCurrentFragment = mFragmentManager.findFragmentByTag(toTag);
if (mCurrentFragment != null) {
//
transaction.show(mCurrentFragment);
} else {
// fragment
mCurrentFragment = operator.makeFragment(showItem);
if (mCurrentFragment != null) {
transaction.add(operator.getFragmentContainerId(), mCurrentFragment, toTag);
}
}
}
//
operator.syncSelectState(showItem);
// fragment item
mHideItem = hideItem;
mShowItem = showItem;
transaction.commitAllowingStateLoss();
}
private String getFragmentTag(int item) {
return FRAGMENT_ATG + item;
}
}