android - 在 MvxLinearLayout 中绑定(bind)到 View 的宽度

标签 android xamarin xamarin.android mvvmcross

我想创建数据绑定(bind)到 View位于 MvxLinearLayout 内的宽度在 MvxListView 中.

所以,MvxListView包含 MvxLinearLayout包含 View 的项目 需要 Width 的元素被绑定(bind)到。

我的布局代码(为清楚起见删除了不必要的 ViewGroup 容器):

MvxListView

<Mvx.MvxLinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        local:MvxBind="ItemsSource ContainerItems; ItemClick DoSomething"
        local:MvxItemTemplate="@layout/container_item_template"
        />

container_item_template

<Mvx.MvxLinearLayout
    android:layout_width="match_parent"
    android:layout_height="20dp"
    android:orientation="horizontal"
    local:MvxBind="ItemsSource MyItems"
    local:MvxItemTemplate="@layout/my_item_template" />

我的项目模板

<?xml version="1.0" encoding="utf-8"?>
<View xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:layout_width="40dp"
android:layout_height="20dp"
local:MvxBind="Width Width" />

我创建了以下自定义目标绑定(bind):

public class ViewWidthCustomBinding : MvxAndroidTargetBinding
{
    public ViewWidthCustomBinding(object target) : base(target)
    {

    }

    public override Type TargetType
    {
        get { return typeof (double); }
    }

    protected override void SetValueImpl(object target, object value)
    {
        var realTarget = target as View;
        if (target == null)
            return;
        int width = 0;

        if (value is int)
        {
            width = (int) value;
        }
        else if (value is float)
        {
            width = (int) Math.Ceiling((float) value);
        }
        else if (value is double)
        {
            width = (int)Math.Ceiling((double)value);
        }

        if (width < 1)
        {
            return;
        }
        // my LayoutParameters here are always null for some reason
        // so the layout parameters are not set to the 40dp. 20dp, as it is set above in the item template
        // Looks like this gets applied first, and then it is replaced when actual parent (root) gets assigned since all my views get the 40do width, 20dp height assigned in the item template
        realTarget.LayoutParameters = new MvxLinearLayout.LayoutParams(width, MvxLinearLayout.LayoutParams.MatchParent);

    }
}

有人有什么想法吗?

最佳答案

我认为您必须处理竞争条件绑定(bind)与布局膨胀(从 XML/布局周期创建布局参数)。

我认为您必须使用像这样的自定义 View :

public class CustomView : View
{
    private double _customWidth;

    public double CustomWidth
    {
        get { return _customWidth; }
        set
        {
            _customWidth = value;
            var param = LayoutParameters;

            if (param != null)
            {
                param.Width = (int)_customWidth;
            }
            LayoutParameters = param;
        }
    }

    public override ViewGroup.LayoutParams LayoutParameters
    {
        get { return base.LayoutParameters; }
        set
        {
            if (value != null)
            {
                value.Width = (int)_customWidth;
                base.LayoutParameters = value;
            }
        }
    }

    public CustomView(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
    {
    }

    public CustomView(Context context) : base(context)
    {
    }

    public CustomView(Context context, IAttributeSet attrs) : base(context, attrs)
    {
    }

    public CustomView(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)
    {
    }

    public CustomView(Context context, IAttributeSet attrs, int defStyleAttr, int defStyleRes) : base(context, attrs, defStyleAttr, defStyleRes)
    {
    }
}

然后绑定(bind) CustomWidth 而不是 Width

<CustomView
    android:layout_width="40dp"
    android:layout_height="20dp"
    android:background="#FF0000"
    local:MvxBind="CustomWidth MyWidth"/>

如果你想在你的绑定(bind)目标中绑定(bind)不同类型的宽度值(int、float、double),你必须将转换转移到一个转换器中,或者只是稍微改变你的绑定(bind)目标。我想你明白了。

这里的好处是,您不必知道布局参数的类型(例如 MvxLinearLayout.LayoutParams),因为您不必自己创建它。这有两个优点:

  • 您不会覆盖其他属性,例如边距、高度等。
  • 它适用于多个父布局

关于android - 在 MvxLinearLayout 中绑定(bind)到 View 的宽度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38688830/

相关文章:

c# - Xamarin 'Resource.Layout' 不包含 'Tabbar' 错误的定义

python - 如何在Web服务器中托管python脚本并通过从xamarin应用程序调用API来访问它?

c# - Xamarin Android 工具栏如何动态添加项目

c# - Visual Studio 无法安装 Android SDK(API 级别 19 和 21)(缺少 extra-android-support)

mono - 从 javascript 示例调用 monodroid 方法

xamarin.android - 在 MonoForAndroid 中使用 IInputFilter

android - 如何在android中刷新imageview

android - com.huawei.agconnect 插件未找到

Android App Play 商店重定向

android - 有关 Firebase 应用索引的某些查询