Material Design学习之 Bottom Sheets (顺便提提CoordinatorLayout)
来自: 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>