序言:
需要做一个游戏社区App。
一、采用多模块Activity+多Fragment架构
多模块Activity+多Fragment架构:
即一个模块用一个Activity,比如
1、登录注册流程使用:
LoginActivity + 登录Fragment + 注册Fragment + 填写信息Fragment + 忘记密码Fragment
优点:速度快,相比单Activity+多Fragment,相对简单,更易维护。
关于Fragment在GitHub上Start最多的是Fragmentation库。所以使用Fragmentation来打造多模块Activity+多Fragment。
先看一下Fragmentation的使用:
首先在gradle中引入相关的依赖
//gradle中引入Fragment依赖
api 'me.yokeyword:fragmentation:1.2.7'
api 'me.yokeyword:fragmentation-swipeback:1.2.7'
然后封装BaseDelegate
自定义BaseDelegate继承Fragmentation提供的SwipeBackFragment。
将 BaseDelegate改为抽象类,在具体业务中定义具体的页面Fragment时就继承这个类,实现它的抽象方法,传入布局,绑定视图。
public abstract class BaseDelegate extends SwipeBackFragment{ //SwipeBackFragment为Fragmentation库的基础类
public abstract setLayout();// 需要实现的设置layout的抽象方法
public abstract onBindView(@Nullable Bundle savedInstanceState, View rootView);// 需要实现的绑定完界面之后的操作方法
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState){
View rootView = null;
if (setLayout() instanceof Integer){
rootView = inflater.inflate((Integer)setLayout(), container, false);
}else if(setLayout() instanceof View){
rootView = (View)setLayout();
}else{
throw new ClassCastException("type must be int or view");
}
onBindView(@Nullable savedInstanceState, View rootView);
}
//返回Activity实例
public final ProxyActivity getProxyActivity(){
return (ProxyActivity)_mActivity;
}}
最好
再使用PermissionCheckerDelegat继承BaseDelegate,PermissionCheckerDelegat中做权限申请的操作。
public abstract class PermissionCheckerDelegate extends BaseDelegate {
/**
* 在这里做 动态权限的申请
* */
}
再使用LatteDelegate 继承PermissionCheckerDelegat,在LatteDelegate中存放通用的方法
public abstract class LatteDelegate extends PermissionCheckerDelegate {
@SuppressWarnings("unchecked")
public <T extends LatteDelegate> T getParentDelegate() { //获取父类Fragment
return (T) getParentFragment();
}
}
然后封装ProxyActivity
自定义ProxyActivity继承自Fragmentation提供的SupportActivity
同样也是抽象类,用来绑定自定义的Fragement到界面上
public abstract class ProxyActivity extends SupportActivity { //SupportActivity 为 Fragmentation 的基础类(并不是v4包的Support类)
public abstract LatteDelegate setRootDelegate(); // 需要实现的设置Fragment的方法
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initContainer(savedInstanceState);
}
private void initContainer(@Nullable Bundle savedInstanceState){
final FrameLayout container=new FrameLayout(this);
container.setId(R.id.delegate_container); //id要在res/vlues定义一个资源文件ids,再定义一个id值
setContentView(container);
if(savedInstanceState==null){
loadRootFragment(R.id.delegate_container,setRootDelegate()); //框架提供的绑定Fragment到Framelayout的方法
}
}
@Override
protected void onDestroy() { //释放一些资源
super.onDestroy();
System.gc();
System.runFinalization();
}
}
最后定义具体的ExampleDelegate继承自LatteDelegate
public class ExampleDelegate extends LatteDelegate {
@Override
public Object setLayout() { //设置layout
return R.layout.delegate_helloworld;
}
@Override
public void onBindView(@Nullable Bundle savedInstanceState, View rootView) { //绑定完界面之后的操作方法
}
}
把定义的ExampleDelegate嵌入唯一的Activity实例当中
public class MainActivity extends ProxyActivity{
@override
public LatteDelegate setRootDelegate(){
return new ExampleDelegate();
}}
HelloWorld显示完成。
二、ButterKnife
ButterKnife是一个专注于Android系统的View注入框架,以前总是要写很多findViewById来找到View对象,有了ButterKnife可以很轻松的省去这些步骤。
ButterKnife的优势:
1、可以进行View绑定和Click事件处理功能,简化代码,提升开发效率
2、代码清晰,可读性强
使用了ButterKnife后,绑定控件可以不再使用findViewById,直接使用
@BindView(R2.id.hello)
TextView tvHello=null;
也可以一次绑定多个控件
@BindViews({ R2.id.button1,R2.id.button2,R2.id.button3 })
List<Button> buttonList ;
ButterKnife的其他的注解
//绑定注解
@BindView—->绑定一个view;
@BindViews —-> 绑定多个view;
@BindArray—-> 绑定string里面array数组;
@BindBitmap—->绑定图片资源为Bitmap;
@BindBool —->绑定boolean值
@BindColor —->绑定color;
@BindDimen —->绑定Dimen;
@BindDrawable —-> 绑定Drawable;
@BindFloat —->绑定float
@BindInt —->绑定int
@BindString —->绑定一个String id为一个String变量;
//事件注解
@OnClick—->点击事件
@OnCheckedChanged —->选中,取消选中
@OnEditorAction —->软键盘的功能键
@OnFocusChange —->焦点改变
@OnItemClick item—->被点击(注意:如果item里面有Button等这些 有点击的控件事件的,需要设置这些控件属性focusable为false)
@OnItemLongClick item—->长按(返回真可以拦截onItemClick)
@OnItemSelected —->item被选择事件
@OnLongClick —->长按事件
@OnPageChange —->页面改变事件
@OnTextChanged —->EditText里面的文本变化事件
@OnTouch —->触摸事件
@Optional —->选择性注入,如果当前对象不存在,就会抛出一个异常,为了压制这个异常,可以在变量或者方法上加入一下注解,让注入变成选择性的,如果目标View存在,则注入, 不存在,则什么事情都不做
ButterKnife的配置
首先需要在build.gradle中引入相关的依赖
api 'com.jakewharton:butterknife:9.0.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:9.0.0'
和添加
apply plugin: 'com.jakewharton.butterknife'
并且还需要在工程的build.gradle中(最外层的build.gradle)
dependencies {
......
classpath 'com.jakewharton:butterknife-gradle-plugin:9.0.0'
......
}
最后还需要回到BaseDelegate中,对其进行修改,在onDestroyView对其进行解绑
public abstract class BaseDelegate extends SwipeBackFragment { //SwipeBackFragment为Fragmentation库的基础类
@SuppressWarnings("SpellCheckingInspection")
private Unbinder mUnbinder = null;
public abstract Object setLayout(); //需要实现的设置layout的抽象方法
public abstract void onBindView(@Nullable Bundle savedInstanceState, View rootView); //需要实现的绑定完界面之后的操作方法
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView=null;
if(setLayout() instanceof Integer){
rootView=inflater.inflate((Integer) setLayout(),container,false);
}else if(setLayout() instanceof View){
rootView= (View) setLayout();
}
if(rootView!=null){
mUnbinder= ButterKnife.bind(this,rootView); //返回一个Unbinder值(用于进行解绑)
onBindView(savedInstanceState,rootView);
}
return rootView; //返回唯一的view实例
}
//返回Activity
public final ProxyActivity getProxyActivity(){
return (ProxyActivity) _mActivity;
}
//Activity销毁的时候,需要先进行解绑
@Override
public void onDestroyView() {
super.onDestroyView();
if(mUnbinder != null){
mUnbinder.unbind();
}
}
}
然后可以回到ExampleDelegate,对HelloWorld进行修改。
public class ExampleDelegate extends LatteDelegate {
@BindView(R2.id.hello)
TextView tvHello=null;
@Override
public Object setLayout() {
return R.layout.delegate_helloworld;
}
@Override
public void onBindView(@Nullable Bundle savedInstanceState, View rootView) {
tvHello.setText("GoodBye");
}
}