Android控件设置宽高比的方法

作者:WolfXu 时间:2023-02-14 09:30:04 

0. 困扰很久的问题

Android控件的宽和高保持比例,这是从我接触Android以来,一直不断会遇到的需求。以前,要么就是在代码里直接设置宽和高,要么就是自定义控件。网上也有开源的自定义ViewGroup,可以让其子View比较方便的设置宽和高的比例。但这些实现方式,还是比较麻烦,也不够直观。直到有了DataBinding,我们可以很方便地给控件加上自定义的属性,也就可以很方便的在布局文件中设置控件的宽高比了。

1. 如何实现

通过BinderAdapter为所有View绑定下面的方法,当设置widthHeightRatio属性时,会调用下面这个方法。这个有点AOP的意思,我们针对所有的View做了处理。


public class DataBindingAdapters {
 // 根据View的高度和宽高比,设置高度
 @BindingAdapter("widthHeightRatio")
 public static void setWidthHeightRatio(final View view, final float ratio) {
   view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
     @Override
     public void onGlobalLayout() {
       int height = view.getHeight();
       if (height > 0) {
         view.getLayoutParams().width = (int) (height * ratio);
         view.invalidate();
         view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
       }
     }
   });
 }
}

我们在获取到控件的高度后,根据比例计算宽度,然后设置给控件。这里注册了OnGlobalLayoutListener,是因为控件的高度有可能还没计算完成。在获取到高度之后,移除监听,避免多余的调用。


<ImageView
 android:layout_width="120dp"
 android:layout_height="match_parent"
 app:widthHeightRatio="@{1}"/>

然后我们就可以在布局文件中直接设置宽高比了。这个布局文件必须使用DataBinding,也就是最外层要用layout标签。属性值必须加上@{},不然是按普通属性处理的,不会调用我们的方法,编译时会因为找不到属性报错。当然,这个属性只能根据高度计算宽度,如果要根据宽度计算高度,可以用同样的方式再加一个属性。

2. 原理简析

其实在编译后的layout文件中是没有我们加的属性的(编译后的layout文件在build/intermediates/data-binding-layout-out下面可以看到)。真正设置这个属性,还是在Java代码中直接调用了我们绑定的方法。在DataBinding自动生成的Binding类中,可以发现有类似下面这样的调用。


DataBindingAdapters.setWidthHeightRatio(this.mboundView0, cardWidthHeightRatio);


这里只是做一个简单的解释,至于在什么时机会触发这行代码,敬请期待我后续的文章。

3. BinderAdapter的其他妙用

ImageView自动加载网络图片


@BindingAdapter({"android:src", "error"})
public static void setImageUrl(ImageView view, String url, @DrawableRes int errorImage) {
 if (!TextUtils.isEmpty(url)) {
   // 封装好的图片加载工具
   ImageManager.from(view.getContext()).displayImage(view, url, errorImage);
 } else {
   view.setImageResource(errorImage);
 }
}

直接在布局文件中设置要加载的图片的url,和加载失败时显示的默认图。

来源:https://www.jianshu.com/p/4709299ce76c

标签:android,控件,宽,高
0
投稿

猜你喜欢

  • android 获取视频,图片缩略图的具体实现

    2023-07-28 00:20:39
  • c#实现数据同步的方法(使用文件监控对象filesystemwatcher)

    2021-11-27 03:03:46
  • IDEA2020如何打开Run Dashboard的方法步骤

    2023-02-10 15:29:10
  • 关于AndroidStudio R文件莫名其妙缺失的快速解决方法

    2023-02-24 21:59:06
  • C#字符串内存分配与驻留池学习分享

    2022-07-02 12:11:29
  • C++智能指针读书笔记

    2022-02-24 06:51:28
  • C++异常处理入门(try和catch)

    2022-09-18 04:16:34
  • SpringCloud实现Eureka服务注册与发现

    2021-08-16 04:00:44
  • Android实现三角形气泡效果方式汇总

    2021-12-20 06:21:51
  • 详解Java中使用泛型实现快速排序算法的方法

    2022-04-28 09:47:00
  • 解析Spring Boot内嵌tomcat关于getServletContext().getRealPath获取得到临时路径的问题

    2023-08-28 07:44:11
  • java实现socket客户端连接服务端

    2021-12-02 03:52:07
  • 解决Android手机屏幕横竖屏切换

    2022-10-21 18:55:33
  • Springboot项目引入druid安装部署使用教程

    2023-07-28 01:39:25
  • Kryo框架使用方法代码示例

    2021-05-30 15:46:05
  • java求100以内的素数示例分享

    2021-06-30 21:34:39
  • Java实现循环体的过滤器的方法

    2023-11-22 09:35:33
  • Android图片无限轮播的实现代码

    2023-02-12 14:57:20
  • Android原生视频播放VideoView的使用

    2022-10-13 08:33:07
  • eclipse构建和发布maven项目的教程

    2022-01-12 21:41:00
  • asp之家 软件编程 m.aspxhome.com