Android深入--Snackbar用法及源码解析

什么是Snackbar?Google退出Matrial Design已经有一段时间了,其中有一款控件,叫做Snackbar。那么它是做什么的呢?开发过Android的童鞋们应该对Toast不陌生了,Toast是一款用于在屏幕上显示提示信息的控件。而Snackbar,可以理解为Matrial Design风格的Toast,并且在功能上也有了一定的加强。废话不多说,上图:图中屏幕下方弹出的框...
摘要由CSDN通过智能技术生成

什么是Snackbar?

Google退出Matrial Design已经有一段时间了,其中有一款控件,叫做Snackbar。
那么它是做什么的呢?开发过Android的童鞋们应该对Toast不陌生了,Toast是一款用于在屏幕上显示提示信息的控件。而Snackbar,可以理解为Matrial Design风格的Toast,并且在功能上也有了一定的加强。

废话不多说,上图:
Snackbar演示图
图中屏幕下方弹出的框就是Snackbar。其有着与Toast一样的特性(定时隐藏),也有一些新的特性(可按钮,不点击后隐藏等)。

使用Snackbar

Snackbar的用法并不复杂,使用时并不需要手动去创建Snackbar对象,其用法与Toast相似:

Snackbar.make(view,"显示的内容", Snackbar.LENGTH_LONG).show();

而如果要添加一个按钮并增加点击事件,只需要使用setAction方法即可。
Snackbar中的按钮被点击后,Snackbar会自动消失,并响应//点击事件:

Snackbar.make(view, "显示的内容", Snackbar.LENGTH_LONG)
                        .setAction("按钮", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                //TODO: 点击按钮后的处理
                            }
                        }).show();

当然,Snackbar的每一种属性都可以单独设置,不过其构造方法是私有的,所以获取Snackbar对象的途径只有Snackbar.make方法:

//view可以为布局中任何控件或者跟布局。
public static Snackbar make(@NonNull View view, @NonNull CharSequence text, int duration)	
public class MainActivity extends AppCompatActivity {

    Snackbar snackbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        FloatingActionButton fab = findViewById(R.id.fab);
        snackbar = Snackbar.make(fab, "显示的内容", Snackbar.LENGTH_LONG)
                .setAction("按钮", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        //TODO: 点击按钮后的处理
                    }
                });
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                snackbar.setText("修改后的内容");
                snackbar.setAction("修改后的按钮文字", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        //TODO: 点击按钮后的处理
                    }
                });
                snackbar.show();
            }
        });
    }
}

源码分析

那么了解了Snackbar的用法,大家可能依然会有许多疑问,比如:

  • Snackbar是如何显示到界面上的?
  • 多个Snackbar短时间内显示的时候排队逻辑时什么样的?
  • Snackbar的make方法为什么必须要传递一个view进去?
  • ····
    好的,那么我们就通过源码来了解一下上述疑问。

Snackbar如何显示在界面上

首先,我们需要知道,我们调用Snackbar的make方法后,再次调用show方法,即可将其显示到屏幕上。所以我们就从这两个方法入手:
make方法(ctrl+鼠标左键点进去):

    @NonNull
    public static Snackbar make(@NonNull View view, @NonNull CharSequence text, int duration) {
        ViewGroup parent = findSuitableParent(view);
        if (parent == null) {
            throw new IllegalArgumentException("No suitable parent found from the given view. Please provide a valid view.");
        } else {
            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            SnackbarContentLayout content = (SnackbarContentLayout)inflater.inflate(hasSnackbarButtonStyleAttr(parent.getContext()) ? layout.mtrl_layout_snackbar_include : layout.design_layout_snackbar_include, parent, false);
            Snackbar snackbar = new Snackbar(parent, content, content);
            snackbar.setText(text);
            snackbar.setDuration(duration);
            return snackbar;
        }
    }

从Snackbar的make方法可以看到,其通过我们传递的view来获取到了一个ViewGroup parent。之后又通过parent创建了LayoutInflater并取得了SnackbarContentLayout content。接下来内部通过new创建了一个Snackbar 实例,并且设置显示的文字及显示时长。最终将设置好的Snackbar返回。

看到这里我们可以确定每次调用Snackbar就会新建一个Snackbar对象。而其他代码的意义却不明朗。没关系,继续分析。

首先,我们看看第一行代码:ViewGroup parent = findSuitableParent(view);。可以推测,findSuitableParent方法通过view找到了一个ViewGroup。进入方法查看:

    private static ViewGroup findSuitableParent(View view) {
        ViewGroup fallback = null;

        do {
            if (view instanceof CoordinatorLayout) {
                return (ViewGroup)view;
            }

            if (view instanceof FrameLayout) {
                if (view.getId() == 16908290) {
                    return (ViewGroup)view;
       
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值