【问题标题】:Where to place Toasts, Snackbars etc. in era of Android Architecture ComponentsAndroid 架构组件时代的 Toasts、Snackbars 等在哪里放置
【发布时间】:2019-04-29 15:58:35
【问题描述】:

ViewModelone activity multiple fragments 概念的时代,关于在Activity vs. Fragment 中放置Toasts、Snackbars 有什么建议。

很明显

  • 新意图
  • 片段事务/片段设置
  • 权限请求
  • 呈现导航组件(抽屉、查看器)

应该由活动来处理,但是 Toasts/Snackbars 呢?

关于如何在 Fragment 中显示 Toast 或 Snackbars 以及如何 + 何时使用 getContext() 有很多 SO 问题,我倾向于让活动处理所有显示消息。

使用 ViewModel 和 SingleLiveEvent 很容易拥有一个 sharedViewModel,它将被 Activity 和 Fragment 观察,并且在需要时,Fragment 会调度一个通知 Activity 显示消息的事件。

那么,在考虑责任和关注点分离的同时,您认为最佳做法/建议是什么?

【问题讨论】:

    标签: android android-architecture-components android-viewmodel


    【解决方案1】:

    Google's codelabs on basic architecture components 中汲取灵感,让片段/活动对ViewModel 的变化做出反应似乎更好。

    从上面的 Google 链接来看,这意味着最有效的方法之一是从您的​​ ActivityViewModel 对象的 Observe() LiveData 属性

    【讨论】:

      【解决方案2】:

      这取决于。也许你总是可以用一些 UI 部件(TextViews、Buttons)或 Dialogs / DialogFragments 替换 toasts/snackbars。

      这确实取决于您的应用架构,但我想您可以设计一些依赖项:活动或片段范围,因此您可以将其作为 ViewModel 的抽象注入并按照您的需要使用。

      恕我直言,如果您处理 Toasts,您可以在 activty/application 范围内设计 MessageShower 并在任何地方重用它(处理 Toast 的单个实例),但 Snackbars 需要显示 View(因此它们需要生命周期,而且更容易造成内存泄漏)。

      interface MessageShower{
          void showMessage(String message);
      }
      
      class LongToastMessageShower implements MessageShower{
          private Toast toast;
      
          public LongToastMessageShower(Context appContext){
               this.toast = Toast.makeText(appContext,"",Toast.LENGTH_LONG);
          }
      
          @Override
          public void showMessage(String message){
              toast.cancel();
              toast.setText(message);
              toast.show(); 
          }
      
      }
      

      【讨论】:

        【解决方案3】:

        您可以创建BaseActivityBaseFragment,在其中创建所有常用方法,例如在YourActivityYourFragment 中扩展的Toast、Snackbar 等。

        【讨论】:

          【解决方案4】:

          使用 AndroidViewModel() 例如

          class LoginViewModel(application: Application) : AndroidViewModel(application) {
               private val context = getApplication<Application>().applicationContext
               //use that context when toasting in your viewModel
          }
          

          用于小吃店 如果它是您 xml 中的按钮,请使用此属性和值

          android:onClick="@{() -> login.signIn(signIn)}"
          

          在该上下文中,括号内的signIn 指的是您设置 onClick 属性的按钮的 id 请记住,.signIn 之前的登录是指您的变量名

          在您的视图模型中

          fun signIn(view: View){
             //use view to display your snack bar
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-08-01
            • 2019-12-16
            • 1970-01-01
            • 2011-03-30
            • 2018-11-09
            • 1970-01-01
            • 1970-01-01
            • 2011-10-26
            相关资源
            最近更新 更多