我想创建数据绑定(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/