学习From鸿洋大神的微信公众号,mark一下
开发者经常需要的就是对控件的
findViewById
,setOnClickListener
、有的用到注解的方式绑定控件,如:Butterknife
等,有的用DataBinding
(2015年IO大会介绍的一个框架),下面我要写的Base类是用最简单的findViewById
来实现的,如果你想尝试其他的方式,不妨试试,反正不会被打-_-
代码如下:
package com.song.basedemo.base;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.util.SparseArray;
import android.view.View;
/**
* Created by song on 2017/3/30.
* 继承于FragmentActivity,实现View.OnClickListener监听事件
* 用一个SparseArray 来管理控件的findView
* findView(int viewId)方法提取出来,强制转换等
* setOnclick(E view)设置监听事件
*/
public abstract class BaseActivity extends FragmentActivity implements View.OnClickListener {
//管理控件的的findView
private SparseArray mViews;
//获取布局资源文件
public abstract int getLayoutID();
//初始化控件
public abstract void initViews();
//注册监听事件
public abstract void registerListener();
//初始化数据,如:网络请求获取数据
public abstract void initData();
//控件的点击事件
public abstract void viewsClick(View view);
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mViews = new SparseArray();//初始化集合
setContentView(getLayoutID()); //设置ContentView
initViews(); //初始化控件
registerListener(); //注册监听事件
initData(); //初始化数据
}
/**
* 将控件的点击事件传递给抽象方法viewsClick,
* 让子类去实现
* @param v View
*/
@Override
public void onClick(View v) {
viewsClick(v);
}
/**
* findVeiwById
* @param viewId 控件的id
* @param 控件的类型
* @return view
*/
protected E findView(int viewId){
E view = (E) mViews.get(viewId);
if(null == view){
view = (E) findViewById(viewId);
mViews.put(viewId,view);
}
return view;
}
/**
* 给控件设置点击事件,最后传递给抽象方法viewsClick()
* @param view 需要设置点击事件的控件
* @param 控件的类型
*/
protected void setOnclick(E view){
view.setOnClickListener(this);
}
}
使用例子,继承于BaseActivity
package com.song.basedemo;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.song.basedemo.base.BaseActivity;
public class DetailActivity extends BaseActivity {
private Button btn1,btn2;
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public int getLayoutID() {
return R.layout.activity_detail;
}
@Override
public void initViews() {
btn1 = findView(R.id.btn_click1);
btn2 = findView(R.id.btn_click2);
tv = findView(R.id.tv_txt);
}
@Override
public void registerListener() {
setOnclick(btn1);
setOnclick(btn2);
}
@Override
public void initData() {
//进行网络请求
}
@Override
public void viewsClick(View view) {
switch (view.getId()){
case R.id.btn_click1:
tv.setText("btn_click1");
break;
case R.id.btn_click2:
tv.setText("btn_click2");
break;
}
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.song.basedemo.DetailActivity">
<TextView
android:id="@+id/tv_txt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
tools:text="hello" />
<Button
android:id="@+id/btn_click1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="click1" />
<Button
android:id="@+id/btn_click2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="click2" />
LinearLayout>
BaseFragment用懒加载模式 刚刚踩了一个坑-_- 在lazyLoad()方法里,我把registerListener写在if前面了,写在if后面就没有注册监听事件啦~~~,懒加载,加载不加载都需要监听滴。
/**
* 懒加载
* 如果不是第一次加载、没有初始化控件、不对用户可见就不加载
*/
protected void lazyLoad(){
registerListener();//注册监听事件
if(!isFirstLoad || !isInitView || !isVisible){
return;
}
initData();//初始化数据
isFirstLoad = false;//已经不是第一次加载
}
下面是完整的BaseFragment代码
package com.song.basedemo.base;
import android.app.Fragment;
import android.os.Bundle;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by song on 2017/3/30.
* 继承Fragment,实现View.OnClickListener监听事件
* 懒加载模式:界面对用户可见的时候加载,懒嘛~懒,是节省流量的一种方式
* 用了几个boolean值,为了判断对用户可见的时候才加载
*/
public abstract class BaseFragment extends Fragment implements View.OnClickListener {
private boolean isFirstLoad;//是否是第一次加载
private boolean isVisible;//是否对用户可见
private boolean isInitView;//是否初始化控件
protected View convertView;//显示的converView
private SparseArray mViews;//管理View的集合
public abstract int getLayoutID(); //获取布局资源文件
public abstract void initViews();//初始化控件
public abstract void registerListener();//注册监听事件
public abstract void initData();//初始化数据,如:网络请求获取数据
public abstract void viewsClick(View view);//控件的点击事件
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mViews = new SparseArray();//初始化集合
convertView = inflater.inflate(getLayoutID(),container,false);//用布局填充器填充布局
initViews();//初始化控件
isInitView = true;//已经初始化
lazyLoad();//懒加载
return convertView;
}
/**
* 懒加载
* 如果不是第一次加载、没有初始化控件、不对用户可见就不加载
*/
protected void lazyLoad(){
registerListener();//注册监听事件
if(!isFirstLoad || !isInitView || !isVisible){
return;
}
initData();//初始化数据
isFirstLoad = false;//已经不是第一次加载
}
/**
* 是否对用户可见
* @param isVisibleToUser true:表示对用户可见,反之则不可见
*/
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser){
isVisible = true;
//这里根据需求,如果不要每次对用户可见的时候就加载就不要调用lazyLoad()这个方法,根据个人需求
lazyLoad();
}else{
isVisible = false;
}
}
/**
* 将控件的点击事件传递给抽象方法viewsClick,
* 让子类去实现
* @param v View
*/
@Override
public void onClick(View v) {
viewsClick(v);
}
/**
* findVeiwById
* @param viewId 控件的id
* @param 控件的类型
* @return view
*/
protected E findView(int viewId){
if(null != convertView){
E view = (E) mViews.get(viewId);
if(null == view) {
view = (E) convertView.findViewById(viewId);
mViews.put(viewId, view);
}
return view;
}
return null;
}
/**
* 给控件设置点击事件,最后传递给抽象方法viewsClick()
* @param view 需要设置点击事件的控件
* @param 控件的类型
*/
protected void setOnclick(E view){
view.setOnClickListener(this);
}
}
使用例子,继承于BaseFragment
package com.song.basedemo;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.song.basedemo.base.BaseFragment;
/**
* Created by song on 2017/3/30.
* DetaliFragment继承BaseFragment,实现监听事件
*/
public class DetaliFragment extends BaseFragment implements View.OnClickListener {
private Button btn1,btn2;
private TextView tv;
@Override
public int getLayoutID() {
return R.layout.fragment_detail;
}
@Override
public void initViews() {
btn1 = findView(R.id.btn_click1);
btn2 = findView(R.id.btn_click2);
tv = findView(R.id.tv_txt);
}
@Override
public void registerListener() {
setOnclick(btn1);
setOnclick(btn2);
}
@Override
public void initData() {
//进行网络请求
}
@Override
public void viewsClick(View view) {
switch (view.getId()){
case R.id.btn_click1:
tv.setText("btn_click1");
break;
case R.id.btn_click2:
tv.setText("btn_click2");
break;
}
}
}
布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.song.basedemo.DetailActivity">
<TextView
android:id="@+id/tv_txt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="baseFragment" />
<Button
android:id="@+id/btn_click1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Click1" />
<Button
android:id="@+id/btn_click2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Click2" />
LinearLayout>
就先mark这两个Base类了,其他的Base举一反三嘛