上一节我们定义了样式,现在我们开始进行类编写。首先我们知道整个BottomSheet是由一个个item组成的,而我们也是使用了recyclerview来显示出所有的item,所以我们先创建一个 BottomSheetItem.java
这里定义了一个接口,因为item的种类有很多,除了可点击传统的item以外,我们还有分隔符与标题,所以这个接口来使他们都统一的行为。只有一个函数用来返回item的title。
然后我们来实现传统的可点击的item,创建一个 BottomSheetMenuitem.java
很简单,一个图标,一个标题,一个id,和一个目录项,还有三个可能看起来比较奇怪的东西,但是看名字也明白是用来定义样式的,字体颜色,背景等等。对于整个BottomSheet,我们的处理是定义menu文件,然后在menu里读取一个个MenuItem,处理后作为我们的item。由于是在menu文件中编写,所以我们也只需要get函数,而不需要set函数了。
标题类型的item与分隔符的item非常简单,这里就不再说明。
BottomSheetHeader.javaclass BottomSheetHeader implements BottomSheetItem { private String mTitle; @ColorInt private int mTextColor; public BottomSheetHeader(String title, @ColorInt int color) { mTitle = title; mTextColor = color; } @ColorInt public int getTextColor() { return mTextColor; } @Override public String getTitle() { return mTitle; }}BottomSheetDivider.javaclass BottomSheetDivider implements BottomSheetItem { @DrawableRes private int mBackgroundDrawable; public BottomSheetDivider(@DrawableRes int background) { mBackgroundDrawable = background; } @DrawableRes public int getBackground() { return mBackgroundDrawable; } @Override public String getTitle() { return ""; }}这样的话,我们就定义完了所有类型的item类。
对于传统的可点击的item,我们定义一个接口来处理它的点击操作。
BottomSheetItemClickListener.javapublic interface BottomSheetItemClickListener { void onBottomSheetItemClick(MenuItem item);}这样的处理大家应该也非常熟悉。定义完了item接下来的动作就是在recyclerview里面建立item了,所以我们还需要编写一个适配器。
对于recyclerview中的适配器编写大家肯定已经非常熟悉了,这里需要注意的点无非是item类型的判断以及还需要知道BottomSheet是什么类型的。
BottomSheetItemAdapter.javaclass BottomSheetItemAdapter extends RecyclerView.Adapter<BottomSheetItemAdapter.ViewHolder> { public static final int TYPE_ITEM = 0; public static final int TYPE_HEADER = 1; public static final int TYPE_DIVIDER = 2; private List<BottomSheetItem> mItems; BottomSheetItemClickListener mListener; private int mMode; private int mItemWidth; public BottomSheetItemAdapter(List<BottomSheetItem> items, int mode, BottomSheetItemClickListener listener) { mMode = mode; mItems = items; mListener = listener; } public void setItemWidth(int width) { mItemWidth = width; } public void setListener(BottomSheetItemClickListener listener) { mListener = listener; } @Override public int getItemViewType(int position) { BottomSheetItem item = mItems.get(position); if (item instanceof BottomSheetMenuItem) { return TYPE_ITEM; } else if (item instanceof BottomSheetDivider) { return TYPE_DIVIDER; } else if (item instanceof BottomSheetHeader) { return TYPE_HEADER; } return super.getItemViewType(position); } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (mMode == BottomSheetBuilder.MODE_GRID) { View layout = LayoutInflater.from(parent.getContext()) .inflate(R.layout.bottomsheetbuilder_grid_adapter, parent, false); ViewGroup.LayoutParams layoutParams = layout.getLayoutParams(); layoutParams.width = mItemWidth; layout.setLayoutParams(layoutParams); return new ItemViewHolder(layout); } if (mMode == BottomSheetBuilder.MODE_LIST) { if (viewType == TYPE_HEADER) { return new HeaderViewHolder(LayoutInflater.from(parent.getContext()) .inflate(R.layout.bottomsheetbuilder_list_header, parent, false)); } if (viewType == TYPE_ITEM) { return new ItemViewHolder(LayoutInflater.from(parent.getContext()) .inflate(R.layout.bottomsheetbuilder_list_adapter, parent, false)); } if (viewType == TYPE_DIVIDER) { return new DividerViewHolder(LayoutInflater.from(parent.getContext()) .inflate(R.layout.bottomsheetbuilder_list_divider, parent, false)); } } return new ViewHolder(LayoutInflater.from(parent.getContext()) .inflate(R.layout.bottomsheetbuilder_list_adapter, parent, false)); } @Override public void onBindViewHolder(ViewHolder holder, int position) { BottomSheetItem item = mItems.get(position); if (mMode == BottomSheetBuilder.MODE_LIST) { if (holder.getItemViewType() == TYPE_ITEM) { ((ItemViewHolder) holder).setData((BottomSheetMenuItem) item); } else if (holder.getItemViewType() == TYPE_HEADER) { ((HeaderViewHolder) holder).setData((BottomSheetHeader) item); } else if (holder.getItemViewType() == TYPE_DIVIDER) { ((DividerViewHolder) holder).setData((BottomSheetDivider) item); } } else { ((ItemViewHolder) holder).setData((BottomSheetMenuItem) item); } } @Override public int getItemCount() { return mItems.size(); } public class ViewHolder extends RecyclerView.ViewHolder { public ViewHolder(View itemView) { super(itemView); } } public class DividerViewHolder extends ViewHolder { public View divider; public DividerViewHolder(View itemView) { super(itemView); divider = itemView; } public void setData(BottomSheetDivider item) { int background = item.getBackground(); if (background != 0) { divider.setBackgroundResource(background); } } } public class HeaderViewHolder extends ViewHolder { public TextView textView; public HeaderViewHolder(View itemView) { super(itemView); textView = (TextView) itemView.findViewById(R.id.textView); } public void setData(BottomSheetHeader item) { textView.setText(item.getTitle()); int color = item.getTextColor(); if (color != 0) { textView.setTextColor(color); } } } public class ItemViewHolder extends ViewHolder implements View.OnClickListener { public AppCompatImageView imageView; public TextView textView; public ItemViewHolder(View itemView) { super(itemView); itemView.setOnClickListener(this); imageView = (AppCompatImageView) itemView.findViewById(R.id.imageView); textView = (TextView) itemView.findViewById(R.id.textView); } public void setData(BottomSheetMenuItem item) { imageView.setImageDrawable(item.getIcon()); textView.setText(item.getTitle()); int color = item.getTextColor(); int background = item.getBackground(); if (color != 0) { textView.setTextColor(color); } if (background != 0) { itemView.setBackgroundResource(background); } } @Override public void onClick(View v) { BottomSheetMenuItem item = (BottomSheetMenuItem) mItems.get(getLayoutPosition()); if (mListener != null) { mListener.onBottomSheetItemClick(item.getMenuItem()); } } }}可以看到,首先我们定义三个常量来代表三种类型的item,并使用了一个mMode变量来得知BottomSheet的类型。对于item类型的判断,我们重载了 getItemViewType()
函数,来对于item 进行类型判断。并为不同的item类型构建了不同类型的ViewHolder,内部都定义了一个 setData()
函数来对于类进行赋值。对于传统的item我们还实现了 View.OnClickListener 来监听点击事件。
而在 onCreateViewHolder()
我们首先对BottomSheet的类型进行判断,这一步的主要原因是,在grid类型的BottomSheet中我们是没有标题与分隔符类型的item,所以可以少很多判断,并要加载相应的布局样式文件。在 onBindViewHolder()
的判断越是同理。
这样的话,我们就编写完了适配器。
前期的准备工作基本完成了,下面就可以开始来构建视图了。
新闻热点
疑难解答