您的位置:首页 > 其它

编写基类BaseFragment

2017-03-26 01:34 281 查看
上一篇写了封装一个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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Fragment