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

Houston1756 8年前

来自: http://android.jobbole.com/82560/

昨天连续上了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作为基本布局,将自动产生向上移动的动画。

也就是这样

Java

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>
android.support.design.widget.CoordinatorLayoutxmlns: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.RecyclerViewxmlns: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>
</div>

更多介绍可以看: 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这个类是 翔哥 之前写的分割线

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

Java

public class MainActivity extends AppCompatActivity implements View.OnClickListener {                       public static List 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 {                                                 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();                                                                               }                                                                                                   }                                                                                                     }
public class MainActivityextends AppCompatActivityimplements View.OnClickListener {                      public static ListmDatas;                                                                      public ButtonbyRecycleView;                                                                            public BottomSheetBehaviorbehavior;                                                                    public RecyclerViewrecyclerView;                                                                      public ViewfillView;                                                                                  public WjjAdapterwjjAdapter;                                                                             @Override                                                                                              protected void onCreate(BundlesavedInstanceState) {                                                        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 ViewbottomSheet, int newState) {                                      if (newState == BottomSheetBehavior.STATE_COLLAPSED || newState == BottomSheetBehavior  //blackView.setBackgroundColor(Color.TRANSPARENT);                                                      fillView.setVisibility(View.GONE);                                                                  }                                                                                                  }                                                                                                         @Override                                                                                              public void onSlide(@NonNull ViewbottomSheet, 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 {                                                 public ItemClickListenermItemClickListener;                                                               public void setItemClickListener(ItemClickListenerlistener) {                                              mItemClickListener = listener;                                                                      }                                                                                                         public interface ItemClickListener {                                                                        void onItemClick(int pos);                                                                          }                                                                                                         private ContextmContext;                                                                                 public static class ViewHolderextends RecyclerView.ViewHolder {                                               public final TextViewmTextView;                                                                           public ViewHolder(Viewview) {                                                                                 super(view);                                                                                            mTextView = (TextView) view.findViewById(R.id.tv);                                                     }                                                                                                     }                                                                                                         public WjjAdapter(Contextcontext) {                                                                           super();                                                                                                mContext = context;                                                                                   }                                                                                                         @Override                                                                                              public ViewHolderonCreateViewHolder(ViewGroupparent, int viewType) {                                         ViewHolderholder = new ViewHolder(LayoutInflater.from(                                                        parent.getContext()).inflate(R.layout.list_item, parent,                                                false));                                                                                        return holder;                                                                                         }                                                                                                         @Override                                                                                              public void onBindViewHolder(final ViewHolderholder, 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();                                                                              }                                                                                                  }                                                                                                     }
</div>

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

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

</div>