MvvmCross:MvxAdapter GetBindableView方法无限期循环的第一个孩子 [英] MvvmCross: MvxAdapter GetBindableView method loops indefinitely on first child

查看:652
本文介绍了MvvmCross:MvxAdapter GetBindableView方法无限期循环的第一个孩子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的适配器的 GetBindableView 方法为我MvxGridView所有孩子的正常调用,但随后的第一个孩子无限循环。

The GetBindableView method of my adapter is called normally for all childs of my MvxGridView, but then it loops indefinitely on the first child.

在一个MvxFragment我在 OnCreateView 方法来设置适配器一个MvxGridView:

In a MvxFragment I set an adapter to a MvxGridView in the OnCreateView method:

public class MetronomeFragment : MvxFragment<MetronomeViewModel>, View.IOnTouchListener
{
    public override View OnCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        var ignored = base.OnCreateView (inflater, container, savedInstanceState);
        var view = this.BindingInflate (Resource.Layout.fragment_metronome, null);

        // GridView
        var gridView = view.FindViewById<MvxGridView>(Resource.Id.grid_view);
        gridView.Adapter = new CustomAdapter (Activity, (MvxAndroidBindingContext)BindingContext);

        return view;
    }
}

我的观点的一部分:

A part of my view:

<Mvx.MvxGridView
    android:id="@+id/grid_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:stretchMode="columnWidth"
    android:numColumns="5"
    android:verticalSpacing="@dimen/metronome_grid_view_vertical_spacing"
    local:MvxBind="ItemsSource MeasureViewModel.Measure.BeatList"
    local:MvxItemTemplate="@layout/template_item_metronome_beat" />

我的模板:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:layout_width="@dimen/item_metronome_beat_layout_width"
    android:layout_height="@dimen/item_metronome_beat_layout_height"
    android:layout_gravity="center"
    local:cardBackgroundColor="@color/card_view"
    local:cardCornerRadius="@dimen/card_view_corner_radius"
    local:MvxBind="CardElevation BoolToElevation(IsPlaying, 2); Alpha BoolToAlpha(IsPlaying, 0.5)">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="@dimen/item_metronome_beat_margin">
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="fitXY"
            local:MvxBind="DrawableId BeatToImageResource(.)" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:textSize="@dimen/text_small"
            local:MvxBind="Text Number" />
    </RelativeLayout>
</android.support.v7.widget.CardView>

下面是我的自定义适配器:

Here is my custom adapter:

public class CustomAdapter : MvxAdapter
{
    public CustomAdapter(Context context, IMvxAndroidBindingContext bindingContext)
            : base(context, bindingContext)
    {
    }

    protected override View GetBindableView(View convertView, object source, int templateId)
    {
        var beat = (Beat)source;
        Mvx.Trace (beat.Number.ToString ());

        return base.GetBindableView(convertView, source, templateId);
    }
}

对于这个测试的目的,我只登录节拍数(DataContext对象)。列表中包含4次,输出为:1,2,3,4,1个,1个,1个,1个,1个,1个,1个,1个,1个,1个,......它总是第一个孩子环路! !

For this test purpose, I just log the beat number (DataContext object). The list contains 4 beats and the output is: 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ... And it loops always on first child!!!

我使用MvvmCross 4.0.0-beta5的。

I'm using MvvmCross 4.0.0-beta5.

任何人有一个想法?

干杯

推荐答案

我终于找到一个解释!
这是一个意想不到的屏幕刷新由于 ViewTreeObserver.GlobalLayout 事件的组合和 RelativeLayout的

I finally found an explanation! It's an unexpected screen refresh due to a combination of a ViewTreeObserver.GlobalLayout event and a RelativeLayout.

我在我的主要活动此code 的OnCreate 方法能够显示(作为临时的屏幕调试信息)的屏幕尺寸和密度:

I have this code in my main activity OnCreate method to be able to display (as a temporary onscreen debug info) the screen size and density:

var contentView = FindViewById<View> (Window.IdAndroidContent);
var sizeText = FindViewById<Android.Widget.TextView> (Resource.Id.size_text);
contentView.ViewTreeObserver.GlobalLayout += (sender, e) => {
    var height = (int) ((contentView.Height)/Resources.DisplayMetrics.Density);
    var width = (int) ((contentView.Width)/Resources.DisplayMetrics.Density);
    sizeText.Text = height + " x " + width + " " + Resources.DisplayMetrics.DensityDpi.ToString();
};

我不知道什么是,这种方法称为重复。这意味着,在的TextView 更改文本每秒(即使规模一直没有更改)。

What I didn't know, is that this method is called repetitively. It implies that the text in the TextView is changed several times per seconds (even if the size hasn't changed).

我的主要观点是:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background">
    <include
        android:id="@+id/toolbar"
        layout="@layout/toolbar" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/size_text" />
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/toolbar"
        android:layout_above="@+id/ad_view" />
    <com.google.android.gms.ads.AdView
        android:id="@id/ad_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        local:adSize="BANNER"
        local:adUnitId="@string/ad_unit_id" />
</RelativeLayout>

我的包含的FrameLayout 我的 GridView控件被包含在一个RelativeLayout的,以及我的TextView 。由于的TextView 的内容总是变化,每一个视图的大小被重新计算。而且这也为 GridView控件,这意味着到 GetBindable 方法的调用情况。

My FrameLayout containing my GridView is contained in a RelativeLayout as well as my TextView. As the content of the TextView always changes, the size of every views is recalculated. And it's also the case for the GridView, which implied a call to the GetBindable method.

要避免这一呼吁得到循环大小时,让你的活动实施 Android.Views.ViewTreeObserver.IOnGlobalLayoutListener ,并在 OnCreate中添加此方法:

To avoid this call loop when getting the size, make your activity to implement Android.Views.ViewTreeObserver.IOnGlobalLayoutListener and add this in the OnCreate method:

var contentView = FindViewById<View> (Window.IdAndroidContent);
contentView.ViewTreeObserver.AddOnGlobalLayoutListener(this);

和添加此方法:

public void OnGlobalLayout ()
{
    var metrics = Resources.DisplayMetrics;
    var contentView = FindViewById<View> (Window.IdAndroidContent);
    var sizeText = FindViewById<Android.Widget.TextView> (Resource.Id.size_text);
    var height = (int) ((contentView.Height)/metrics.Density);
    var width = (int) ((contentView.Width)/metrics.Density);
    sizeText.Text = height + " x " + width + " " + metrics.DensityDpi.ToString();
    contentView.ViewTreeObserver.RemoveOnGlobalLayoutListener(this);
}

有一个愉快的周末乡亲!!!!

Have a nice weekend folks!!!!

这篇关于MvvmCross:MvxAdapter GetBindableView方法无限期循环的第一个孩子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆