本文主要介绍以下三个Android支持库控件的配合使用:html
对于支持库的使用,这里稍做介绍:
Android支持库包含经常使用的v四、v七、v13以及v17,注解支持(annotation),设计支持(material design)等。
目前v4和v7已经根据不一样的功能进行了拆分,以减少目标Apk的大小,可针对某项具体的功能引入特定的包,而不用总体引入support-v4
包。
好比,如下为笔者经常使用的支持库,读者能够参考:android
// 实现各类 UI 相关组件,例如 ViewPager、NestedScrollView 和 ExploreByTouchHelper。 supportCoreUi : 'com.android.support:support-core-ui:24.2.0', // 添加对使用片断封装用户界面和功能的支持,从而使应用可以提供能够在大屏幕设备与小屏幕设备之间进行调节的布局。 // 此模块依赖于 compat、core-utils、core-ui 和 media-compat。 supportFragment : 'com.android.support:support-fragment:24.2.0', // 此库添加了对操做栏用户界面设计模式的支持。此库包含对 Material Design 用户界面实现的支持。 supportAppCompat : 'com.android.support:appcompat-v7:24.2.0', // recyclerview 库添加了 RecyclerView 类。此类可以为 RecyclerView 小部件提供支持, // RecyclerView 是一种经过提供有限的数据项窗口有效显示大数据集的视图。 supportRecyclerView : 'com.android.support:recyclerview-v7:24.2.0', // 此库添加了对 CardView 小部件的支持,让您可以在卡片内显示信息,从而使应用具有一致的外观。 supportCardView : 'com.android.support:cardview-v7:24.2.0', // 注解软件包提供的 API 支持向应用中添加注解元数据。 supportAnnotations : 'com.android.support:support-annotations:24.2.0', // 设计软件包提供的 API 支持向应用中添加 Material Design 组件和模式。 supportDesign : 'com.android.support:design:24.2.0',
最后,须要注意,支持库的版本须要保持一致,否则容易出现编译错误。
更多关于支持库的使用,请参考官方文档。设计模式
先上效果图:app
(左滑的比较慢,是为了看清效果)ide
TabLayout是design支持库中引入的支持Tab页的控件,配合ViewPager使用,实现Table页面的滑动。使用时:布局
setTabMode(TabLayout.MODE_FIXED)
来设置TabLayout的模式;addTab
来添加Tab页面;setupWithViewPager
来关联ViewPager.// 设置TabLayout的模式 goodsTypeTl.setTabMode(TabLayout.MODE_FIXED); // 添加Fragment显示 for (int i = 0; i < 2; i++) { PickingTaskGoodsFragment itemFragment = PickingTaskGoodsFragment.newInstance( i == 0 ? unCompletedPickingSku : pickingCompletedSku); fragmentList.add(itemFragment); goodsTypeTl.addTab(goodsTypeTl.newTab().setText(titleList.get(i))); } // 实例化ViewPage的适配器 FragmentPagerAdapter fAdapter = new PickingFragmentPagerAdapter( getSupportFragmentManager(), fragmentList, titleList); // viewpager加载adapter goodsDetailVp.setAdapter(fAdapter); // TabLayout加载viewpager goodsTypeTl.setupWithViewPager(goodsDetailVp);
ViewPager是在v4包中引入的控件,在布局文件中,紧接着TabLayout
进行布局。ViewPager继承自ViewGroup,在使用时,最关键的是为其添加PagerAdapter,通常ViewPage会包含Fragment,那么这里PagerAdapter会使用FragmentPagerAdapter:大数据
public abstract class FragmentPagerAdapter extends PagerAdapter
FragmentPagerAdapter是一个抽象类,在使用时通常继承自FragmentPagerAdapter自定义实现:ui
public class PickingFragmentPagerAdapter extends FragmentPagerAdapter { private List<Fragment> fragmentList; private List<String> titleList; public PickingFragmentPagerAdapter(FragmentManager fm, List<Fragment> fragmentList, List<String> titleList) { super(fm); this.fragmentList = fragmentList; this.titleList = titleList; } @Override public Fragment getItem(int position) { return fragmentList.get(position); } @Override public int getCount() { return titleList.size(); } @Override public CharSequence getPageTitle(int position) { return titleList.get(position); } }
getItem和getCount方法必需要求实现,分别返回List<Fragment>
的内容就好了。this
在实例化PickingFragmentPagerAdapter时,须要传入FragmentManager,通常采用getSupportFragmentManager()。spa
RecyclerView是v7支持库中引入的控件,使用时须要依赖com.android.support:recyclerview-v7:22.2.1
,使用RecyclerView须要注意两点:
recyclerView.setLayoutManager(new LinearLayoutManager(context));
固然,这里还能够设置GridLayoutManager
。
recyclerView.setAdapter(new PickingTaskGoodsAdapter(pickingTaskDParams, mListener));
RecyclerView的Adapter是须要重点关注的。其中,须要实现的方法有三个:onCreateViewHolder
、onBindViewHolder
和getItemCount
。
View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.out_picking_goods_detail_item, parent, false); return new ViewHolder(view, new MySkuItemData());
View是直接经过Inflater提取出来的(注意item的根ViewGroup的height不能设置为match parent,否则多行item没法正常显示),ViewHolder的入参须要传入View。ViewHolder的定义有点讲究,与ListView中有不一致:
public class ViewHolder extends RecyclerView.ViewHolder { final View mView; AutofitTextView goodsNumberTv; TextView goodsNameTv; TextView goodsLeftNumberTv; ImageView skuState; Button pickingSku; ViewHolder(View view) { super(view); mView = view; goodsNumberTv = (AutofitTextView) view.findViewById(R.id.out_picking_task_goods_number_tv); goodsNameTv = (TextView) view.findViewById(R.id.out_picking_task_goods_name_tv); goodsLeftNumberTv = (TextView) view.findViewById(R.id.out_picking_task_goods_left_number_tv); skuState = (ImageView) view.findViewById(R.id.out_picking_task_goods_sku_state_iv); pickingSku = (Button) view.findViewById(R.id.out_picking_task_goods_picking_btn); } }
首先,须要定义一个带参构造器,第一个参数必定是View,ViewHolder也须要包含View的域,另外,ViewHolder能够包含各个View的监听器,而这种监听器通常都须要自定义,由于其中会包含重要的参数。
ViewHolder holder, int position
,所以,首先经过position获取数据,而后对ViewHolder的控件依次设置:@Override public void onBindViewHolder(ViewHolder holder, int position) { PickingTaskDParam dParam = taskDParamList.get(position); holder.goodsNumberTv.setText(dParam.getSkuNo()); holder.goodsNameTv.setText(dParam.getSkuName()); holder.goodsLeftNumberTv.setText(String.valueOf(dParam.getPlannedPickQty().intValue())); if (dParam.getOptStatus() == 1 || dParam.getOptStatus() == 2) { // 大小设置 holder.pickingSku.setVisibility(View.GONE); holder.skuState.setVisibility(View.VISIBLE); } else { holder.skuState.setVisibility(View.GONE); if (pickingVisible) { holder.pickingSku.setVisibility(View.VISIBLE); holder.pickingSku.setOnClickListener(new MyItemOnClickListener(dParam)); } else { holder.pickingSku.setVisibility(View.GONE); } } }
RecyclerView添加分割:分为设置垂直方向距离和设置分隔条两种方式:
垂直方向距离:
public class VerticalSpaceItemDecoration extends RecyclerView.ItemDecoration { private final int verticalSpaceHeight; public VerticalSpaceItemDecoration(int verticalSpaceHeight) { this.verticalSpaceHeight = verticalSpaceHeight; } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { outRect.bottom = verticalSpaceHeight; } }
分隔条:
public class DividerItemDecoration extends RecyclerView.ItemDecoration { private static final int[] ATTRS = new int[]{android.R.attr.listDivider}; private Drawable divider; /** * Default divider will be used */ public DividerItemDecoration(Context context) { final TypedArray styledAttributes = context.obtainStyledAttributes(ATTRS); divider = styledAttributes.getDrawable(0); styledAttributes.recycle(); } /** * Custom divider will be used */ public DividerItemDecoration(Context context, int resId) { divider = ContextCompat.getDrawable(context, resId); } @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { int left = parent.getPaddingLeft(); int right = parent.getWidth() - parent.getPaddingRight(); int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { View child = parent.getChildAt(i); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); int top = child.getBottom() + params.bottomMargin; int bottom = top + divider.getIntrinsicHeight(); divider.setBounds(left, top, right, bottom); divider.draw(c); } } }
以上关于分隔条内容可参考Stack Overflow:How to add dividers and spaces between items in RecyclerView?
最后,复习下Fragment和Activity的数据传递:
public static PickingTaskGoodsFragment newInstance(List<PickingTaskDParam> pickingTaskDParams) { PickingTaskGoodsFragment fragment = new PickingTaskGoodsFragment(); Bundle args = new Bundle(); args.putParcelable(PICKING_TASK_D_PARAM, Parcels.wrap(pickingTaskDParams)); fragment.setArguments(args); return fragment; }
@Override public void onAttach(Context context) { super.onAttach(context); if (context instanceof OnListFragmentInteractionListener) { mListener = (OnListFragmentInteractionListener) context; } else { throw new RuntimeException(context.toString() + " must implement OnListFragmentInteractionListener"); } } @Override public void onDetach() { super.onDetach(); mListener = null; } public interface OnListFragmentInteractionListener { void onListFragmentInteraction(PickingTaskDParam item); }
以上。