上一篇写了封装一个BaseActivity,这一期我们开始写一个BaseFragment。废话就不多说了结合上一篇看吧!
http://blog.csdn.net/xx244488877/article/details/65937778
引言:Fragment刚出来的时候,我们天真的认为它一定是一个骑着白马的王子!到最后才知道它只不过是一个捡到一匹白马的乞丐,因为它的使用让人感觉非常糟糕!
1、Fragment的产生与介绍
Android运行在各种各样的设备中,有小屏幕的手机,超大屏的平板甚至电视。针对屏幕尺寸的差距,很多情况下,都是先针对手机开发一套app,然后拷贝一份,修改布局以适应什么超级大屏的。难道无法做到一个app可以同时适应手机和平板吗?答案是,当然有,那就是Fragment.Fragment出现的初衷就是为了解决这样的问题。
你可以把Fragment当成Activity一个界面的一部分,甚至Activity的界面由完全不同的Fragment组成,更帅气的是Fragment有自己的声明周期和接收、处理用户的事件,这样就不必要在一个Activity里面写一堆事件、控件的代码了。更为重要的是,你可以动态的添加、替换、移除某个Fragment。
2、Fragment的生命周期
Fragment必须是依存于Activity而存在的,因此Activity的生命周期会直接影响到Fragment的生命周期。官网这张图很好的说明了俩者的关系:
onAttach(Activity); //当Activity与Fragment发生关联时调用
onCreateView(LayoutInflater,ViewGroup,Bundle); //创建该Fragment的视图
onActivityCreate(bundle); //当Activity的onCreate();方法返回时调用
onDestoryView(); //与onCreateView相对应,当改Fragment被移除时调用
onDetach(); //与onAttach()相对应,当Fragment与Activity的关联被取消时调用
注意:除了onCreateView,其他的所有方法如果你重写了,必须调用父类对于该方法的实现。
不得不说Fragment真心很难用但是没办法,我们不得不用!Fragment的坑、坑、坑 坑了我们无数次!看下Square公司的这篇文章吧,Square:从今天开始抛弃Fragment吧!
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0605/2996.html
3.开始写一个BaseFragment吧!
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public abstract class BaseFragment extends Fragment {
protected BaseActivity mActivity;
protected abstract int setView();
protected abstract void init(View view);
protected abstract void initData(Bundle savedInstanceState);
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mActivity = (BaseActivity) activity;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(setView(), container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
init(view);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initData(savedInstanceState);
}
@Override
public void onStart() {
super.onStart();
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onPause() {
super.onPause();
}
@Override
public void onStop() {
super.onStop();
}
@Override
public void onDestroyView() {
super.onDestroyView();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onDetach() {
super.onDetach();
}
}
使用的时候是这样的,很简洁!!
import android.os.Bundle;
import android.view.View;
import net.lililearn.baseproject.R;
import net.lililearn.baseproject.base.BaseFragment;
public class HomeFragment extends BaseFragment {
@Override
protected int setView() {
return R.layout.fragment_home;
}
@Override
protected void init(View view) {
}
@Override
protected void initData(Bundle savedInstanceState) {
}
}
关于Fragment的管理我们还是使用一个FragmenManager来管理
这里引入大神的http://www.jianshu.com/p/a58b375b6b98?1487381730192
虽然写得不错 但是感觉封装太重了!
上面的文章说到了Fragment的难以驾驭,所以我们需要开始考虑如何去控制Fragment。
刚开始我也考虑抽象出一个FragmentManager,但是Fragment与Activity相辅相成所以我们把Fragment管理全加入到BaseActivity吧!
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.KeyEvent;
import net.lililearn.baseproject.R;
import net.lililearn.baseproject.utils.ActivityStackManager;
import net.lililearn.baseproject.utils.ScreenManager;
import java.util.ArrayList;
public abstract class BaseActivity extends AppCompatActivity {
private static final String TAG = "BaseActivity";
/**
* 是否沉浸状态栏
**/
private boolean isStatusBar = true;
/**
* 是否允许全屏
**/
private boolean isFullScreen = true;
/**
* 是否禁止旋转屏幕
**/
private boolean isScreenRoate = false;
/**
* context
**/
protected Context ctx;
/**
* 是否输出日志信息
**/
private boolean isDebug;
private final int container = R.id.container;
/**
* 初始化界面
**/
protected abstract void initView();
/**
* 初始化数据
*/
protected abstract void initData();
/**
* 绑定事件
*/
protected abstract void setEvent();
private ScreenManager screenManager;
private ArrayList<BaseFragment> fragments;// back fragment list.
private BaseFragment fragment;// current fragment.
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "--->onCreate()");
initView();
initData();
setEvent();
ctx = this;
ActivityStackManager.getInstance().pushActivity(this);
screenManager = ScreenManager.getInstance();
screenManager.setStatusBar(isStatusBar, this);
// screenManager.setScreenRoate(isScreenRoate, this);
screenManager.setFullScreen(isFullScreen, this);
}
public ArrayList<BaseFragment> getFragments() {
return fragments;
}
/**
* replace the current fragment.
*
* @param fragment the new fragment to shown.
* @param addToBackStack if it can back.
*/
public void addContent(BaseFragment fragment, boolean addToBackStack) {
initFragments();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(container, fragment);
if (addToBackStack) {
ft.addToBackStack(null);
} else {
removePrevious();
}
ft.commitAllowingStateLoss();
getSupportFragmentManager().executePendingTransactions();
fragments.add(fragment);
setFragment();
}
// use replace method to show fragment.
public void replaceContent(BaseFragment fragment, boolean addToBackStack) {
initFragments();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(container, fragment);
if (addToBackStack) {
ft.addToBackStack(null);
} else {
removePrevious();
}
ft.commitAllowingStateLoss();
getSupportFragmentManager().executePendingTransactions();
fragments.add(fragment);
setFragment();
}
public void backTopFragment() {
if (fragments != null && fragments.size() > 1) {
removeContent();
backTopFragment();
}
}
/**
* set current fragment.
*/
private void setFragment() {
if (fragments != null && fragments.size() > 0) {
fragment = fragments.get(fragments.size() - 1);
} else {
fragment = null;
}
}
/**
* get the current fragment.
*
* @return current fragment
*/
public BaseFragment getFirstFragment() {
return fragment;
}
/**
* get amount of fragment.
*
* @return amount of fragment
*/
public int getFragmentNum() {
return fragments != null ? fragments.size() : 0;
}
/**
* clear fragment list
*/
protected void clearFragments() {
if (fragments != null) {
fragments.clear();
}
}
/**
* remove previous fragment
*/
private void removePrevious() {
if (fragments != null && fragments.size() > 0) {
fragments.remove(fragments.size() - 1);
}
}
/**
* init fragment list.
*/
private void initFragments() {
if (fragments == null) {
fragments = new ArrayList<>();
}
}
/**
* remove current fragment and back to front fragment.
*/
public void removeContent() {
removePrevious();
setFragment();
getSupportFragmentManager().popBackStackImmediate();
}
/**
* remove all fragment from back stack.
*/
protected void removeAllStackFragment() {
clearFragments();
setFragment();
getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
/**
* 跳转Activity
* skip Another Activity
*
* @param activity
* @param cls
*/
public static void skipAnotherActivity(Activity activity,
Class<? extends Activity> cls) {
Intent intent = new Intent(activity, cls);
activity.startActivity(intent);
activity.finish();
}
/**
* 退出应用
* called while exit app.
*/
public void exitLogic() {
ActivityStackManager.getInstance().popAllActivity();//remove all activity.
removeAllStackFragment();
System.exit(0);//system exit.
}
/**
* [是否设置沉浸状态栏]
*
* @param statusBar
*/
public void setStatusBar(boolean statusBar) {
isStatusBar = statusBar;
}
/**
* [是否设置全屏]
*
* @param fullScreen
*/
public void setFullScreen(boolean fullScreen) {
isFullScreen = fullScreen;
}
/**
* [是否设置旋转屏幕]
*
* @param screenRoate
*/
public void setScreenRoate(boolean screenRoate) {
isScreenRoate = screenRoate;
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG, "--->onStart()");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "--->onResume()");
}
@Override
protected void onRestart() {
super.onRestart();
Log.i(TAG, "--->onRestart()");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "--->onPause()");
}
@Override
protected void onStop() {
super.onStop();
Log.i(TAG, "--->onStop()");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "--->onDestroy()");
ActivityStackManager.getInstance().popActivity(this);
}
//返回键返回事件
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (KeyEvent.KEYCODE_BACK == keyCode) {
if (getSupportFragmentManager().getBackStackEntryCount() == 1) {
finish();
return true;
}
}
return super.onKeyDown(keyCode, event);
}
}
最后贴上一张运行成功的图
终于做完了!代码会传到我的GitHub上!代码中的还有一些Bug 我也会后面慢慢修改
Github:https://github.com/liliLearn/BaseProject