【问题标题】:Android databinding - How to get dimensions from dimens.xmlAndroid 数据绑定 - 如何从 dimens.xml 获取维度
【发布时间】:2016-04-22 07:35:56
【问题描述】:

我想根据我在dimens.xml中创建的尺寸设置边距它自己的尺寸工作正常,它只是数据绑定在以下情况下找不到它:

<TextView
           android:id="@+id/title_main"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_below="@+id/disableButton"
*************
        android:layout_marginBottom="@{@bool/showAds ? 
@dimen/frontpage_margin_ads: @dimen/frontpage_margin_noads}"
*************        
android:gravity="center_horizontal"
        android:text="@string/app_name"
        android:textColor="@android:color/holo_orange_dark"
        android:contentDescription="@string/app_name"
        android:textSize="64sp"
        android:textStyle="bold" />

它确实找到了它,但它说marginbottom 不能采用float 类型。我怎样才能解决这个问题?我尝试将两个维度都转换为 int,但随后它抱怨它不能转换为 int。

我的尺寸 xml 文件如下所示:

    <resources>

    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
    <dimen name="bigText">44sp</dimen>
    <dimen name="littleText">44sp</dimen>
    <dimen name="mediumText">40sp</dimen>
        <dimen name="smallText">24sp</dimen>
    <dimen name="fab_margin">16dp</dimen>
    <dimen name="frontpage_margin_noads">0dp</dimen>
    <dimen name="frontpage_margin_ads">13dp</dimen>


</resources>

【问题讨论】:

    标签: android data-binding


    【解决方案1】:

    这里的问题不在于尺寸,而在于android:layout_marginBottom。没有对任何 LayoutParams 属性的内置支持。这样做是为了消除许多人可能用来将变量绑定到 LayoutParams 的“脚枪”,并且可能会尝试使用数据绑定来以这种方式为其位置设置动画。

    数据绑定非常适合在您的示例中使用,您可以轻松添加自己的。应该是这样的。

    @BindingAdapter("android:layout_marginBottom")
    public static void setBottomMargin(View view, float bottomMargin) {
        MarginLayoutParams layoutParams = (MarginLayoutParams) view.getLayoutParams();
        layoutParams.setMargins(layoutParams.leftMargin, layoutParams.topMargin,
            layoutParams.rightMargin, Math.round(bottomMargin));
        view.setLayoutParams(layoutParams);
    }
    

    当然,您还可以添加左侧、顶部、右侧、开始和结束 BindingAdapters

    【讨论】:

    • 我应该在哪里编写这段代码?我指定 marginBottom 的所有布局都将使用此方法还是仅数据绑定或仅此特定布局?
    • 您可以在启用了数据绑定的项目中的任何(公共)类上添加它。它将用于所有数据绑定边距属性。
    • 问题很简单:margin不是视图的属性,而是视图的布局实例。您可以使用其他视图属性(如填充)执行您尝试的操作,但边距属性具有前缀 layout_ 是有充分理由的。
    • @GeorgeMount,我发现在 AS 2.2 preview 6 中,我需要将 bottomMargin 的类型设置为 float 而不是 int,否则会出现编译错误,提示 Cannot find the setter for属性“android:layout_marginBottom”,参数类型浮动在 android.widget.TextView
    • 不,这不是错误。 @dimen 资源是浮点数,而 @dimenOffset@dimenSize 是整数。这分别对应于 Resources.getDimension()、getDimensionPixelSize() 和 getDimensionPixelOffset()。使用浮点数总是安全的,因为整数会自动转换为浮点数,但浮点数不会自动转换为整数。
    【解决方案2】:

    几乎相同的解决方案,但使用 Kotlin:

    在 BindingAdapters.kt 文件中添加:

    @BindingAdapter("layoutMarginBottom")
    fun setLayoutMarginBottom(view: View, dimen: Float) {
        view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
            bottomMargin = dimen.toInt()
        }
    }
    

    在布局中的使用:

    <LinearLayout
        app:layoutMarginBottom="@{viewModel.type == Type.SMALL ? @dimen/margin_small : @dimen/margin_large}"
    

    您可以为topstartend 边距编写类似的方法。

    【讨论】:

      【解决方案3】:

      其他例子对我不起作用,所以我自己写了。这可以添加到一个新的空白 Kotlin 文件中。这些函数不需要在一个类中。确保您在文件顶部有自己的 package 声明。

      import android.view.View
      import android.view.ViewGroup
      import androidx.databinding.BindingAdapter
      
      @BindingAdapter("android:layout_marginBottom")
      fun setLayoutMarginBottom(view: View, dimen: Int) {
          (view.layoutParams as ViewGroup.MarginLayoutParams).let {
              it.bottomMargin = dimen
              view.layoutParams = it
          }
      }
      
      @BindingAdapter("android:layout_marginTop")
      fun setLayoutMarginTop(view: View, dimen: Int) {
          (view.layoutParams as ViewGroup.MarginLayoutParams).let {
              it.topMargin = dimen
              view.layoutParams = it
          }
      }
      
      @BindingAdapter("android:layout_marginStart")
      fun setLayoutMarginStart(view: View, dimen: Int) {
          (view.layoutParams as ViewGroup.MarginLayoutParams).let {
              it.marginStart = dimen
              view.layoutParams = it
          }
      }
      
      @BindingAdapter("android:layout_marginEnd")
      fun setLayoutMarginEnd(view: View, dimen: Int) {
          (view.layoutParams as ViewGroup.MarginLayoutParams).let {
              it.marginEnd = dimen
              view.layoutParams = it
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2015-12-17
        • 2023-04-07
        • 1970-01-01
        • 1970-01-01
        • 2013-10-11
        • 2021-05-04
        • 1970-01-01
        • 2023-03-29
        • 1970-01-01
        相关资源
        最近更新 更多