Snackbar的简单使用

本文详细介绍了Snackbar控件的使用方法及其实现原理。从创建Snackbar的基本步骤出发,包括寻找合适的父容器、设置显示时间和按钮监听等,并展示了如何自定义Snackbar的样式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Snackbar是5.0推出的新控件,主要作用是一种新的软提醒,也可以与用户进行简单的交互。
效果图如下:
这里写图片描述
直接看下snackbar的主要创建方法

 Snackbar.make(target, "请事件输入标题", Snackbar.LENGTH_LONG)//设置目标容器,事件标题,显示时间
                .setActionTextColor(Color.WHITE)//设置事件文字颜色
                .setAction("按鈕文字", new View.OnClickListener() {//设置按钮文字和监听
                    @Override
                    public void onClick(View v) {

                    }
                })
                .show();//显示

直接看下make方法的里面实现了什么

@NonNull
    public static Snackbar make(@NonNull View view, @NonNull CharSequence text,
            @Duration int duration) {
        final ViewGroup parent = findSuitableParent(view);
        if (parent == null) {
            throw new IllegalArgumentException("No suitable parent found from the given view. "
                    + "Please provide a valid view.");
        }

        final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        final SnackbarContentLayout content =
                (SnackbarContentLayout) inflater.inflate(
                        R.layout.design_layout_snackbar_include, parent, false);
        final Snackbar snackbar = new Snackbar(parent, content, content);
        snackbar.setText(text);
        snackbar.setDuration(duration);
        return snackbar;
    }

先看第一行代码final ViewGroup parent = findSuitableParent(view);通过传递过来目标view,寻找合适的
父控件,来加入snackbar。看方法里面实现找到合适的父容器

private static ViewGroup findSuitableParent(View view) {
        ViewGroup fallback = null;
        //循环获取
        do {
            if (view instanceof CoordinatorLayout) {
                //如果这里传过来是协调布局,想当然容器viewgroup了,直接返回
                // We've found a CoordinatorLayout, use it
                return (ViewGroup) view;
            } else if (view instanceof FrameLayout) {
                if (view.getId() == android.R.id.content) {
                    // If we've hit the decor content view, then we didn't find a CoL in the
                    // hierarchy, so use it.
                    //DecorView是PhoneWindow类的内部类 相当于DecorView是一个FrameLayout,对布局进行装饰的作用。然后会根据theme去选择系统中的布局文件,将布局文件通过inflate转化为view,加入到DecorView中;所以这里直接寻找android.R.id.content的控件,找到就是一个适合的容器布局
这些布局文件中都包含一个id为content的FrameLayout,
                    return (ViewGroup) view;
                } else {
                    // It's not the content view but we'll use it as our fallback
                    fallback = (ViewGroup) view;
                }
            }

            if (view != null) {
                // 否则,我们会循环并寻找上视图层级并试图找到一个父类
                final ViewParent parent = view.getParent();
                view = parent instanceof View ? (View) parent : null;
            }
        } while (view != null);

        // If we reach here then we didn't find a CoL or a suitable content view so we'll fallback
        return fallback;
    }

内容很好理解,就是寻找一个合适的父类而已。
往下看下面代码:

final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        final SnackbarContentLayout content =
                (SnackbarContentLayout) inflater.inflate(
                        R.layout.design_layout_snackbar_include, parent, false);

更好理解了,将snackbar的布局加入到合适的父控件里面。
再往下就是

final Snackbar snackbar = new Snackbar(parent, content, content);
        snackbar.setText(text);
        snackbar.setDuration(duration);
        return snackbar;

返回一个Snackbar的实例,设置标题文字,显示时间参数。

snackbar的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2015 The Android Open Source Project
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~      http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
-->

<view
    xmlns:android="http://schemas.android.com/apk/res/android"
    class="android.support.design.internal.SnackbarContentLayout"
    android:theme="@style/ThemeOverlay.AppCompat.Dark"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom">

    <TextView
        android:id="@+id/snackbar_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:paddingTop="@dimen/design_snackbar_padding_vertical"
        android:paddingBottom="@dimen/design_snackbar_padding_vertical"
        android:paddingLeft="@dimen/design_snackbar_padding_horizontal"
        android:paddingRight="@dimen/design_snackbar_padding_horizontal"
        android:textAppearance="@style/TextAppearance.Design.Snackbar.Message"
        android:maxLines="@integer/design_snackbar_text_max_lines"
        android:layout_gravity="center_vertical|left|start"
        android:ellipsize="end"
        android:textAlignment="viewStart"/>

    <Button
        android:id="@+id/snackbar_action"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/design_snackbar_extra_spacing_horizontal"
        android:layout_marginStart="@dimen/design_snackbar_extra_spacing_horizontal"
        android:layout_gravity="center_vertical|right|end"
        android:minWidth="48dp"
        android:visibility="gone"
        android:textColor="?attr/colorAccent"
        style="?attr/borderlessButtonStyle"/>

</view>

发现里面控件相对于父控件属性为android:layout_gravity=”bottom”,所以显示在底部
发现button默认为隐藏掉的,只有设置setAction才会显示。
既然知道了布局文件及其id,就可以自定义其他属性,比如设置背景颜色之类的

        View snackbarView = snackbar.getView();
        ((Button) snackbarView.findViewById(R.id.snackbar_action)).setBackground(null);
        snackbarView.setBackgroundColor(Color.parseColor("#87CEFA"));

简单分析到此

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值