Android数据绑定 - 如何从dimens.xml获取维度

时间:2016-01-16 21:55:56

标签: android data-binding

我想根据我在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>

3 个答案:

答案 0 :(得分:29)

此处的问题不是维度,而是android:layout_marginBottom。任何LayoutParams属性都没有内置支持。这是为了移除脚枪#34;许多人可能会用来将变量绑定到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

答案 1 :(得分:0)

几乎相同的解决方案,但使用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边距编写类似的方法。

答案 2 :(得分:0)

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

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
    }
}