2015-03-12 19 views
5

Tôi đang cố gắng để tạo ra một giải pháp gọn gàng cho tình huống sau đây:Xamarin MvvmCross Android Ngăn chặn Nút Quay lại trở về trước Xem

tôi đã xây dựng một ứng dụng mà đòi hỏi phải có chứng chỉ để xác thực người dùng. Bất cứ khi nào API muốn xác thực lại người dùng, tôi muốn buộc người dùng quay lại chế độ xem đăng nhập. Chức năng này hoạt động tốt, nhưng khi người dùng nhấn nút quay lại trên thiết bị, chế độ xem trước đó sẽ hiển thị. Tôi muốn thấy rằng khi người dùng nhấn nút quay lại, ứng dụng sẽ thoát.

MvvmCross có tùy chọn sử dụng MvxPresentationHint. Tôi đã tạo CustomAndroidViewPresenter và tạo MvxAndroidSetup sau:

public class Setup : MvxAndroidSetup 
{ 
    private CustomAndroidViewPresenter _presenter; 
    public Setup(Context applicationContext) 
     : base(applicationContext) 
    { 
     _presenter = new CustomAndroidViewPresenter(applicationContext); 
    } 

    protected override IMvxAndroidViewPresenter CreateViewPresenter() 
    { 
     Mvx.RegisterSingleton(_presenter); 
     return _presenter; 
    } 
} 

Tôi biết rằng bạn nên gọi đến Finish(); trên một hoạt động để ngăn backbutton điều hướng trở lại chế độ xem chưa được xác thực. Nhưng truyền applicationContext để ném một ngoại lệ.

public CustomAndroidViewPresenter(Context context) 
{ 
    _context = context; 
} 

public override void ChangePresentation(MvxPresentationHint hint) 
{ 
    if (hint is LoginOnlyBackStackHint) 
    { 
     var context = Application.Context; 
     if (context is Activity) 
     { 
      // Context is NOT activity 
     } 
     try 
     { 
      Activity x = (Activity) context; 
      x.Finish(); 
      // Exception is thrown 
     } 
     catch (Exception ex) 
     { 

     } 
    } 
    base.ChangePresentation(hint); 
} 

Có ai có ý tưởng nào về cách đạt được điều này không?

Rất cám ơn trước.

Trả lời

11

Tôi đã gặp vấn đề tương tự. Chỉ cần thực hiện một tùy chỉnh Presenter, mà đặt ra một số cờ ý định, nếu bạn muốn đạt được điều này:

public class CustomAndroidPresenter : MvxAndroidViewPresenter 
    { 
     public override void Show(MvxViewModelRequest request) 
     { 
      if (request != null && request.PresentationValues != null) 
      { 
       if (request.PresentationValues.ContainsKey("MyCustomFlag")) 
       { 
        // Get intent from request and set flags to clear backstack. 
        var intent = base.CreateIntentForRequest(request); 
        intent.SetFlags(ActivityFlags.ClearTask | ActivityFlags.NewTask); 

        base.Show(intent); 
        return; 
       } 
      } 

      base.Show(request); 
     } 
    } 

Sau đó, bạn cần phải thiết lập người dẫn chương trình này trong lớp học thiết lập của bạn:

protected override IMvxAndroidViewPresenter CreateViewPresenter() 
     { 
      var presenter = new CustomAndroidPresenter(); 
      Mvx.RegisterSingleton<IMvxViewPresenter>(presenter); 
      return presenter; 
     } 

Và sau đó để hiển thị một viewmodel (như đăng nhập-view của bạn) chỉ cần thiết lập tùy chỉnh-cờ-key-code của bạn mà người dẫn chương trình biết rằng anh ta nên thiết lập các Inten-cờ:

protected void ShowViewModel<TViewModel>(bool clearbackstack) where TViewModel : MvxViewModel 
     { 
      if (clearbackstack) 
      { 
       var presentationBundle = new MvxBundle(new Dictionary<string, string> { { "MyCustomFlag", "" } }); 
       ShowViewModel<TViewModel>(presentationBundle: presentationBundle); 
       return; 
      } 

     // Normal start 
     ShowViewModel<TViewModel>(); 
    } 

Để hiển thị một viewmodel (không back-navigation) chỉ cần sử dụng follo mã cánh:

ShowViewModel<MyViewModel>(true); 

Sau đó, khi bạn nhấn nút quay lại, bạn không thể điều hướng trở lại hoạt động trước đó vì hậu trường bị xóa.

+0

Cảm ơn bạn đã trả lời! Tôi sẽ xem xét và cung cấp phản hồi của tôi – JonHendrix

+0

Nó đã hoạt động! Đánh dấu là câu trả lời - Cảm ơn! – JonHendrix

1

Bạn có thể tận dụng phương pháp vòng đời Hoạt động OnStop.

public class LoginActivity : MvxAppCompatActivity<LoginViewModel> 
{ 
    protected override void OnCreate(Bundle bundle) 
    { 
     base.OnCreate(bundle); 
     SetContentView(Resource.Layout.activity_login); 
    } 

    /// <summary> 
    /// Removes activity from history after navigating to new activity. 
    /// </summary> 
    protected override void OnStop() 
    { 
     base.OnStop(); 
     Finish(); 
    } 

    /// <summary> 
    /// Closes app if back button is pressed. 
    /// </summary> 
    public override void OnBackPressed() 
    { 
     if (FragmentManager.BackStackEntryCount > 0) 
     { 
      FragmentManager.PopBackStack(); 
     } 
     else 
     { 
      base.OnBackPressed(); 
     } 
    } 
} 
Các vấn đề liên quan