美文网首页
DataBinding--Event

DataBinding--Event

作者: 墨留痕 | 来源:发表于2017-03-27 11:00 被阅读0次

    通过DataBinding,事件的 处理变得更加简洁,不单单是支持 点击,同时也支持一些其他事件。例如:CheckBox的 onCheckedChange,TextView的onTextChanged,同时也支持借助一些表达式指定事件的处理者。

    1、普通事件

    <!--在res 文件的使用如下 ,当然你需要在 layout 布局中声明-->
    <!-- DataBinding 是可以支持泛型的 -->
    <layout>
    
        <data>
            <variable
                name="holder"
                type="com.zk.sample.module.binding.view.DataBindingFragment.DataBindingFace" />
        </data>
              <CheckBox
                    android:id="@+id/cb_event"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="5dp"
                    android:layout_marginTop="5dp"
                    android:checked="true"
                    android:onCheckedChangeListener="@{holder.onCheckedChangeListener}"
                    android:text="事件" />
      </layout>
    

    holder 也就是ViewHolder,主要是处理一些用户操作后的数据处理及相应结果的再次展示,实现如下

    //单独的事件处理
    public class DataBingHolder implements DataBindingFragment.DataBindingFace {
        public static DataBingHolder holder;
    
        private DataBingHolder() {
        }
    
        public static DataBingHolder getInstance() {
            if (holder == null) {
                synchronized (DataBingHolder.class) {
                    if (holder == null) {
                        holder = new DataBingHolder();
                    }
                }
            }
            return holder;
        }
      /**
      *     checkBox 的状态监听
      *
      */
        public CompoundButton.OnCheckedChangeListener getOnCheckedChangeListener() {
            return new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    FragmentDataBindingBinding binding = DataBindingUtil.findBinding(buttonView);
                    switch (buttonView.getId()) {
                        case R.id.cb_event:
                        //选中时显示事件列表
                            binding.llEvent.setVisibility(isChecked ? View.VISIBLE : View.GONE);
                            break;
                    }
                }
            };
        }
    }
    
    // View 中事件的调用
    //此处使用单例模式保证数据源的唯一性
     DataBingHolder holder = DataBingHolder.getInstance();
     binding.setHolder(holder);
    

    2、自定义事件

    DataBinding 支持自定义事件,可以扩展事件参数,并指定是否是必须参数

    1、声明自定义事件 必须是静态的

    public class BindUtil {
    
        private static final String TAG = "BindUtil";
    
        /**
         * requireAll 默认为true 如果不设置一个控件中xml中三个必须同时具备才可以正常编译
         */
        //    @BindingAdapter("imageUrl")//单个参数
        //    @BindingAdapter({"imageUrl", "error", "placeHolder"})//多个参数
        @BindingAdapter(value = {"imageUrl", "error", "placeHolder"}, requireAll = false)//非必须
        public static void loadImage(ImageView view, String url, Drawable error, Drawable placeHolder) {
            LogUtil.d(TAG, "load image ->url:" + url);
            DrawableTypeRequest<String> request = Glide.with(view.getContext()).load(url);
    
            if (error != null) {
                request.error(error);
            }
            if (placeHolder != null) {
                request.placeholder(placeHolder);
            }
            request.into(view);
        }
    }
    

    2、xml 文件中的使用 (当参数默认需要全部时必须要写全,负责会导致变异失败)

    <?xml version="1.0" encoding="utf-8"?>
    <layout>
    
        <data>
    
            <variable
                name="holder"
                type="com.zk.sample.module.binding.view.DataBindingFragment.DataBindingFace" />
    
          <!-- 声明图片的数据源 -->
            <variable
                name="imageUrl"
                type="String" />
    
            <variable
                name="event"
                type="com.zk.sample.module.binding.BindingEvent" />
        </data>
    
        <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/grey"
                android:orientation="vertical">
    
                <CheckBox
                    android:id="@+id/cb_event"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="5dp"
                    android:layout_marginTop="5dp"
                    android:checked="true"
                    android:onCheckedChangeListener="@{holder.onCheckedChangeListener}"
                    android:text="事件" />
    
                <LinearLayout
                    android:id="@+id/ll_event"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@color/white"
                    android:orientation="vertical">
                <!--事件处理者的指定 及自定义传参-->
                    <Button
                        style="@style/ButtonStyle"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:onClick="@{(theview)->event.getDataOnClick(theview,imageUrl)}"
                        android:text="传参事件(获取图片网址)" />
                  
                  <!--自定义事件的触发控件 通过点击触发-->
                    <Button
                        style="@style/ButtonStyle"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:onClick="@{holder.imageOnClickListener}"
                        android:text="自定义事件(加载图片)" />
    
                  <!-- 自定义事件所需参数 及结果显示-->
                    <ImageView
                        android:layout_width="match_parent"
                        android:layout_height="200dp"
                        android:scaleType="fitCenter"
                        app:error="@{@color/black}"
                        app:imageUrl="@{imageUrl}"
                        app:placeHolder="@{@color/holderColor}" />
                  
                  <!--事件的可以直接传送数据源 -->
                    <Button
                        style="@style/ButtonStyle"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:onClick="@{()->event.setParamsOnClick(userImg)}"
                        android:text="点击直接修改图片网址" />
    
                    <ImageView
                        android:layout_width="match_parent"
                        android:layout_height="200dp"
                        android:scaleType="fitCenter"
                        app:error="@{@color/black}"
                        app:imageUrl="@{userImg.url}"
                        app:placeHolder="@{@color/holderColor}" />
                </LinearLayout>
    
            </LinearLayout>
        </ScrollView>
    </layout>
    

    3、自定义事件的触发

    当自定义事件需要的参数 发生改变的时候就会产生回调触发自定义事件,如图 则会发生加载图片

    @SuppressWarnings("unused")
    public class DataBingHolder implements DataBindingFragment.DataBindingFace {
        @Override
      public View.OnClickListener getImageOnClickListener() {
          return new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                //获取视图绑定的holder ,对holder 设置参数
                  FragmentDataBindingBinding binding = DataBindingUtil.findBinding(v);
                  binding.setImageUrl(DataManager.getRandomUrl());
                //DataBinding 触发自定义事件加载图片
              }
          };
      }
    }
    

    3、事件指定

    可以通过表达式将事件的处理者进行转接,并加入自定义的参数 如 2、自定义事件中

    android:onClick="@{(theview)->event.getDataOnClick(theview,imageUrl)}"

    theview 代指当前控件 如果指定的方法需要 则必须在当前方法中声明(theview),如果方法参数不对则变异失败

    event 需要事先声明

    /**
     * 点击传参
     * url 可以为空
     */
    public void getDataOnClick(View view,String url) {
        ToastUtil.showToast(view.getContext(), "网址:" + url);
    }
    

    4、事件直接修改数据源

    由于java 传参时 传递的实际是地址值,古在 指定的数据源不发生变化时,可以直接修改数据,会自发相应的回调如

    android:onClick="@{()->event.setParamsOnClick(userImg)}"

    参数的处理,此处切记不要用new 新增对象

    /**
     * 点击切换显示的图片
     */
    public void setParamsOnClick(UserImg img) {
        String url = DataManager.getRandomUrl();
        img.setUrl(url);
        String t = url.substring(url.length() - 10, url.length());
        LogUtil.d(TAG, "原标题:" + img.title + "\n现标题:" + t);
        img.setTitle(t);
    }
    

    附上Demo

    https://github.com/zhaokai1033/LearnProject

    相关文章

      网友评论

          本文标题:DataBinding--Event

          本文链接:https://www.haomeiwen.com/subject/yualottx.html