diff --git a/ZBLibrary/src/main/java/zuo/biao/library/base/BaseBottomTabActivity.java b/ZBLibrary/src/main/java/zuo/biao/library/base/BaseBottomTabActivity.java index 9f2f279..16de7fd 100755 --- a/ZBLibrary/src/main/java/zuo/biao/library/base/BaseBottomTabActivity.java +++ b/ZBLibrary/src/main/java/zuo/biao/library/base/BaseBottomTabActivity.java @@ -14,6 +14,7 @@ package zuo.biao.library.base; +import zuo.biao.library.R; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentTransaction; import android.view.View; @@ -30,7 +31,7 @@ public abstract class BaseBottomTabActivity extends BaseActivity { - //UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + // UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< protected static int[] tabClickIds; @@ -38,7 +39,7 @@ public abstract class BaseBottomTabActivity extends BaseActivity { protected View[] vTabClickViews; protected View[][] vTabSelectViews; @Override - public void initView() {//必须调用 + public void initView() {// 必须调用 tabClickIds = getTabClickIds(); @@ -67,7 +68,7 @@ public void initView() {//必须调用 protected abstract void selectTab(int position); /**设置选中状态 - * @param position + * @param position */ protected void setTabSelection(int position) { if (vTabSelectViews == null) { @@ -87,57 +88,122 @@ protected void setTabSelection(int position) { /** * == true >> 每次点击相应tab都加载,调用getFragment方法重新对点击的tab对应的fragment赋值。 - * 如果不希望重载,可以重写selectFragment。 + * 如果不希望重载,可以setOnTabSelectedListener,然后在onTabSelected内重写点击tab事件。 */ protected boolean needReload = false; /** * 当前显示的tab所在位置,对应fragment所在位置 */ protected int currentPosition = 0; + /**选择并显示fragment * @param position */ public void selectFragment(int position) { - //tab,资源消耗很小<<<<<< - setTabSelection(position); - selectTab(position); - //tab,资源消耗很小>>>>>> + if (fragments == null || fragments.length != getCount()) { + if (fragments != null) { + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + for (int i = 0; i < fragments.length; i++) { + fragmentTransaction.remove(fragments[i]); + } + fragmentTransaction.commit(); + } + + fragments = new Fragment[getCount()]; + } + + Fragment fragment = fragments[position]; + String tag = TAG + "-fragment-" + position; + if (fragment == null) { + fragment = fragmentManager.findFragmentByTag(tag); + } if (currentPosition == position) { - if (needReload) { - if (fragments[position] != null && fragments[position].isAdded()) { - FragmentTransaction ft = fragmentManager.beginTransaction(); - ft.remove(fragments[position]).commit(); - fragments[position] = null; - } - } else { - if (fragments[position] != null && fragments[position].isVisible()) { - Log.w(TAG, "selectFragment currentPosition == position" + - " >> fragments[position] != null && fragments[position].isVisible()" + - " >> return; "); - return; - } + if (needReload == false && fragment != null && fragment.isVisible()) { + android.util.Log.w(TAG, "selectFragment currentPosition == position" + + " >> fragment != null && fragment.isVisible()" + + " >> return; "); + return; } } + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + if (needReload) { + fragmentTransaction.remove(fragment); + fragment = null; + } + + if (fragment == null) { + fragment = fragments[position] = getFragment(position); + } - if (fragments[position] == null) { - fragments[position] = getFragment(position); + // 用全局的fragmentTransaction因为already committed 崩溃 + for (Fragment f : fragmentManager.getFragments()) { + if (f != null) { + fragmentTransaction.hide(f); + } } - //全局的fragmentTransaction因为already committed 崩溃 - FragmentTransaction ft = fragmentManager.beginTransaction(); - ft.hide(fragments[currentPosition]); - if (fragments[position].isAdded() == false) { - ft.add(getFragmentContainerResId(), fragments[position]); + if (fragment.isAdded() == false) { + fragmentTransaction.add(R.id.flBaseTabFragmentContainer, fragment, tag); + } + FragmentTransaction ft = fragmentTransaction.show(fragment); + try { // cannot perform this action after savedInstance + ft.commit(); + } catch (Throwable e) { + e.printStackTrace(); } - ft.show(fragments[position]).commit(); this.currentPosition = position; } - //UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + protected void reload(int position) { + remove(position); + if (position == currentPosition) { + selectFragment(position); + } + } + protected void reloadAll() { + runUiThread(new Runnable() { + + @Override + public void run() { + removeAll(true); + selectFragment(currentPosition); + } + }); + } + protected void remove(int position) { + remove(position, false); + } + protected void remove(int position, boolean destroy) { + if (fragments != null && position >= 0 && position < fragments.length && fragments[position] != null) { + try { + fragmentManager.beginTransaction().remove(fragments[position]).commit(); + } catch (Exception e) { + Log.e(TAG, "remove try { fragmentManager.beginTransaction().remove(fragments[position]).commit();" + + " } catch (Exception e) {\n" + e.getMessage()); + destroy = true; + } + if (destroy) { + fragments[position].onDestroy(); + fragments[position] = null; + } + } + } + protected void removeAll() { + removeAll(false); + } + protected void removeAll(boolean destroy) { + if (fragments != null) { + for (int i = 0; i < fragments.length; i++) { + remove(i, destroy); + } + } + } + + // UI显示区(操作UI,但不存在数据获取或处理代码,也不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -148,19 +214,18 @@ public void selectFragment(int position) { - //Data数据区(存在数据获取或处理代码,但不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + // Data数据区(存在数据获取或处理代码,但不存在事件监听代码)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< protected Fragment[] fragments; @Override - public void initData() {//必须调用 + public void initData() {// 必须调用 - //fragmentActivity子界面初始化<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + // fragmentActivity子界面初始化<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - fragments = new Fragment[getCount()]; selectFragment(currentPosition); - //fragmentActivity子界面初始化>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // fragmentActivity子界面初始化>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> } @@ -194,7 +259,7 @@ public int getCount() { return tabClickIds == null ? 0 :tabClickIds.length; } - //Data数据区(存在数据获取或处理代码,但不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Data数据区(存在数据获取或处理代码,但不存在事件监听代码)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -205,10 +270,10 @@ public int getCount() { - //Event事件区(只要存在事件监听代码就是)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + // Event事件区(只要存在事件监听代码就是)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @Override - public void initEvent() {//必须调用 + public void initEvent() {// 必须调用 for (int i = 0; i < vTabClickViews.length; i++) { final int which = i; @@ -222,26 +287,23 @@ public void onClick(View v) { } } - //生命周期、onActivityResult<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - - - //生命周期、onActivityResult>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - - - //Event事件区(只要存在事件监听代码就是)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // 系统自带监听方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + // 类相关监听<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + // 类相关监听>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // 系统自带监听方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Event事件区(只要存在事件监听代码就是)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - //内部类,尽量少用<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + // 内部类,尽量少用<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - //内部类,尽量少用>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // 内部类,尽量少用>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> } \ No newline at end of file diff --git a/ZBLibrary/src/main/java/zuo/biao/library/base/BaseFragment.java b/ZBLibrary/src/main/java/zuo/biao/library/base/BaseFragment.java index 148176f..91906ce 100755 --- a/ZBLibrary/src/main/java/zuo/biao/library/base/BaseFragment.java +++ b/ZBLibrary/src/main/java/zuo/biao/library/base/BaseFragment.java @@ -42,6 +42,8 @@ public abstract class BaseFragment extends Fragment implements FragmentPresenter { private static final String TAG = "BaseFragment"; + public static final String ARGUMENT_POSITION = "ARGUMENT_POSITION"; + /** * 添加该Fragment的Activity * @warn 不能在子类中创建 @@ -79,6 +81,12 @@ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, this.inflater = inflater; this.container = container; + if (view != null) { + if (container == null || container.indexOfChild(view) < 0) { + container = (ViewGroup) view.getParent(); + } + container.removeView(view); + } return view; } @@ -109,6 +117,23 @@ public void setContentView(View v, ViewGroup.LayoutParams params) { } + /** + * 该Fragment在Activity添加的所有Fragment中的位置,通过ARGUMENT_POSITION设置 + * @must 只使用getPosition方法来获取position,保证position正确 + */ + private int position = -1; + /**获取该Fragment在Activity添加的所有Fragment中的位置 + */ + public int getPosition() { + if (position < 0) { + argument = getArguments(); + if (argument != null) { + position = argument.getInt(ARGUMENT_POSITION, position); + } + } + return position; + } + /** * 可用于 打开activity与fragment,fragment与fragment之间的通讯(传值)等 */ @@ -118,9 +143,11 @@ public void setContentView(View v, ViewGroup.LayoutParams params) { */ protected Intent intent = null; + /**通过id查找并获取控件,使用时不需要强转 + * @warn 调用前必须调用setContentView * @param id - * @return + * @return */ @SuppressWarnings("unchecked") public V findView(int id) { @@ -136,23 +163,6 @@ public V findView(int id, OnClickListener l) { v.setOnClickListener(l); return v; } - /**通过id查找并获取控件,使用时不需要强转 - * @warn 调用前必须调用setContentView - * @param id - * @return - */ - public V findViewById(int id) { - return findView(id); - } - /**通过id查找并获取控件,并setOnClickListener - * @param id - * @param l - * @return - */ - public V findViewById(int id, OnClickListener l) { - return findView(id, l); - } - public Intent getIntent() { return context.getIntent(); @@ -180,7 +190,7 @@ public final Handler runThread(String name, Runnable runnable) { Log.w(TAG, "runThread isAlive() == false >> return null;"); return null; } - return context.runThread(name + hashCode(), runnable);//name, runnable);同一Activity出现多个同名Fragment可能会出错 + return context.runThread(name + getPosition(), runnable);//name, runnable);同一Activity出现多个同名Fragment可能会出错 } //运行线程>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> diff --git a/ZBLibrary/src/main/java/zuo/biao/library/base/BaseTabActivity.java b/ZBLibrary/src/main/java/zuo/biao/library/base/BaseTabActivity.java index 72ebdcf..4cddcb9 100755 --- a/ZBLibrary/src/main/java/zuo/biao/library/base/BaseTabActivity.java +++ b/ZBLibrary/src/main/java/zuo/biao/library/base/BaseTabActivity.java @@ -189,34 +189,59 @@ public void select(int position) { * @param position */ public void selectFragment(int position) { - if (currentPosition == position) { - if (needReload) { - if (fragments[position] != null && fragments[position].isAdded()) { - FragmentTransaction ft = fragmentManager.beginTransaction(); - ft.remove(fragments[position]).commit(); - fragments[position] = null; - } - } else { - if (fragments[position] != null && fragments[position].isVisible()) { - Log.w(TAG, "selectFragment currentPosition == position" + - " >> fragments[position] != null && fragments[position].isVisible()" + - " >> return; "); - return; + if (fragments == null || fragments.length != getCount()) { + if (fragments != null) { + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + for (int i = 0; i < fragments.length; i++) { + fragmentTransaction.remove(fragments[i]); } + fragmentTransaction.commit(); } + + fragments = new Fragment[getCount()]; + } + + Fragment fragment = fragments[position]; + String tag = TAG + "-fragment-" + position; + if (fragment == null) { + fragment = fragmentManager.findFragmentByTag(tag); } - if (fragments[position] == null) { - fragments[position] = getFragment(position); + if (currentPosition == position) { + if (needReload == false && fragment != null && fragment.isVisible()) { + android.util.Log.w(TAG, "selectFragment currentPosition == position" + + " >> fragment != null && fragment.isVisible()" + + " >> return; "); + return; + } } - //全局的fragmentTransaction因为already committed 崩溃 - FragmentTransaction ft = fragmentManager.beginTransaction(); - ft.hide(fragments[currentPosition]); - if (fragments[position].isAdded() == false) { - ft.add(R.id.flBaseTabFragmentContainer, fragments[position]); + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + if (needReload) { + fragmentTransaction.remove(fragment); + fragment = null; + } + + if (fragment == null) { + fragment = fragments[position] = getFragment(position); + } + + // 用全局的fragmentTransaction因为already committed 崩溃 + for (Fragment f : fragmentManager.getFragments()) { + if (f != null) { + fragmentTransaction.hide(f); + } + } + + if (fragment.isAdded() == false) { + fragmentTransaction.add(R.id.flBaseTabFragmentContainer, fragment, tag); + } + FragmentTransaction ft = fragmentTransaction.show(fragment); + try { // cannot perform this action after savedInstance + ft.commit(); + } catch (Throwable e) { + e.printStackTrace(); } - ft.show(fragments[position]).commit(); this.currentPosition = position; } diff --git a/ZBLibrary/src/main/java/zuo/biao/library/base/BaseTabFragment.java b/ZBLibrary/src/main/java/zuo/biao/library/base/BaseTabFragment.java index 6902510..d025b48 100755 --- a/ZBLibrary/src/main/java/zuo/biao/library/base/BaseTabFragment.java +++ b/ZBLibrary/src/main/java/zuo/biao/library/base/BaseTabFragment.java @@ -185,34 +185,59 @@ public void select(int position) { * @param position */ public void selectFragment(int position) { - if (currentPosition == position) { - if (needReload) { - if (fragments[position] != null && fragments[position].isAdded()) { - FragmentTransaction ft = fragmentManager.beginTransaction(); - ft.remove(fragments[position]).commit(); - fragments[position] = null; - } - } else { - if (fragments[position] != null && fragments[position].isVisible()) { - Log.w(TAG, "selectFragment currentPosition == position" + - " >> fragments[position] != null && fragments[position].isVisible()" + - " >> return; "); - return; + if (fragments == null || fragments.length != getCount()) { + if (fragments != null) { + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + for (int i = 0; i < fragments.length; i++) { + fragmentTransaction.remove(fragments[i]); } + fragmentTransaction.commit(); } + + fragments = new Fragment[getCount()]; + } + + Fragment fragment = fragments[position]; + String tag = TAG + "-fragment-" + position; + if (fragment == null) { + fragment = fragmentManager.findFragmentByTag(tag); } - if (fragments[position] == null) { - fragments[position] = getFragment(position); + if (currentPosition == position) { + if (needReload == false && fragment != null && fragment.isVisible()) { + android.util.Log.w(TAG, "selectFragment currentPosition == position" + + " >> fragment != null && fragment.isVisible()" + + " >> return; "); + return; + } } - //全局的fragmentTransaction因为already committed 崩溃 - FragmentTransaction ft = fragmentManager.beginTransaction(); - ft.hide(fragments[currentPosition]); - if (fragments[position].isAdded() == false) { - ft.add(R.id.flBaseTabFragmentContainer, fragments[position]); + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + if (needReload) { + fragmentTransaction.remove(fragment); + fragment = null; + } + + if (fragment == null) { + fragment = fragments[position] = getFragment(position); + } + + // 用全局的fragmentTransaction因为already committed 崩溃 + for (Fragment f : fragmentManager.getFragments()) { + if (f != null) { + fragmentTransaction.hide(f); + } + } + + if (fragment.isAdded() == false) { + fragmentTransaction.add(R.id.flBaseTabFragmentContainer, fragment, tag); + } + FragmentTransaction ft = fragmentTransaction.show(fragment); + try { // cannot perform this action after savedInstance + ft.commit(); + } catch (Throwable e) { + e.printStackTrace(); } - ft.show(fragments[position]).commit(); this.currentPosition = position; }