弹出式消息 - Snackbar

弹出式消息 - Snackbar

弹出式消息有多种,如Toast, Notification, Snackbar等,谷歌Material Design推出后,建议前台中使用Snackbar,后台中使用Notification代替Toast。

Snackbar简介

Snackbar是一种轻量级的消息反馈,将会在位于设备左下角显示一则简短的消息。和Toast一样Snackbar会在短暂显示后自动消失,此外Snackbar还可以和用户交互,如滑动清除,点击事件等。Snackbar的使用需要有几个条件:

BaseTransientBoottomBar.java

final void showView() {
    ...
    // Set view to INVISIBLE so it doesn't flash on the screen before the inset adjustment is
    // handled and the enter animation is started
    view.setVisibility(View.INVISIBLE);
    targetParent.addView(this.view);
    ...
}
  • 由于Toast是基于Window而Snackbar是基于View动态添加到页面,因此Snackbar的父View Group中,必须要有CoordinatorLayout
  • Snackbar必须在前台页面中呈现

显示一则消息

直接看个效果

可以看出两点区别:

  1. Snackbar只会在前台页面的底部出现,当页面置为后台后无法跟随置为后台;而Toast因为其本质基于Window,因此其行为与前台后台无关;

  2. 顺序执行两条消息展示时,Snackbar的更新机制是实时更新,而Toast则是要等待前一条消息消失后,才会更新第二条;

  3. 此外,Snackbar还支持滑动消失;

源码如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/coordinator_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".material.design.MaterialDesignActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <Button
            android:id="@+id/btn_snackbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Snackbar" />

    </LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
class MaterialDesignActivity : AppCompatActivity() {
    companion object {
        @JvmStatic
        fun startActivity(context: Context) {
            context.startActivity(Intent(context, MaterialDesignActivity::class.java))
        }
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_material_design)
        findViewById<View>(R.id.btn_snackbar).setOnClickListener {
            Snackbar.make(findViewById(R.id.coordinator_layout), "SnackBar: 弹出消息,测试测试1", Snackbar.LENGTH_SHORT).show()
            Snackbar.make(findViewById(R.id.coordinator_layout), "SnackBar: 弹出消息,测试测试2", Snackbar.LENGTH_SHORT).show()
            with(Toast.makeText(this, "Toast: 弹出消息,测试测试1", Toast.LENGTH_SHORT)) {
                setGravity(Gravity.CENTER, 0, 0)
                show()
            }
            with(Toast.makeText(this, "Toast: 弹出消息,测试测试2", Toast.LENGTH_SHORT)) {
                setGravity(Gravity.CENTER, 0, 0)
                show()
            }
        }
    }
}

核心代码为: Snackbar.make().show()

本例代码中有一点需要注意:Toast在sdk 30开始,setGravity()方法设置文本型消息的弹出位置将无效:

还有一点需要注意:Snackbar默认添加在View Group的底部,会将页面中一些特殊的组件挤上去,如FloatingActionButton

添加点击交互

Snackbar还提供了和用户的动作交互,可以允许用户直接在消息条上点击并触发响应。如用户进行了误删除操作,此时可以在删除成功的消息条上增加撤销删除的交互:

代码实现如下:

...

val btn = findViewById<View>(R.id.btn_snackbar)
btn.visibility = View.INVISIBLE
val snackbar = Snackbar.make(findViewById(R.id.coordinator_layout), "已删除", Snackbar.LENGTH_LONG)
snackbar.setAction("撤销") { btn.visibility = View.VISIBLE }.show()

...

核心代码为:Snackbar.setAction()

总结

不少公司产品习惯用苹果的设计思路来套在安卓样式上,其实安卓也有自己的样式-Material Design,如上面提到的Snackbar。在项目开发中,应该根据不同场景合理的选择风格,才有利于安卓生态的建设。

posted @ 2022-05-20 15:46  zhoux_top  阅读(277)  评论(0编辑  收藏  举报