OxyPlot in RecyclerView-MVVMCross Xamarin.Андроид
У меня есть следующая реализация, где у меня есть recycler view, в каждом представлении я пытаюсь отобразить данные с помощью OxyPlot.
Я мог бы видеть жестко закодированные значения графика на каждой карте, но когда я прокручиваю, это своего рода медленный ответ, и приложение зависает на некоторое время. Интересно, что я делаю не так или как улучшить эту проблему производительности?
Мэйнвью.xml
<MvxRecyclerView
android:id="@+id/myRecyclerView"
android:layout_marginTop="10dp"
android:scrollbars="vertical"
android:divider="@null"
android:layout_width="match_parent"
android:layout_height="match_parent"
local:MvxItemTemplate="@layout/mycardview" />
Микардвью.xml
<RelativeLayout
android:layout_width="200dp"
android:layout_height="match_parent">
<oxyplot.xamarin.android.PlotView
android:id="@+id/Plot"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
Мэйнвью.cs
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var ignored = base.OnCreateView(inflater, container, savedInstanceState);
var view = this.BindingInflate(Resource.Layout.MainView, null);
HasOptionsMenu = true;
var cardRecyclerView = view.FindViewById<MvxRecyclerView>(Resource.Id.myRecyclerView);
if (cardRecyclerView != null)
{
cardRecyclerView.HasFixedSize = false;
cardRecyclerView .Adapter = new MainViewRecyclerAdapter((IMvxAndroidBindingContext)BindingContext, Activity);
var layoutManager = new LinearLayoutManager(Activity);
cardRecyclerView.SetLayoutManager(layoutManager);
}
return view;
}
MainViewRecyclerAdapter .cs
public class MainViewRecyclerAdapter : MvxRecyclerAdapter
{
private readonly FragmentActivity _activity;
public MainViewRecyclerAdapter(IMvxAndroidBindingContext bindingContext, FragmentActivity activity)
: base(bindingContext)
{
_activity = activity;
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
base.OnBindViewHolder(holder, position);
var view = holder.ItemView;
var cardOptionsButton = view.FindViewById<PlotView>(Resource.Id.Plot);
MainViewModel MyMainViewModel = new MainViewModel();
cardOptionsButton.Model = MyMainViewModel.MyModel;
}
}
MyMainViewModel.cs
public class MyViewModel : MvxViewModel
{
public MyViewModel()
{
GeneratePlotPoints();
}
void GeneratePlotPoints()
{
var mo = new PlotModel();
var s1 = new LineSeries()
{
Color = OxyColors.SkyBlue,
MarkerType = MarkerType.Circle,
MarkerSize = 6,
MarkerStroke = OxyColors.White,
MarkerFill = OxyColors.SkyBlue,
MarkerStrokeThickness = 1.5
};
s1.Points.Add(new DataPoint(0, 10));
s1.Points.Add(new DataPoint(10, 40));
s1.Points.Add(new DataPoint(40, 20));
s1.Points.Add(new DataPoint(60, 30));
mo.Series.Add(s1);
MyModel = mo;
}
PlotModel _myModel;
public PlotModel MyModel
{
get { return _myModel; }
set { SetProperty(ref _myModel, value); }
}
}
1 ответ:
Я не смог заставить ваш пример из вопроса работать. Тем не менее, вы можете попробовать использовать привязку данных (точек участка) к вашему макету, а не воссоздавать ваш
ViewModel
как стандартный объект класса в вашемAdapter
.
Пример Реализации:
ViewModel
Для простоты я только что создал простой
ObservableCollection
, который содержит одни и те же группы точек графика (форма графика), повторяющиеся несколько раз. обновление: как aPlotModel
может использоваться только один раз вPlotView
вы должны убедиться, чтоPlotModel
всегда является новым экземпляром.public class MyViewModel : BaseViewModel { PlotModel GeneratePlotPoints() { var mo = new PlotModel(); var s1 = new LineSeries() { Color = OxyColors.SkyBlue, MarkerType = MarkerType.Circle, MarkerSize = 6, MarkerStroke = OxyColors.White, MarkerFill = OxyColors.SkyBlue, MarkerStrokeThickness = 1.5 }; s1.Points.Add(new DataPoint(0, 10)); s1.Points.Add(new DataPoint(10, 40)); s1.Points.Add(new DataPoint(40, 20)); s1.Points.Add(new DataPoint(60, 30)); mo.Series.Add(s1); return mo; } List<PlotModel> GenerateGraph() { var graphPlots = new List<PlotModel>(); int counter = 0; while (counter < 10) { graphPlots.Add(GeneratePlotPoints()); counter++; } return graphPlots; } public List<PlotModel> GraphPlots => GenerateGraph(); }
Макет
Ваш основной макет с RecyclerView.
<MvxRecyclerView android:id="@+id/myRecyclerView" android:layout_marginTop="10dp" android:scrollbars="vertical" android:divider="@null" android:layout_width="match_parent" android:layout_height="match_parent" local:MvxBind="ItemsSource GraphPlots" local:MvxItemTemplate="@layout/mycardview" />
Шаблон макета
mycardview
. Обратите внимание, что использование точки используется для указания Mvx привязаться ко всей модели (в данном случае к PlotModel), но она также может быть оставлена пустой (mvx doc ссылка ).<?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"> <oxyplot.xamarin.android.PlotView android:id="@+id/Plot" android:layout_width="match_parent" android:layout_height="match_parent" local:MvxBind="Model ."/> </RelativeLayout>
Вид
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { var ignored = base.OnCreateView(inflater, container, savedInstanceState); var view = this.BindingInflate(Resource.Layout.MainView, null); HasOptionsMenu = true; var cardRecyclerView = view.FindViewById<MvxRecyclerView>(Resource.Id.myRecyclerView); if (cardRecyclerView != null) { cardRecyclerView.HasFixedSize = false; var layoutManager = new LinearLayoutManager(Activity); cardRecyclerView.SetLayoutManager(layoutManager); } return view; }
обновление-включить скриншот