Material Design学习之 Bottom Sheets (顺便提提CoordinatorLayout)

转载请注明出处:王亟亟的大牛之路

昨天连续上了2篇介绍第三方库的文章,正直好久没提交自己写东西了,那么就补一篇之前MD系列漏的部分 Bottom Sheets



Bottom Sheets–底部动作条

底部动作条(Bottom Sheets)是一个从屏幕底部边缘向上滑出的一个面板,使用这种方式向用户呈现一组功能。底部动作条呈现了简单、清晰、无需额外解释的一组操作。

在一个标准的列表样式的底部动作条(Bottom Sheets)中,每一个操作应该有一句描述和一个左对齐的 icon。如果需要的话,也可以使用分隔符对这些操作进行逻辑分组,也可以为分组添加标题或者副标题。

像这样:

请记得遵循MD严谨的设计规则,统一编剧,字体等尺寸规范,像这样

上面那种是类似于ListView的呈现,要变成类似于GridView的样子也行,像这样

原文地址:http://www.google.com/design/spec/components/bottom-sheets.html



CoordinatorLayout (不知道怎么称呼,泪目。。)

CoordinatorLayout实现了多种Material Design中提到的滚动效果(传送门:http://www.google.com/design/spec/patterns/scrolling-techniques.html)
打不开的话我就简单描述下,就是手势上下滑动的一些操作,像这样

只要使用CoordinatorLayout作为基本布局,将自动产生向上移动的动画。

也就是这样

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="sample.wjj.materialdesignbottomsheets.MainActivity">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <Button
            android:id="@+id/byRecycleView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:background="#c2cc"
            android:text="RecycleView方式"
            android:textColor="@android:color/white" />
    </RelativeLayout>

    <ImageView
        android:src="@drawable/flash"
        android:id="@+id/fillView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></ImageView>

    <android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#fff"
        app:behavior_hideable="false"
        app:behavior_peekHeight="10dp"
        app:layout_behavior="@string/bottom_sheet_behavior" />
</android.support.design.widget.CoordinatorLayout>

更多介绍可以看:http://blog.csdn.net/xyz_lmn/article/details/48055919

接下来我们来看今天的例子

先上下效果图

这里把最上方的2种样式分别实现了一下(无视具体item 还是请跟着规范走)

这样的实现以前用PopupWindow我也写过一篇,效果大致差不多不过,Popup那一系列方法都得自己重写,还是比较麻烦的,这里也补下传送门:http://blog.csdn.net/ddwhan0123/article/details/50379340

OK,那我们来看下如何实现的

包结构

如果你不需要RecycleView的分割线的话就Copy走MainActivity内的内容即可DividerItemDecoration这个类是翔哥之前写的分割线

直接贴代码,然后在 // 里做解释

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    public static List<String> mDatas;
    public Button byRecycleView;
    public BottomSheetBehavior behavior;
    public RecyclerView recyclerView;
    public View fillView;
    public WjjAdapter wjjAdapter;                                                                     

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化,业务逻辑
        init();                                                                                       

    }
    //绿色的按钮,触发隐藏和显示RecycleView    

    //Bottom Sheet 一共有五个状态回调:
    //STATE_COLLAPSED
    //折叠状态。可通过app:behavior_peekHeight来设置默认显示的高度。

    //STATE_SETTING
    //拖拽松开之后到达终点位置(collapsed or expanded)前的状态。

    //STATE_EXPANDED
    //完全展开的状态。

    //STATE_HIDDEN
    //隐藏状态。默认是false,可通过app:behavior_hideable属性设置。

    //STATE_DRAGGING
    //被拖拽状态  

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.byRecycleView:                                                                  

               //展开控件 behavior.setState(BottomSheetBehavior.STATE_EXPANDED);                                

                break;
        }                                                                                             

    }                                                                                                 

    private void init() {                                                                             

        initData();                                                                                   

        byRecycleView = (Button) findViewById(R.id.byRecycleView);
        byRecycleView.setOnClickListener(this);                                                       

        recyclerView = (RecyclerView) findViewById(R.id.recyclerview);                                

        //添加分割线
//        recyclerView.addItemDecoration(new DividerItemDecoration(this,
//                DividerItemDecoration.VERTICAL_LIST));                                              

        //设置ListView模式
        recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext()));
//设置GridView模式
//recyclerView.setLayoutManager(new GridLayoutManager(this, 3));                               

        //初始化适配器
        wjjAdapter = new WjjAdapter(this);
        //设置监听事件
        wjjAdapter.setItemClickListener(new WjjAdapter.ItemClickListener() {
            @Override
            public void onItemClick(int pos) {
//当被点击后隐藏控件                behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
//土司被点击的Item的位置
                Toast.makeText(MainActivity.this, "--->" + pos, Toast.LENGTH_LONG).show();
            }
        });
        //设置适配器
        recyclerView.setAdapter(wjjAdapter);
        //设置动画
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        //这句很重要,绑定滑动操作内容给 recyclerView
        behavior = BottomSheetBehavior.from(recyclerView);
        //设置滑动回调
        behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
        //状态变化时触发
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
                if (newState == BottomSheetBehavior.STATE_COLLAPSED || newState == BottomSheetBehavior
//blackView.setBackgroundColor(Color.TRANSPARENT);
                    fillView.setVisibility(View.GONE);
                }
            }                                                                                         

            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {
                // 手势滑动时
                fillView.setVisibility(View.VISIBLE);
                ViewCompat.setAlpha(fillView, slideOffset);
            }
        });
         //显示RecycleView时才呈现的“树懒--闪电”
        fillView = findViewById(R.id.fillView);
        fillView.setBackgroundColor(getResources().getColor(R.color.white));
        fillView.setVisibility(View.GONE);
        fillView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            //点击闪电时也隐藏掉ReclcyeView
                behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);                               

            }
        });                                                                                           

    }
     //填充数据
    public void initData() {
        mDatas = new ArrayList<>();
        for (int k = 0; k < 6; k++) {
            mDatas.add("第" + k + "个");
        }
    }                                                                                                 

    //下面就是 Adapter的内容了,就不做解释了
    public static class WjjAdapter
            extends RecyclerView.Adapter<WjjAdapter.ViewHolder> {                                     

        public ItemClickListener mItemClickListener;                                                  

        public void setItemClickListener(ItemClickListener listener) {
            mItemClickListener = listener;
        }                                                                                             

        public interface ItemClickListener {
            void onItemClick(int pos);
        }                                                                                             

        private Context mContext;                                                                     

        public static class ViewHolder extends RecyclerView.ViewHolder {                              

            public final TextView mTextView;                                                          

            public ViewHolder(View view) {                                                            

                super(view);
                mTextView = (TextView) view.findViewById(R.id.tv);                                    

            }                                                                                         

        }                                                                                             

        public WjjAdapter(Context context) {                                                          

            super();
            mContext = context;                                                                       

        }                                                                                             

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {                        

            ViewHolder holder = new ViewHolder(LayoutInflater.from(
                    parent.getContext()).inflate(R.layout.list_item, parent,
                    false));
            return holder;                                                                            

        }                                                                                             

        @Override
        public void onBindViewHolder(final ViewHolder holder, final int position) {                   

            holder.mTextView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {                                                         

                    mItemClickListener.onItemClick(position);
                }
            });                                                                                       

            holder.mTextView.setText(mDatas.get(position));
        }                                                                                             

        @Override
        public int getItemCount() {
            return mDatas.size();
        }
    }                                                                                                 

}

整体使用起来不复杂,而且拓展性好。只是对版本有一定的要求,至少21+的才可以作为.from()的寄存对象

源码地址:https://github.com/ddwhan0123/BlogSample/blob/master/MaterialDesignBottomSheets.zip

时间: 2024-10-21 11:33:17

Material Design学习之 Bottom Sheets (顺便提提CoordinatorLayout)的相关文章

Material Design学习之 Button(详细分析,传说中的水滴动画)

转载请注明出处:王亟亟的大牛之路       上一篇大致介绍了Material Design的一些基本概念传送门:http://blog.csdn.net/ddwhan0123/article/details/50541561 这一片来具体学习下里面的内容,这篇分为两部分一部分是原理分析,一部分是代码分析. 先简要的介绍一些理论知识,顺便温顾下基础知识 按钮 按钮由文字和/或图标组成,文字及图标必须能让人轻易地和点击后展示的内容联系起来. 主要的按钮有三种: 悬浮响应按钮(Floating ac

Material Design学习之 EditText (功能强大,优于系统自带,感谢“扔物线”)

转载请注明出处:王亟亟的大牛之路 继续之前的Material Design历程,今天是EditText,素材来源于http://www.rengwuxian.com/post/materialedittext(那么代码解释部分大家可以看原作者的文档,我在这里把理论知识灌输下就OK了,作者做的很全面,我都不知道要讲什么了 只能6666666) 大牛的这个库已经有了广泛的认知度和认可,EditText部分就拿他的作为比较推崇的演示版本. 因为大牛已经做了Jar包的支持,所以平时的拆的工作都省了,要直

Material Design学习之 Snackbars(详细分析,Toast的加强版)

转载请注明出处:王亟亟的大牛之路 昨天把Material Design Button部分的内容分析完了,不知道大家理解了他的实现没有.如果没看的话,可以看下,传送门:http://blog.csdn.net/ddwhan0123/article/details/50555958 这几篇关于Material Design文章的代码几乎都是Git上摘录的,我做的事主要是分享给大家+解释分析. 昨天有小伙伴看完后希望我像以前一样把按钮那一部分的代码单独提取出来单独打成一个包,想单独使用或者学习而不是去

Material Design学习之 CheckBox(详细分析,富有表现力)

转载请注明出处:王亟亟的大牛之路 这些天一直在讲Material Design控件的内容,今天继续,说说CheckBox(妈蛋,好冷),上一篇的传送门:http://blog.csdn.net/ddwhan0123/article/details/50560638 老规矩,两部分,第一部分理论知识,第二部分代码 选择控制器 选择控制器允许用户选择选项.有三种类型:复选框.单选框以及开/关切换.选择控制器使用主题同样的颜色.(待会的代码主要讲的是单选按钮) 复选框 单选按钮 切换开关 官方对呈现的

Material Design学习之 Switch(详细解释)

转载请注明出处:王亟亟的大牛之路 继续这一系列的Material Design之行,昨天讲的是Sliders链接如下:http://blog.csdn.net/ddwhan0123/article/details/50586510 今天讲的是Switch,本来有考虑把它和CheckBox一起做了,但是毕竟实现不同,还是分开做吧,废话不多,开始正题 开关 On/off 开关切换单一设置选择的状态.开关控制的选项以及它的状态,应该明确的展示出来并且与内部的标签相一致.开关应该单选按钮呈现相同的视觉特

Material Design学习之 Camera

转载请注明出处:王亟亟的大牛之路 年后第一篇,自从来了某司产量骤减,这里批评下自己,这一篇的素材来源于老牌Material Design控件写手afollestad的 https://github.com/afollestad/material-camera 开篇前,继续安利,你懂的:https://github.com/ddwhan0123/Useful-Open-Source-Android (最近把 6.0授权部分单独罗列出来了) 介绍代码之前先贴下效果图 如何使用 先是添加依赖让mave

Material Design学习之 ProgreesBar

转载奇怪注明出处:王亟亟的大牛之路 继续我们Material Design的内容,这一篇讲的是进度条,上一篇是Switch地址如下:http://blog.csdn.net/ddwhan0123/article/details/50592579 进度和动态 在用户可以查看并与内容进行交互之前,尽可能地减少视觉上的变化,尽量使应用加载过程令人愉快.每次操作只能由一个活动指示器呈现,例如,对于刷新操作,你不能即用刷新条,又用动态圆圈来指示. 指示器类型 在操作中,对于完成部分可以确定的情况下,使用确

Material Design学习之 Sliders(详细分析,悬空气球显示进度值,附带Eclipse可以jar)

转载请注明出处:王亟亟的大牛之路 Material Design系列的文章这是第五篇,今天讲滑块控件(Sliders). 之前的传送门:http://blog.csdn.net/ddwhan0123/article/details/50578348(代码实现都靠画,学好View还是很重要的) 老规矩,先说下理论部分 滑块控件(Sliders,简称滑块)可以让我们通过在连续或间断的区间内滑动锚点来选择一个合适的数值.区间最小值放在左边,对应的,最大值放在右边.滑块(Sliders)可以在滑动条的左

Material Design学习之 Dialog(顺便把前两天AppBarLayout没讲的部分提一提)

转载请注明出处:王亟亟的大牛之路 继续之前的MD系列的内容,今天说Dialog,不知道还能翻几篇,反正这一系列都说完了话就找点别的内容整整. Dialogs (提示框)用于提示用户作一些决定,或者是完成某个任务时需要的一些其它额外的信息. Dialog可以是用一种 取消/确定 的简单应答模式,也可以是自定义布局的复杂模式,比如说一些文本设置或者是文本输入 . 官方的呈现,像这样 Dialog 包含了一个标题(可选),内容 ,事件. 标题:主要是用于简单描述下选择类型.它是可选的,要需要的时候赋值