Android绑定框架-FSS开源框架之FssBind

介绍

fss_bind是fss框架的一部分,使用它可以实现Activity或Fragment的绑定,比如layout绑定,finish方法绑定,View/OnClick绑定(类似ButterKnife),参数绑定,参数绑定到databinding变量,view绑定到intent对象等等。
gitHub地址:https://github.com/gongbox/fss

使用教程

  • 用法1:绑定布局文件(Activity,Fragmeng等)
 @BindActivity(R.layout.activity_bind_test)
 public class BindTestActivity extends BaseFssActivity {
 }

另外,BindActivity可以绑定退出按钮,如下:

 @BindActivity(value = R.layout.activity_bind_test, finishViewId = R.id.btn_finish)
 public class BindTestActivity extends BaseFssActivity {
 }

这样就可以在点击id为btn_finish的控件时直接调用finish方法,退出Activity
如果是Fragment,也可以绑定

 @BindFragment(R.layout.fragment_bind_test)
 public class BindTestFragment extends BaseFssFragment {
 }
  • 用法2:绑定视图
 public class BindTestActivity extends BaseFssActivity {
     @BindView(R.id.list_view)
     private ListView listView;  //支持绑定所有类型的视图
 }
  • 用法3:绑定点击事件
 public class BindTestActivity extends BaseFssActivity {
     @BindOnClick(R.id.btn_click)
     private void click() {
         ...
     }
     //或者
     @BindOnClick(R.id.btn_click)
     private void click(View view) {
         ...
     }
     //或者
     @BindOnClick(R.id.btn_click)
     private void click(Button button) {
         ...
     }
 }

或者可以声明写在类上

 @BindOnClick(value = R.id.btn_test, onClickMethod = "test")
 public class BindTestActivity extends BaseFssActivity {
  //方法可以无参或者有一个该控件类型或父类型的参数,如private void test(Button button){},或private void click(View view){}
  private void test(){
     ...
  }
 }

上面的写法有其他妙用,比如绑定退出按钮到finish方法上

  • 用法4:绑定路由
 //当用户点击id为btn_route的控件时,便可以直接跳转到BindDetailActivity页面(支持携带参数,这里先不介绍)
 @BindRoute(viewId = R.id.btn_route, toActivity = BindDetailActivity.class)  
 public class BindTestActivity extends BaseFssActivity {
 }
  • 用法5: 绑定参数(支持Activity或Fragmeng)
    假设A页面跳转到B页面,并且传递了一个Integer类型(或其他类型)的参数,key值为“value”,那么在B页面可以直接使用BindExtra绑定变量获取这个参数
 public class BindTestActivity extends BaseFssActivity {
     @BindExtra(value = "value")//key值与变量名相同时可以省略为@BindExtra
     private Integer value;
 }
  • 用法6:绑定databinding变量
    如果你的项目使用了databinding(数据绑定),那么你还可以这么用:
    假设A页面跳转到B页面,并且传递了一个String类型(或其他类型)的参数,key值为“value”,那么在B页面可以直接使用BindExtra绑定变量获取这个参数,并且可以将这个参数绑定到页面对应的视图中,如下所示:
    B页面的布局文件:
 <?xml version="1.0" encoding="utf-8"?>
 <layout xmlns:android="http://schemas.android.com/apk/res/android">

     <data>
         <variable
             name="value"
             type="String" />
     </data>

     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:orientation="vertical">

         <TextView
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginTop="50dp"
             android:gravity="center"
             android:text="@{value}" />

     </LinearLayout>
 </layout>

B页面的代码

 public class BindTestActivity extends BaseFssActivity {
     //BindExtra除了会将A页面传过来的参数绑定到value变量上,也会将该变量绑定到布局文件中databinding变量名value的变量中
     @BindExtra(id = BR.value) 
     private String value;
 }

如果你不需要使用value变量的话,你也可以这么写,效果同上

 @BindExtra(value = "value", id = BR.value) 
 public class BindTestActivity extends BaseFssActivity {
 }

看到这儿,如果你觉得也没多简洁的话,那我们接下来看看实际使用中的几个例子。

使用与集成

implementation 'com.github.gongbox.fss:bind:{lastversion}'
  • 一般Android项目中会有一个Activity或Fragmengt的父类,我们在父类中初始化后即可使用。如下
public abstract class BaseFssActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //获取布局
        int layoutId = FssBind.getLayoutId(this);
        //设置布局
        setContentLayout(layoutId);
        //绑定参数(只绑定BaseFssActivity及其子类的参数)
        FssBind.bind(this, BaseFssActivity.class);
        ...
    }
    
    //这样写是为了支持databinding
     protected void setContentLayout(@LayoutRes int layoutResID) {
        setContentView(layoutResID);
    }
}
public abstract class BaseFssFragment extends Fragment {

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //获取布局
        int layoutId = FssBind.getLayoutId(this);
        //根据布局填充
        return inflater.inflate(layoutId, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        //绑定参数(只绑定BaseFssFragment及其子类的参数)
        FssBind.bind(this, BaseFssFragment.class);
        ...
    }
}

如果使用databinding的话,可以在写一个databinding的父类,如下:

public abstract class BaseBindingActivity<VB extends ViewDataBinding> extends BaseActivity {

    protected VB binding;  //变量名必须为binding

    @Override
    protected void setContentLayout(int layoutResID) {
        binding = DataBindingUtil.setContentView(this, layoutResID);
    }
}
public abstract class BaseBindingFragment<VB extends ViewDataBinding> extends BaseFragment {
    protected VB binding;  //变量名必须为binding

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        binding = DataBindingUtil.inflate(inflater, FssBind.getLayoutId(this), container, false);
        return binding.getRoot();
    }
}

声明上面的父类后,我们就可以在子类中直接使用了

例子

我们先看个简单的例子

  • 例子1
    比如我们有一个详情页面,这个详情页由另一个Activity跳转过来,并且向这个详情页传递了参数(key值为“value”),详情页页面只有一个textView(id为R.id.text)以及一个返回按钮(R.id.back),详情页要求只需要显示数据并且返回就可以了就可以了,那么我们可以这么写
@BindActivity(value = R.layout.activity_detail, finishViewId = R.id.back)
public class DetailActivity extends BaseBindingActivity<ActivityDetailBinding> {
    
   //绑定intent参数,将key值为value的参数绑定达到value变量
   @BindExtra(value = "value")
   private String value;
    
    //绑定视图
   @BindView(R.id.text)
   private TextView textView;
    
   //使用的时候,注意initView方法在OnCreate方法里会自己调用,参考fss_runpriority框架
   @Override
   protected void initView(){
       textView.setText(value);
   }
}

如果使用了databinding的话,那么代码又会更加简单了,假设databinding页面中使用变量value,该变量绑定到textView的text属性上:

@BindActivity(value = R.layout.activity_detail, finishViewId = R.id.back)
public class DetailActivity extends BaseBindingActivity<ActivityDetailBinding> {

    @BindExtra(value = "value",  id = BR.value)
    private String value;

}

上面的代码还可以写的更简单:

@BindActivity(value = R.layout.activity_detail, finishViewId = R.id.back)
@BindExtra(value = "EXTRA_VALUE",  id = BR.value)
public class DetailActivity extends BaseBindingActivity<ActivityDetailBinding> {
}

看到没有,一行代码都没有了!!!,这就是使用fss_bind框架的简洁。
然后我们看一个比较完整的例子:

  • 例子2
//绑定layout,并且将视图中id为R.id.img_back的点击事件绑定到finish方法,如果是Fragment,注解需要改为BindFragment,并且没有finish参数
@BindActivity(value = R.layout.activity_a, finishViewId = R.id.img_back)
//绑定Route,当用户点击id为R.id.to_activity_b的view后,会跳转到ActivityB
@BindRoute(viewId = R.id.to_activity_b, toActivity = ActivityB.class)
//绑定Route,当用户点击id为R.id.to_activity_c的view后,会跳转到ActivityC,并会传递参数,参数key值为EXTRA_VALUE2,携带参数为"value":value变量值,"value2":"789","value3":[234](这里为int类型数组)
@BindRoute(viewId = R.id.to_activity_c,toActivity = ActivityC.class,
        extras = {":@value", "value2:789", "value3:(int)[234]"}
)
//绑定intent参数到databinding变量
@BindExtra(value = "EXTRA_VALUE4",  id = BR.value4)
//绑定点击事件,将id为R.id.test的view的点击事件绑定到test方法上,要求该方法没有参数或只有一个View类型的参数
@BindOnClick(value = {R.id.test}, onClickMethod = "test")
public class ActivityA extends BaseBindingActivity<ActivityABinding> {
    
    //绑定intent参数,将key值为EXTRA_VALUE的参数绑定达到value变量
    @BindExtra(value = "EXTRA_VALUE")
    private Integer value;
    
    //绑定intent参数,和上面的BindParam不同的时,除了会将变量绑定外,在使用databinding的情况下,还会将该变量值直接绑定到databinding变量
    //另外,该注解可以直接写到类上面,因为有的时候我只需要将intent传递过来的参数绑定到databinding中,而我并不关心它的值
    @BindExtra(value = "EXTRA_VALUE3",  id = BR.value3)
    private String value3;
    
    //路由参数,用于绑定路由时传递参数
    private String value2 = "123456";
    
    //绑定视图
    @BindView(value = R.id.list_view)
    private ListView listView;

    //绑定点击事件,将id为R.id.img_fun1的view的点击事件绑定到opertation方法上,注意该方法没有参数
    @BindOnClick(R.id.img_fun1)
    public void opertation() {
    }
    
    //绑定点击事件,将id为R.id.img_fun2,R.id.img_fun3的view的点击事件绑定到opertation方法上
    //注意该方法有一个参数View,该参数即为对应触发点击事件对的view
    @BindOnClick({R.id.img_fun2,R.id.img_fun3})
    public void opertation(View view) {
    }
    
    private void test(){
    }
}

想想如果不用fss_bind框架上面的代码会有多少?

例子我们先看到这儿,如果想要更详细了解怎么使用,我为大家提供了demo工程

接下来,我们总结一下fss_bind框架的特点。

  • 大量运用注解,开发更简洁,规范
  • 由于使用了反射,运行效率不高。(虽然不高,但也可以接受,除非你的应用要求特别高)

用过ButterKnife的可能知道什么是绑定视图,fss_bind可不是ButterKnife的山寨,它完全来自于笔者自己的灵感,实现方式与ButterKnife不大相同,它的功能也不仅仅是绑定视图。
我们再对比一下和butterKnife的区别

  1. fss_bind框架中BindView视图,BindOnClick方法等修饰的属性或方法可以为任意访问修饰符,而ButterKnife必须为public修饰符
  2. ButterKnife适合绑定视图(绝大多数情况),绑定资源文件,而fss_bind除了绑定视图或点击事件外还可以绑定参数,路由等等功能
  3. ButterKnife中用到的注解不能继承,而fss_bind所使用到的注解可以被继承,这在开发模板类时十分有用
  4. ButterKnife的优势是性能,因为它没有使用反射,因此效率比较高,而fss_bind是使用反射实现的,效率不及ButterKnife

笔者在实际使用fss框架开发过程中,页面代码量较以往简洁清晰了很多,以往一个几十上百行代码的页面可以优化到甚至没有一行或仅仅几行代码。

更多FSS框架:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容