Android Snackbar.SnackbarLayout 已过时;更换?

问题描述 投票:0回答:1

我正在维护一个“企业”Android 应用程序,该应用程序在工业环境中的腕戴式计算机上运行。当我们需要让用户知道一些中等重要的信息时,我们让设备发出声音并产生触觉反馈,并在屏幕中间的气泡中弹出一条简短的文本消息。弹出窗口会在几秒钟后自行消失。

这里的设计意图是,用户可以看到发生了什么,但不必伸出惯用手(可能装满了工具或产品)并弄乱设备按钮或屏幕来继续工作。

最初,这是使用

Toast
实现的,生活很美好。然后
Toast
被 Google 淘汰,基于
Snackbar
的新实现(用户无法区分)诞生了。 (出于“历史原因”,使用 C# 为 Xamarin.Android 编写代码,但这对于问题的目的来说应该不重要。)

        public static Snackbar ShowErrorOverlay(Activity activity,
            int duration, int resID, params object[] args)
        {
            var coordinatorLayout = activity.Window.DecorView.RootView;
            var snackbar = Snackbar.Make(coordinatorLayout, string.Empty, Snackbar.LengthLong);
            var layout = activity.LayoutInflater.Inflate(Resource.Layout.ErrorToast,
                activity.FindViewById<ViewGroup>(Resource.Id.errortoast_layout_main), false);
            var txt = layout.FindViewById<TextView>(Resource.Id.errortoast_textview_message);
            txt.Text = string.Format(activity.Resources.GetString(resID), args);
            var snackbarLayout = (Snackbar.SnackbarLayout)snackbar.View;
            snackbarLayout.SetBackgroundColor(Color.Transparent);
            var opts = (FrameLayout.LayoutParams)snackbarLayout.LayoutParameters;
            opts.Gravity = GravityFlags.Center;
            snackbarLayout.LayoutParameters = opts;
            snackbarLayout.AddView(layout);
            snackbar.SetDuration(duration);
            snackbar.Show();
            return snackbar;
        }

Resource.Layout.ErrorToast
来自哪里:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/errortoast_layout_main"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="8dp"
    android:background="@drawable/ErrorToast">
    <TextView
        android:id="@+id/errortoast_textview_message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal|center_vertical"
        android:text="(error message)"
        android:paddingLeft="12dp"
        android:paddingRight="12dp"
        style="@style/TextAppearance"
        android:layout_centerInParent="true" />
</RelativeLayout>

drawable/ErrorToast
看起来像:

<?xml version="1.0" encoding="utf-8" ?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
  <solid android:color="@color/errorBackground" />
  <stroke
      android:width="4dp"
      android:color="@color/errorBorder" />
  <padding
      android:bottom="5dp"
      android:left="5dp"
      android:right="5dp"
      android:top="5dp" />
  <corners android:radius="35dp" />
</shape>

最终结果:文本位于屏幕中间,位于明亮欢快的黄色气泡中,因此:

唉,对于这个麻烦不断的世界来说,有用的 Android API 是永远不会长久的。因此,

Snackbar.SnackbarLayout

Warning XAOBS001    'Snackbar.SnackbarLayout' is obsolete: 'While this type is 'public', Google considers it internal API and reserves the right to modify or delete it in the future. Use at your own risk.'

请阅读通常的 Kübler-Ross 对无端 API 更改的悲痛阶段。

我以后应该用什么来取代这个?具有自定义布局的“最佳实践”吐司/小吃栏之类的弹出窗口是什么? (也许子类

AndroidX.Fragment.App.DialogFragment
?)

我想保留当前的外观(参见上面的屏幕截图)和行为:在屏幕上的任何内容的顶部弹出一段有限的时间,在特定的时间限制后消失(但可以提前关闭)。

当我的应用程序不在前台时,我不需要在屏幕上显示任何内容。

理想情况下,我还可以避免触摸应用程序中的每一个(很多很多)屏幕布局来实现这一目标。

android android-toast snackbar android-snackbar obsolete
1个回答
0
投票

通过反射,

Snackbar.SnackbarLayout
的类层次结构如下所示:

System.Object ->
Java.Lang.Object ->
Android.Views.View ->
Android.Views.ViewGroup ->
Android.Widget.FrameLayout ->
Google.Android.Material.Snackbar.Snackbar+SnackbarLayout

(至少现在是这样。记住,我们的 Google 霸主已经明确警告我们,如果与

Snackbar
类内部过于亲密,后果自负。)

所以,在原来的代码中,我们可以替换:

            var snackbarLayout = (Snackbar.SnackbarLayout)snackbar.View;

与:

            var snackbarLayout = (FrameLayout)snackbar.View;

并且它(至少目前)关闭警告并按预期工作。它没有解决根本问题:我们假设

Snackbar.View
是(或派生自)
View
的特定子类。已发布的 API 不支持该假设,并且仅仅因为它现在是正确的并不能构成其将保持正确的证据。

在紧握的手上,我不清楚将

Snackbar.View
更改为不属于
FrameLayout
子类的任何内容有什么意义。

我想我准备将其归档在“当他们破坏它时我会担心的”(大且不断增长的)类别下,除非有更好的答案。

© www.soinside.com 2019 - 2024. All rights reserved.