问题描述
我的适配器的 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方法无限期循环的第一个孩子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!