我想创建数据绑定到View
的宽度,该宽度位于MvxLinearLayout
内的MvxListView
内。
因此,MvxListView
包含MvxLinearLayout
项,其中包含View
需要Width
绑定的项目。
我的布局代码(为清晰起见,删除了不必要的ViewGroup
个容器):
<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"
/>
<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" />
我创建了以下自定义目标绑定:
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);
}
}
有人有什么想法吗?
答案 0 :(得分:4)
我认为你必须处理竞争条件绑定与布局通胀(从XML /布局周期创建布局参数)。
我认为您必须使用自定义视图,如:
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)
{
}
}
然后绑定CustomWidth
而不是Width
。
<CustomView
android:layout_width="40dp"
android:layout_height="20dp"
android:background="#FF0000"
local:MvxBind="CustomWidth MyWidth"/>
如果要在绑定目标中绑定不同类型的宽度值(int,float,double),则必须将转换转换为转换器或稍微更改绑定目标。我想你明白了。
这里的好处是,您不必知道布局参数的类型(例如MvxLinearLayout.LayoutParams
),因为您不必自己创建它。这有两个好处: