转载请注明出处:http://blog.csdn.net/q649381130?viewmode=contents(漆可的博客)
封装作为面向对象的三大特性之一,在我们平时的coding过程用的那是非常的多的。大多数时候,我们可以根据封装情况评判代码的质量水平。
本文主要讲解的是fragment的封装。大体上,在项目的初期,我们都会在基类中把一些常用的东西封装起来,以供子类方便的调用。这用做的好处是显而易见的:
在fragment中,我们可以通过getActivity()方法获取到当前依附的activity实例。但是如果在使用的时候直接获取有时候可能会报空指针,那么我们可以在fragment生命周期的onAttach(Context context)方法中获取到并提升为全局变量。
/**
* 贴附的activity
*/
protected FragmentActivity mActivity;
@Override
public void onAttach(Context context)
{
super.onAttach(context);
mActivity = getActivity();
}
通常,我们需要在fragment的onCreateView方法中做一些初始化的事情,比如加载布局文件,findview,网络加载数据,初始化数据等,将这些事情都写在一个方法中显得onCreateView非常的庞大,我们可以分成几个方法抽离出来,这样代码既美观又方便阅读:
@Override
@Nullable
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState)
{
mRootView = inflater.inflate(setLayoutResouceId(), container, false);
initData(getArguments());
initView();
mIsPrepare = true;
onLazyLoad();
setListener();
return mRootView;
}
以上代码我们根据功能进行以下封装,注意方法调用顺序不可调换:
封装的属性代码注释已经写的很清楚了:
/**
* 贴附的activity
*/
protected FragmentActivity mActivity;
/**
* 根view
*/
protected View mRootView;
/**
* 是否对用户可见
*/
protected boolean mIsVisible;
/**
* 是否加载完成
* 当执行完oncreatview,View的初始化方法后方法后即为true
*/
protected boolean mIsPrepare;
以下封装的三个方法用于子类的实现:
/**
* 初始化数据
* @author 漆可
* @date 2016-5-26 下午3:57:48
* @param arguments 接收到的从其他地方传递过来的参数
*/
protected void initData(Bundle arguments)
{
}
/**
* 初始化View
* @author 漆可
* @date 2016-5-26 下午3:58:49
*/
protected void initView()
{
}
/**
* 设置监听事件
* @author 漆可
* @date 2016-5-26 下午3:59:36
*/
protected void setListener()
{
}
setLayoutResouceId()是一个抽象方法,子类必须实现,用于获取布局文件的资源id,加载到fragment中,并在onCreatview方法中用mRootView保存其引用
/**
* 设置根布局资源id
* @author 漆可
* @date 2016-5-26 下午3:57:09
* @return
*/
protected abstract int setLayoutResouceId();
是不是很羡慕activity的findViewById()方法,在我们封装的basefragment中,也有自己的findViewById()方法,而且比activity的更加强大,因为它可以直接转化成我们相对应的view,而不需要强制转化。有了它,我们的fragment子类就可以直接使用了。
@SuppressWarnings("unchecked")
protected T findViewById(int id)
{
if (mRootView == null)
{
return null;
}
return (T) mRootView.findViewById(id);
}
何为懒加载,就是view没有与用户交互的话并不会加载,但是他的加载顺序又非常快。该方法主要在viewpager嵌套fragment中使用得多。我们都知道,viewpager可以提前加载左右指定数目(当然这个数目可以通过setOffscreenPageLimit(int limit)设置)的fragment,如果我们使用懒加载,就只会做些view的创建等操作,避免提前执行其他页面的网络请求。
一下代码中,setUserVisibleHint(boolean isVisibleToUser)表示是否与用户可交互,他在onCreatview方法前执行,当isVisibleToUser为true时表示对用户可见,在这里我们执行自定义的onVisibleToUser()
方法,在onVisibleToUser()中,我们进行判断,当mIsPrepare为true且与用户可交互时执行我们的onLazyLoad()方法进行懒加载。
@Override
public void setUserVisibleHint(boolean isVisibleToUser)
{
super.setUserVisibleHint(isVisibleToUser);
this.mIsVisible = isVisibleToUser;
if (isVisibleToUser)
{
onVisibleToUser();
}
}
/**
* 用户可见时执行的操作
* @author 漆可
* @date 2016-5-26 下午4:09:39
*/
protected void onVisibleToUser()
{
if (mIsPrepare && mIsVisible)
{
onLazyLoad();
}
}
好了,整个basefragment的封装就做好了,下面是完整代码,由于代码量不多,本篇博客就不上传完整demo了。
public abstract class BaseFragment extends Fragment
{
/**
* 贴附的activity
*/
protected FragmentActivity mActivity;
/**
* 根view
*/
protected View mRootView;
/**
* 是否对用户可见
*/
protected boolean mIsVisible;
/**
* 是否加载完成
* 当执行完oncreatview,View的初始化方法后方法后即为true
*/
protected boolean mIsPrepare;
@Override
public void onAttach(Context context)
{
super.onAttach(context);
mActivity = getActivity();
}
@Override
@Nullable
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState)
{
mRootView = inflater.inflate(setLayoutResouceId(), container, false);
initData(getArguments());
initView();
mIsPrepare = true;
onLazyLoad();
setListener();
return mRootView;
}
/**
* 初始化数据
* @author 漆可
* @date 2016-5-26 下午3:57:48
* @param arguments 接收到的从其他地方传递过来的参数
*/
protected void initData(Bundle arguments)
{
}
/**
* 初始化View
* @author 漆可
* @date 2016-5-26 下午3:58:49
*/
protected void initView()
{
}
/**
* 设置监听事件
* @author 漆可
* @date 2016-5-26 下午3:59:36
*/
protected void setListener()
{
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser)
{
super.setUserVisibleHint(isVisibleToUser);
this.mIsVisible = isVisibleToUser;
if (isVisibleToUser)
{
onVisibleToUser();
}
}
/**
* 用户可见时执行的操作
* @author 漆可
* @date 2016-5-26 下午4:09:39
*/
protected void onVisibleToUser()
{
if (mIsPrepare && mIsVisible)
{
onLazyLoad();
}
}
/**
* 懒加载,仅当用户可见切view初始化结束后才会执行
* @author 漆可
* @date 2016-5-26 下午4:10:20
*/
protected void onLazyLoad()
{
}
@SuppressWarnings("unchecked")
protected T findViewById(int id)
{
if (mRootView == null)
{
return null;
}
return (T) mRootView.findViewById(id);
}
/**
* 设置根布局资源id
* @author 漆可
* @date 2016-5-26 下午3:57:09
* @return
*/
protected abstract int setLayoutResouceId();
}
敬请期待我的下一篇博客:
5、利用自定义注解精简代码