有没有办法让Mvx.MvxLinearLayout尊重android:layout_weight?

时间:2013-07-29 10:13:02

标签: android xamarin.android mvvmcross

我有一个水平的项目列表,我希望平均分享可用的屏幕宽度。

以前我使用了每个项目的索引绑定和静态LinearLayout,每个项目都有相同的layout_weight。

当我使用Mvx.MvxLinearLayout和ItemsSource绑定替换静态LinearLayout,并将项目的标记移动到Itemtemplate时,MvxLinearLayout不再遵守layout_weight。

我已经尝试了各种重组项目模板的方法,并且在安排项目时似乎没有办法让这个控件服从layout_weight。

有没有办法让Mvx.MvxLinearLayout尊重android:layout_weight,或者任何替代方法可以给我一个动态的项目列表,这些项目将在给定固定维度边界的情况下平均排列?

修改

假设有3个项目的列表,其字符串属性为“Name”。

此标记按预期工作,提供3个宽度相等的文本项:

<LinearLayout
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <TextView
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        local:MvxBind="Text Items[0].Name"
        />
    <TextView
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        local:MvxBind="Text Items[1].Name"
        />
    <TextView
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        local:MvxBind="Text Items[2].Name"
        />
</LinearLayout>

此方法不起作用,布局权重未正确应用于TextViews:

<Mvx.MvxLinearLayout
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    local:MvxBind="ItemsSource Items"
    local:MvxItemTemplate="@layout/item_template" />

ItemTemplate布局文件:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:layout_weight="1"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    local:MvxBind="Text Name" />

2 个答案:

答案 0 :(得分:2)

问题是,当MvxLinearLayout与ItemTemplate一起使用时,mvvmcross会插入一个额外的视图。因此,而不是获得视图层次结构:

MvxLinearLayout - &gt; TextView的

你最终得到:

MvxLinearLayout - &gt; MvxListItemView - &gt; TextView的。

因此,应用于TextView的布局属性(尤其是权重)对于LinearLayout是不可见的。 MvxListItemView使用默认布局属性(换行内容)进行准备,并且看不到重量效果。

动作发生的位置在MvxViewGroupExtensions(例如Refill)中,其中子视图被添加到LinearLayout,而MvxAdapter中的CreateBindableView方法,其中子视图被打包在IMvxListItemView中。

解决此问题的一种方法是覆盖MvxViewGroupExtensions中的方法,并在添加视图后更新MvxListItemViews的布局属性(例如,从底层视图复制它们)。例如:

private static void Refill(this ViewGroup viewGroup, IAdapter adapter) {
    .... // rest of code
    Invalidate();
    for (int j = 0; j < viewGroup.ChildCount; j++)
    {
        var child = GetChildAt(j) as MvxListItemView;
        var param = new LinearLayout.LayoutParams(
                     0, ViewGroup.LayoutParams.WrapContent, 1.0f);
        child.LayoutParameters = param;
    }
}

答案 1 :(得分:0)

  

MvxLinearLayout尊重android:layout_weight

的任何方式

我不知道 - 但听起来你处于调试和实验的完美位置。

要调试布局问题,一个非常有用的工具是层次结构查看器 - http://developer.android.com/tools/debugging/debugging-ui.html - 在两个布局上使用它可以显示它们在设备上实际运行时的区别。

MvxLinearLayout只是LinearLayout - 它继承了它,只是添加了一个数据绑定Adapter,以便您动态添加/删除子项 - 请参阅MvxLinearLayout.cs.

基于此,一个假设是,LinearLayout本身可能不支持layout_weight这样的动态子女。要调查这个:

  • 你可以尝试在不使用Mvx的情况下对UI进行原型设计 - 做一个简单的LinearLayout&#34;尊重layout_weight&#34;当你添加/删除孩子?如果答案是肯定的,那么原型与MvxLinearLayout.cs.之间有什么区别。如果答案是否定的,那么您知道问题出在LinearLayout某处。
  • 您可以尝试查看LinearLayout源代码 - 例如http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/widget/LinearLayout.java - 这项调查可能会发现一些前进的方法 - 例如,它可能会找到一些方法可以强制LinearLayout重新测量,然后你可以调用它来强制重新测量&#39;来自ChildViewAddedChildViewRemoved事件的方法。
  

任何替代方法可以给我一个动态的项目列表,这些项目将在给定固定维度边界的情况下平均排列?

如果内置布局不适合您,那么创建自己的自定义布局非常简单 - 例如看到http://arpitonline.com/blog/2012/07/01/creating-custom-layouts-for-android/ - 完成后,添加绑定就像复制和粘贴MvxLinearLayout.cs.

中的ViewGroup绑定代码一样简单