当前位置:   article > 正文

Jetpack架构组件_5.BindingAdapter

Jetpack架构组件_5.BindingAdapter

1.BindingAdapter介绍

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

  1. public class TextViewBindingAdapter {
  2. private static final String TAG = "TextViewBindingAdapters";
  3. public static final int INTEGER = 1;
  4. public static final int SIGNED = 3;
  5. public static final int DECIMAL = 5;
  6. public TextViewBindingAdapter() {
  7. }
  8. @BindingAdapter({"android:text"})
  9. public static void setText(TextView view, CharSequence text) {
  10. CharSequence oldText = view.getText();
  11. if (text != oldText && (text != null || oldText.length() != 0)) {
  12. if (text instanceof Spanned) {
  13. if (text.equals(oldText)) {
  14. return;
  15. }
  16. } else if (!haveContentsChanged(text, oldText)) {
  17. return;
  18. }
  19. view.setText(text);
  20. }
  21. }

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

  1. /**
  2. * 自定义BindingAdapters
  3. * Powered by jzman.
  4. * Created on 2018/12/6 0006.
  5. */
  6. public class TextViewAdapter {
  7. @BindingAdapter("android:text")
  8. public static void setText(TextView view, CharSequence text) {
  9. //省略特殊处理...
  10. String txt = text.toString().toLowerCase();
  11. view.setText(txt);
  12. }
  13. }

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

  2. 实现步骤

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

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

  1. dataBinding {
  2. enabled = true
  3. }

 step2.修改activity_main.xml布局文件

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <layout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools">
  5. <data>
  6. <variable
  7. name="imageUrl"
  8. type="String" />
  9. </data>
  10. <androidx.constraintlayout.widget.ConstraintLayout
  11. android:id="@+id/main"
  12. android:layout_width="match_parent"
  13. android:layout_height="match_parent"
  14. tools:context=".MainActivity">
  15. <ImageView
  16. app:imageUrl="@{imageUrl}"
  17. android:layout_width="wrap_content"
  18. android:layout_height="wrap_content"
  19. app:layout_constraintBottom_toBottomOf="parent"
  20. app:layout_constraintEnd_toEndOf="parent"
  21. app:layout_constraintStart_toStartOf="parent"
  22. app:layout_constraintTop_toTopOf="parent" />
  23. </androidx.constraintlayout.widget.ConstraintLayout>
  24. </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()中的属性名称和前面布局文件中定义的变量名称一致。

  1. package com.gaoting.imageviewbindingadapter;
  2. import android.widget.ImageView;
  3. import androidx.databinding.BindingAdapter;
  4. import com.squareup.picasso.Picasso;
  5. public class ImageViewBindingAdapter {
  6. @BindingAdapter("imageUrl")
  7. public static void setImage(ImageView imageview,String imageUrl){
  8. Picasso.get().load(imageUrl).into(imageview);
  9. }
  10. }

step5.修改MainActivity。

  1. package com.gaoting.imageviewbindingadapter;
  2. import android.os.Bundle;
  3. import androidx.activity.EdgeToEdge;
  4. import androidx.appcompat.app.AppCompatActivity;
  5. import androidx.core.graphics.Insets;
  6. import androidx.core.view.ViewCompat;
  7. import androidx.core.view.WindowInsetsCompat;
  8. import androidx.databinding.DataBindingUtil;
  9. import com.gaoting.imageviewbindingadapter.databinding.ActivityMainBinding;
  10. public class MainActivity extends AppCompatActivity {
  11. @Override
  12. protected void onCreate(Bundle savedInstanceState) {
  13. super.onCreate(savedInstanceState);
  14. ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
  15. String imageUrl = "https://gd-hbimg.huaban.com/5688b1ee9db26fde1819506c07dbacf8dda05f488ecbe-J3hfQ8_fw658";
  16. activityMainBinding.setImageUrl(imageUrl);
  17. }
  18. }

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

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

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools">
  4. <uses-permission android:name="android.permission.INTERNET"/>
  5. <application
  6. android:allowBackup="true"
  7. android:dataExtractionRules="@xml/data_extraction_rules"
  8. android:fullBackupContent="@xml/backup_rules"
  9. android:icon="@mipmap/ic_launcher"
  10. android:label="@string/app_name"
  11. android:roundIcon="@mipmap/ic_launcher_round"
  12. android:supportsRtl="true"
  13. android:theme="@style/Theme.ImageViewBindingAdapter"
  14. tools:targetApi="31">
  15. <activity
  16. android:name=".MainActivity"
  17. android:exported="true">
  18. <intent-filter>
  19. <action android:name="android.intent.action.MAIN" />
  20. <category android:name="android.intent.category.LAUNCHER" />
  21. </intent-filter>
  22. </activity>
  23. </application>
  24. </manifest>

step7.调试观看效果。

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

3. BindingAdapter多参数重载

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

  1. package com.gaoting.imageviewbindingadapter;
  2. import android.graphics.drawable.Drawable;
  3. import android.widget.ImageView;
  4. import androidx.databinding.BindingAdapter;
  5. import com.squareup.picasso.Picasso;
  6. public class ImageViewBindingAdapter {
  7. @BindingAdapter("imageUrl")
  8. public static void setImage(ImageView imageview,String imageUrl){
  9. Picasso.get().load(imageUrl).into(imageview);
  10. }
  11. @BindingAdapter(value={"imageUrl","localDrawable"})
  12. public static void setImage(ImageView imageview, String imageUrl, Drawable localDrawable){
  13. Picasso.get().load(imageUrl).error(localDrawable).into(imageview);
  14. }
  15. }

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

 

        在布局文件中修改如下:

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

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <layout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools">
  5. <data>
  6. <variable
  7. name="imageUrl"
  8. type="String" />
  9. </data>
  10. <androidx.constraintlayout.widget.ConstraintLayout
  11. android:id="@+id/main"
  12. android:layout_width="match_parent"
  13. android:layout_height="match_parent"
  14. tools:context=".MainActivity">
  15. <ImageView
  16. app:imageUrl="@{imageUrl}"
  17. app:localDrawable="@{@drawable/error}"
  18. android:layout_width="wrap_content"
  19. android:layout_height="wrap_content"
  20. app:layout_constraintBottom_toBottomOf="parent"
  21. app:layout_constraintEnd_toEndOf="parent"
  22. app:layout_constraintStart_toStartOf="parent"
  23. app:layout_constraintTop_toTopOf="parent" />
  24. </androidx.constraintlayout.widget.ConstraintLayout>
  25. </layout>

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

        

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/678142
推荐阅读
相关标签
  

闽ICP备14008679号