Jetpack架构组件_5.BindingAdapter

1.BindingAdapter介绍

        Binding adapters 可以作为一个设置某个值的框架来使用,databinding 库可以允许指定具体的方法来进行相关值的设置,在该方法中可以做一些处理逻辑,Binding adapters 会最终给你想要的结果。Android Databinding框架中已经为我们准备了大部分控件的一些属性的BindingAdapter,就比如TextView: 

public class TextViewBindingAdapter {
    private static final String TAG = "TextViewBindingAdapters";
    public static final int INTEGER = 1;
    public static final int SIGNED = 3;
    public static final int DECIMAL = 5;

    public TextViewBindingAdapter() {
    }

    @BindingAdapter({"android:text"})
    public static void setText(TextView view, CharSequence text) {
        CharSequence oldText = view.getText();
        if (text != oldText && (text != null || oldText.length() != 0)) {
            if (text instanceof Spanned) {
                if (text.equals(oldText)) {
                    return;
                }
            } else if (!haveContentsChanged(text, oldText)) {
                return;
            }

            view.setText(text);
        }
    }

        当某些属性需要自定义处理逻辑的时候可以使用 BindingAdapter,比如我们可以使用 BindingAdapter 重新定义 TextView 的 setText 方法,让输入的英文全部转换为小写,自定义 TextViewAdapter 如下:

/**
 * 自定义BindingAdapters
 * Powered by jzman.
 * Created on 2018/12/6 0006.
 */
public class TextViewAdapter {

    @BindingAdapter("android:text")
    public static void setText(TextView view, CharSequence text) {
        //省略特殊处理...
        String txt = text.toString().toLowerCase();
        view.setText(txt);
    }
}

         此时,当我们使用 databinding 的优先使用我们自己定义的 BindingAdapter,可能会疑惑为什么能够识别呢,在编译期间 data-binding 编译器会查找带有 @BindingAdapter 注解的方法,最终会将自定义的 setter 方法生成到与之对应的 binding 类中。

  2. 实现步骤

  step1.修改app模块下的build.gradle文件    

        开启了后DataBinding才会自动生成Adapter类,比如TextViewAdapter。

    dataBinding {
        enabled = true
    }

 step2.修改activity_main.xml布局文件

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

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

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <ImageView
            app:imageUrl="@{imageUrl}"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

step3.添加Picasso依赖

        添加方法,点击File>Project Structrue>Dependencies。点All Dependencies下面的+,选择1.Library Dependency。

        弹出Add Library Dependency窗口,在窗口中的Step1下面的文本框中输入picasso。点击搜索。这里可能花费的时间比较久, 最后搜索到了选中Square 公司开源的Android 端的图片加载和缓存框架com.squareup.picasso。

 

  step4.创建ImageViewBindingAdapter类。

        注意@BindingAdapter()中的属性名称和前面布局文件中定义的变量名称一致。

package com.gaoting.imageviewbindingadapter;
import android.widget.ImageView;
import androidx.databinding.BindingAdapter;

import com.squareup.picasso.Picasso;

public class ImageViewBindingAdapter {
    @BindingAdapter("imageUrl")
    public static void setImage(ImageView imageview,String imageUrl){
        Picasso.get().load(imageUrl).into(imageview);
    }
}

step5.修改MainActivity。

package com.gaoting.imageviewbindingadapter;

import android.os.Bundle;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.databinding.DataBindingUtil;

import com.gaoting.imageviewbindingadapter.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        String imageUrl = "https://gd-hbimg.huaban.com/5688b1ee9db26fde1819506c07dbacf8dda05f488ecbe-J3hfQ8_fw658";
        activityMainBinding.setImageUrl(imageUrl);
    }
}

 step6.在AndroidMainifest.xml中添加网络权限。

        添加一行:<uses-permission android:name="android.permission.INTERNET"/>

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <uses-permission android:name="android.permission.INTERNET"/>
    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.ImageViewBindingAdapter"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

step7.调试观看效果。

        为了测试方便,我是用自己本地的一个Web服务器上的资源。手机和Web服务器在同一个局域网下的。我的资源地址是:String url = "http://192.168.1.18:8080/images/tree.jpg";允许后可以在手机上看到这个效果,溜溜溜!

3. BindingAdapter多参数重载

         在ImageViewBindingAdapter中增加一个重载方法。

package com.gaoting.imageviewbindingadapter;
import android.graphics.drawable.Drawable;
import android.widget.ImageView;
import androidx.databinding.BindingAdapter;

import com.squareup.picasso.Picasso;

public class ImageViewBindingAdapter {
    @BindingAdapter("imageUrl")
    public static void setImage(ImageView imageview,String imageUrl){
        Picasso.get().load(imageUrl).into(imageview);
    }

    @BindingAdapter(value={"imageUrl","localDrawable"})
    public static void setImage(ImageView imageview, String imageUrl, Drawable localDrawable){
        Picasso.get().load(imageUrl).error(localDrawable).into(imageview);
    }
}

        在res下的drawable下放一张本地图片如下图:error.jpg。 


  

        在布局文件中修改如下:

        app:imageUrl="@{imageUrl}"
        app:localDrawable="@{@drawable/error}"

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

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

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <ImageView
            app:imageUrl="@{imageUrl}"
            app:localDrawable="@{@drawable/error}"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

        测试时把原来可以访问的图片改名,这样就会不能访问,那就应该显示出错时要显示的图片。运行效果如下,符合预期:

        

相关推荐

  1. Jetpack架构组件_LifeCycle组件

    2024-06-06 01:02:06       25 阅读
  2. 架构的思考5--云上组织架构

    2024-06-06 01:02:06       58 阅读
  3. 架构以及架构中的组件

    2024-06-06 01:02:06       18 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-06 01:02:06       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-06 01:02:06       106 阅读
  3. 在Django里面运行非项目文件

    2024-06-06 01:02:06       87 阅读
  4. Python语言-面向对象

    2024-06-06 01:02:06       96 阅读

热门阅读

  1. ffmpeg常用命令

    2024-06-06 01:02:06       26 阅读
  2. Spark的序列化

    2024-06-06 01:02:06       27 阅读
  3. 就在刚刚,雷军又做了个10亿的公司

    2024-06-06 01:02:06       22 阅读
  4. 前端Ajax、Axios和Fetch的用法和区别笔记

    2024-06-06 01:02:06       28 阅读
  5. qt QGroupBox radiobutton

    2024-06-06 01:02:06       31 阅读
  6. 双向链表MyLinkList

    2024-06-06 01:02:06       25 阅读
  7. Unknown module(s) in QT: texttospeech

    2024-06-06 01:02:06       30 阅读
  8. Vue的过滤器是什么如何使用它

    2024-06-06 01:02:06       29 阅读
  9. Git配置SSH-Key

    2024-06-06 01:02:06       28 阅读
  10. rose 聊开源—1 你为什么需要一个开源项目

    2024-06-06 01:02:06       26 阅读