Android 探索Bottom sheets的使用

作者: Angelicas | 来源:发表于2016-09-18 15:53 被阅读558次

    在Android Support Library 23.2版本推出之后,我们可以看到一些新的特性,例如AppCompat DayNight主题,BottomSheet等,其中BottomSheet控件用于从屏幕底部向上滑动,以显示更多的内容。本篇文章是想总结一下我在学习BottomSheet过程中的一些笔记以及一些需要注意的地方。此文章已经同步到CSDN啦,欢迎访问我的博客

    首先我们来看一下效果图


    这里写图片描述

    这个效果的实现很简单,甚至基本不需要java代码,我们只需要给这个可滑动的view添加BottomSheetBehavior 表现行为即可,把这个behavior指定为android.support.design.widget.BottomSheetBehavior就可以达到这种效果了,来看看代码吧

    <?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"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:orientation="vertical">
    
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="onClick1"
                android:text="方式一" />
    
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="onClick2"
                android:text="方式二" />
    
        </LinearLayout>
    
        <LinearLayout
            android:id="@+id/layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            android:background="#EFEFEF"
            app:layout_behavior="@string/bottom_sheet_behavior">
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:minHeight="30dp"
                android:text="选取方式"
                android:textColor="?attr/colorAccent" />
    
            <Button
                android:id="@+id/photo"
                style="@style/Widget.AppCompat.Button.Borderless.Colored"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:minHeight="48dp"
                android:text="照片"
                android:textColor="@android:color/darker_gray" />
    
            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="@android:color/darker_gray" />
    
            <Button
                android:id="@+id/camera"
                style="@style/Widget.AppCompat.Button.Borderless.Colored"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:minHeight="48dp"
                android:text="相机"
                android:textColor="@android:color/darker_gray" />
    
            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="@android:color/darker_gray" />
    
            <Button
                android:id="@+id/tv_dialog_cancel"
                style="@style/Widget.AppCompat.Button.Borderless.Colored"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:text="取消"
                android:textColor="?attr/colorAccent" />
        </LinearLayout>
    
        <android.support.design.widget.FloatingActionButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/fab_margin"
            android:onClick="fab"
            android:src="@android:drawable/ic_dialog_email"
            app:layout_anchor="@id/layout"
            app:layout_anchorGravity="right|top"
            app:pressedTranslationZ="10dp" />
    
    </android.support.design.widget.CoordinatorLayout>
    

    看到LinearLayout的behavior了吧,在这里我们添加BottomSheetBehavior表现行为而已,其他的地方没有任何特殊的。LinearLayout里面的布局,至于定义成什么样就看你自己想怎么写啦。
    虽说我们可以不需要任何java代码就可以实现,不过这里我们还是希望可以通过按钮去控制它的一个显示情况:

     public void fab(View view) {
            BottomSheetBehavior behavior = BottomSheetBehavior.from(findViewById(R.id.layout));
            if (behavior.getState() == BottomSheetBehavior.STATE_EXPANDED) {
                behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
            } else {
                behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
            }
        }
    

    代码也很简单,首先我们通过BottomSheetBehavior.from()方法来获取到它的Behavior,然后通过getState方法来判断现在的状态,如果是展开的状态,我们就让它收缩起来;反之,则展开。
    其中BottomSheet 有这么几种状态:

    • STATE_COLLAPSED :被折叠的状态
    • STATE_SETTING :沉降,我的理解是视图从脱离手指自由滑动到最终停下的这一小段时间
    • STATE_EXPANDED :完全展开的状态
    • STATE_HIDDEN :被隐藏的状态,默认是false,可通过app:behavior_hideable属性设置
    • STATE_DRAGGING :被拖拽的状态

    Support Library 23.2中还提供了BottomSheetDialog和BottomSheetDialogFragment。BottomSheetDialog的用法与普通的dialog差不多,显示的内容可以是列表,也可以是简单的对话,当显示的内容一滑入屏幕时,屏幕的其余部分会变暗,以衬托Dialog重点。下面看下BottomSheetDialog的简单使用:

     BottomSheetDialog dialog = new BottomSheetDialog(this);
            dialog.setContentView(R.layout.dialog_layout);
            dialog.show();
    

    下面我们使用BottomSheetDialog结合RecyclerView来显示一个含有一个列表的dialog,效果图如下:


    这里写图片描述

    使用BottomSheetDialog的话,当我们点击按钮显示的时候,它只会先出现一部分,我们拖动它的时候,它会占满屏幕,现在我们就来看一下代码

    package per.lijuan.bottomsheetdome;
    
    import android.os.Bundle;
    import android.support.annotation.NonNull;
    import android.support.design.widget.BottomSheetBehavior;
    import android.support.design.widget.BottomSheetDialog;
    import android.support.v4.view.ViewCompat;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.DefaultItemAnimator;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.widget.Toast;
    
    public class MainActivity extends AppCompatActivity {
        public BottomSheetBehavior behavior;
        public RecyclerView recyclerView;
        public MyAdapter adapter;
        private BottomSheetDialog dialog;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
        }
    
        private void initView() {
            recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
            recyclerView.setItemAnimator(new DefaultItemAnimator());
            recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext()));
    
            adapter = new MyAdapter();
            adapter.setItemClickListener(new onItemClickListener(2));
            recyclerView.setAdapter(adapter);
            recyclerView.setVisibility(View.GONE);
    
            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.STATE_HIDDEN) {
                        recyclerView.setVisibility(View.GONE);
                    }
                }
    
                @Override
                public void onSlide(@NonNull View bottomSheet, float slideOffset) {
                    recyclerView.setVisibility(View.VISIBLE);
                    ViewCompat.setAlpha(recyclerView, slideOffset);
                }
            });
        }
    
        public void fab(View view) {
            BottomSheetBehavior behavior = BottomSheetBehavior.from(findViewById(R.id.layout));
            if (behavior.getState() == BottomSheetBehavior.STATE_EXPANDED) {
                behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
            } else {
                behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
            }
        }
    
        public void onClick1(View view) {
            if (behavior.getState() == behavior.STATE_EXPANDED) {
                behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
            } else {
                behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
            }
        }
    
        public void onClick2(View view) {
            RecyclerView recyclerView = (RecyclerView) LayoutInflater.from(this)
                    .inflate(R.layout.list, null);
            recyclerView.setItemAnimator(new DefaultItemAnimator());
            recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
            MyAdapter adapter = new MyAdapter();
            recyclerView.setAdapter(adapter);
    
            dialog = new BottomSheetDialog(this);
            dialog.setContentView(recyclerView);
            dialog.show();
            adapter.setItemClickListener(new onItemClickListener(3));
        }
    
        public class onItemClickListener implements MyAdapter.ItemClickListener {
            private int index;
    
            public onItemClickListener(int index) {
                this.index = index;
            }
    
            @Override
            public void onItemClick(int position) {
                Toast.makeText(MainActivity.this, "您点击了item" + position, Toast.LENGTH_LONG).show();
                if (index == 2) {
                    behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
                } else if (index == 3) {
                    dialog.dismiss();
                }
            }
        }
    }
    
    

    MyAdapter.class

    package per.lijuan.bottomsheetdome;
    
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    /**
     * 适配器
     * Created by lijuan on 2016/9/7.
     */
    public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false));
        }
    
        @Override
        public void onBindViewHolder(final ViewHolder holder, final int position) {
            holder.mTextView.setText("item");
            holder.mTextView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mItemClickListener.onItemClick(position);
                }
            });
        }
    
        @Override
        public int getItemCount() {
            return 8;
        }
    
        class ViewHolder extends RecyclerView.ViewHolder {
    
            public TextView mTextView;
    
            public ViewHolder(View view) {
                super(view);
                mTextView = (TextView) view.findViewById(R.id.textview);
            }
        }
    
        public interface ItemClickListener {
            void onItemClick(int position);
        }
    
        public ItemClickListener mItemClickListener;
    
        public void setItemClickListener(ItemClickListener listener) {
            mItemClickListener = listener;
        }
    }
    

    list.xml

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white"/>
    

    list_item.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white"
        android:orientation="vertical">
    
        <TextView
            android:id="@+id/textview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:background="@android:color/white"
            android:gravity="center"
            android:text="Item"
            android:textSize="20sp" />
    
        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="@android:color/darker_gray" />
    </LinearLayout>
    
    

    好了,本篇文章就这样子啦,存在总结不到位的地方还望指导,感谢_

    参考资料:https://material.google.com/components/bottom-sheets.html#

    源码下载

    相关文章

      网友评论

        本文标题:Android 探索Bottom sheets的使用

        本文链接:https://www.haomeiwen.com/subject/hfcgettx.html