Как избежать неправильного повторного использования пользовательских ячеек в MvxGridView? - PullRequest
0 голосов
/ 02 мая 2018
  1. У меня есть страница приложения Android (на фрагменте) с MvxGridView с таким макетом:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:local="http://schemas.android.com/apk/res-auto"
         android:orientation="vertical"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
    
    <MvxGridView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:numColumns="1"
        android:horizontalSpacing="0dp"
        android:verticalSpacing="0dp"
        local:MvxBind="ItemsSource DayGraphsItems"
        local:MvxItemTemplate="@layout/day_graph_item" />
    </LinearLayout>
    
  2. У меня есть пользовательский вид для рисования графика:

    public class GraphView : View
    {
        Paint mPaint;
        Bitmap mBitmap;
        Canvas mCanvas;
        Path mPath;
        Paint mBitmapPaint;
    
        public List<string> Data { get; set; }
    
        public GraphView(Context context, Android.Util.IAttributeSet attributeSet) : base(context)
        {
            mPaint = new Paint();
            mPaint.AntiAlias = true;
            mPaint.Dither = true;
            mPaint.SetARGB(0xFF, 0xFF, 0xFF, 0xFF);
            mPaint.SetStyle(Paint.Style.FillAndStroke);
            mPaint.StrokeJoin = Paint.Join.Round;
            mPaint.StrokeCap = Paint.Cap.Round;
            mPaint.StrokeWidth = 1;
            mPaint.TextSize = 24;
    
            mPath = new Path();
            mBitmapPaint = new Paint();
           mBitmapPaint.SetARGB(0xFF, 0xFF, 0xff, 0xff);
       }
    
       protected override void OnSizeChanged(int w, int h, int oldw, int oldh)
       {
            if (w > 0 && h > 0)
            {
                mBitmap = Bitmap.CreateBitmap(w, h, Bitmap.Config.Argb8888);
                mCanvas = new Canvas(mBitmap);
    
                _canvasHeight = h;
                _canvasWidth = w;
    
                DrawTheGraph(Data);
            }
        }
    
        public override void Draw(Canvas canvas)
        {
            canvas.DrawBitmap(mBitmap, 0, 0, mBitmapPaint);
            canvas.DrawPath(mPath, mPaint);
            canvas.Restore();
        }
    
        private void DrawTheGraph(List<string> data)
        {
           // here is drawing of the graph which works well
        }
    }
    
  3. У меня есть пользовательская привязка

    public class GraphCustomBinding : MvxConvertingTargetBinding
    {
    
        public static string Name = "GraphCustom";
    
        public GraphCustomBinding(GraphView target) : base(target)
        {
        }
    
        protected override void SetValueImpl(object target, object value)
        {
            var data = new List<string>();
            data = (List<string>)value;
    
            var targetGraphView = (GraphView)target;
            targetGraphView.Data = data;
        }
    
        public override Type TargetType
        {
             get { return typeof(GraphView); }
        }
    }
    
  4. Привязка правильно зарегистрирована в настройках.

  5. У меня есть макет элемента для элементов списка DayGraphsItems

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:local="http://schemas.android.com/apk/res-auto"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        android:paddingTop="15dp"
        android:paddingBottom="15dp">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical|center_horizontal"
        style="@style/TextViewCurrentConditionsHeader"
        local:MvxBind="Text Title" />
    <Pogoda.Droid.GraphView
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:padding="5dp"
        local:MvxBind="GraphCustom Data, Mode=TwoWay" />
    </LinearLayout>
    

EDIT:

  1. DayGraphsItems - это список DayGraphItem, который представлен следующим образом:

    public class DayGraphItem
    {
        public int Id { get; set; }
    
        public string Title { get; set; }
    
        public List<string> Data { get; set; }
    }
    
  2. Вид на фрагмент:

    [Register("pogoda.droid.DayGraphsFragment")]
    public class DayGraphsFragment : BaseFragment<DayGraphsViewModel>
    {
        public const string TAG = "DayGraphsFragmentTag";
    
        public override string UniqueImmutableCacheTag
        {
            get
            {
                return TAG;
            }
        }
    
        public override Android.Views.View OnCreateView(Android.Views.LayoutInflater inflater, Android.Views.ViewGroup container, Android.OS.Bundle savedInstanceState)
        {
            base.OnCreateView(inflater, container, savedInstanceState);
            return this.BindingInflate(Resource.Layout.day_graphs_layout, null);
        }
    }
    

Проблема: Графики нарисованы правильно, но в случае, когда на экране больше ячеек, чем можно было бы отобразить сразу, после прокрутки вниз я вижу вместо ранее отображенные ячейки новые (кажется, используются повторно).

ВОПРОС: Как избежать этого и отображать свежие графики вместо «прокручиваемых сверху»?

1 Ответ

0 голосов
/ 04 мая 2018

Решение, которое работает для меня это

Создайте EnhancedMvxListView и замените MvxGridView, используя его в пункте 1.

    public class EnhancedMvxListView : MvxListView
    {
        public EnhancedMvxListView(Context context, IAttributeSet attrs) : base(context, attrs, new EnhancedMvxAdapter(context))
        { 
        }

        public EnhancedMvxListView(Context context, IAttributeSet attrs, IMvxAdapter adapter) : base(context, attrs, new EnhancedMvxAdapter(context))
        { 
        }
    }

, где EnhancedMvxAdapter является следующим

public class EnhancedMvxAdapter : MvxAdapterWithChangedEvent
{
    public EnhancedMvxAdapter(Context context) : base(context)
    {
    }

    protected override View GetBindableView(View convertView, object dataContext, ViewGroup parent, int templateId)
    {
        templateId = GetTemplateId(dataContext);

        var view = base.GetBindableView(convertView, dataContext, parent, templateId);

        var context = dataContext as DayGraphItem;

        view.FindViewById<TextView>(Resource.Id.graphTitle).Text = context.Title;
        view.FindViewById<GraphView>(Resource.Id.graphDrawing).Data = context.Data;

        return view;
    }

    private int GetTemplateId(object data)
    {
        return Resource.Layout.day_graph_item;
    }
}

И, наконец, в файле в пункте 2. Я заменил

    public List<string> Data { get; set; }    

с

    List<string> _data;
    public List<string> Data
    {
        get
        {
            return _data;
        }
        set
        {
            if (value != null && value != _data)
            {
                _data = value;

                if ((int)_canvasWidth == 0 || (int)_canvasHeight == 0)
                    return;

                mBitmap = Bitmap.CreateBitmap((int)_canvasWidth, (int)_canvasHeight, Bitmap.Config.Argb8888);
                mCanvas = new Canvas(mBitmap);

                DrawTheGraph(Data);
            }
        }
    } 
...