赞
踩
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 类中。
开启了后DataBinding才会自动生成Adapter类,比如TextViewAdapter。
- dataBinding {
- enabled = true
- }
- <?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>
添加方法,点击File>Project Structrue>Dependencies。点All Dependencies下面的+,选择1.Library Dependency。
弹出Add Library Dependency窗口,在窗口中的Step1下面的文本框中输入picasso。点击搜索。这里可能花费的时间比较久, 最后搜索到了选中Square 公司开源的Android 端的图片加载和缓存框架com.squareup.picasso。
注意@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);
- }
- }
- 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);
- }
- }
添加一行:<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";允许后可以在手机上看到这个效果,溜溜溜!
在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>
测试时把原来可以访问的图片改名,这样就会不能访问,那就应该显示出错时要显示的图片。运行效果如下,符合预期:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。