Xamarin Android Fragment在ViewModel准备好之前显示View

时间:2018-02-07 11:16:48

标签: android-fragments asynchronous xamarin xamarin.android mvvmcross

我遇到了等待异步方法的问题。我有一个片段(SalesFragment),其中包含带有两个片段的TabLayout(FirstSalesFragment和SecondSalesFragment)。当我显示SalesFragment并且在TabLayout中选择了FirstSalesFragment时,我在ViewModel async方法中调用了API并给了我一些数据。但问题在于FirstSalesFragment我有Microcharts布局,我想显示那里Chart,但主要问题是我的图表条目是来自Api的异步方法和OnCreateView方法只是不等待我在ViewModel中的异步方法。

我的FirstSales视图只是显示但是图表是空的,因为OnCreateView不等待条目......我尝试过OnActivityCreated或OnStart方法,但它同样...

我的SalesFragment

public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            _view = base.OnCreateView(inflater, container, savedInstanceState);

            var viewPager = _view.FindViewById<ViewPager>(Resource.Id.viewpager);
            if (viewPager != null)
            {
                var fragments = new List<MvxViewPagerFragmentInfo>
                {
                    new MvxViewPagerFragmentInfo(ViewModel.FirstSalesTab, typeof(FirstSalesFragment), typeof(FirstSalesViewModel)),
                    new MvxViewPagerFragmentInfo(ViewModel.SecondSalesTab, typeof(SecondSalesFragment), typeof(SecondSalesViewModel))
                };

                viewPager.Adapter = new MvxCachingFragmentStatePagerAdapter(Activity, ChildFragmentManager, fragments);
            }

            var tabLayout = _view.FindViewById<TabLayout>(Resource.Id.tabs);
            tabLayout.SetupWithViewPager(viewPager);

            return _view;
        }

FirstSalesViewModel:

 public class FirstSalesViewModel : BaseViewModel
    {
        private readonly ISessionInfo _session;
        private readonly IInfoMessageReporter _infoMessageReporter;

        public FirstSalesViewModel()
        {
            _session = Mvx.Resolve<ISessionInfo>();
            _infoMessageReporter = Mvx.Resolve<IInfoMessageReporter>();
        }

        public async Task Initialize()
        {
        }

        public void Init()
        {
            Task.Run(InitializeHourlySales);
        }
        private async Task InitializeHourlySales()
        {
            // Call API async service... initialize Entries here....

        }

        private List<Entry> _entries;
        public List<Entry> Entries
        {
            get { return _entries; }
            set
            {
                _entries = value;
                RaisePropertyChanged(() => Entries);
            }
        }

    }
}

FirstSalesFragment

public class FirstSalesFragment : BaseFragment<FirstSalesViewModel>
    {
        protected override int FragmentId => Resource.Layout.fragment_firstsales;
        private View _view;
        private ChartView _chartView;

        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            _view = base.OnCreateView(inflater, container, savedInstanceState);
            _chartView = _view.FindViewById<ChartView>(Resource.Id.chartView);

            if (_chartView != null)
            {
                InitializeChart();
            }

            return _view;
        }



        private void InitializeChart()
        {
            var tempEntries = ViewModel.Entries;

            if (tempEntries == null || tempEntries.Count == 0)
            {
                _chartView.Chart = null;
                return;
            }

              var tempChart = new LineChart
                {
                    Entries = tempEntries,
                    LineMode = LineMode.Straight,
                    LineSize = 5,
                    LabelTextSize = 25,
                    AnimationDuration = new TimeSpan(0, 0, 5),
                    BackgroundColor = SKColor.Parse("#EEEEEE")
                };

                _chartView.Chart = tempChart;
        }
    }

1 个答案:

答案 0 :(得分:0)

在OnResume中调用支持使用async的异步代码。

我已经修改了你的代码示例,并在OnResume()中为FirstSalesFragment调用了ViewModel.Init()。

FirstSalesViewModel

public class FirstSalesViewModel : BaseViewModel
{
       ...
    public async Task Init()
    {
        await Task.Run(InitializeHourlySales);
    }
    private async Task InitializeHourlySales()
    {
        // Call API async service... initialize Entries here....

    }
    .....

FirstSalesFragment

    ...
    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        _view = base.OnCreateView(inflater, container, savedInstanceState);
        _chartView = _view.FindViewById<ChartView>(Resource.Id.chartView);



        return _view;
    }


    public async override void OnResume()
    {
      base.OnResume();
      await ViewModel.Init();
      if (_chartView != null)
        {
            InitializeChart();
        }
    }
    ...