android 新特性material design 之recyclerview 详解

来源:互联网 发布:皇室战争淘宝慢充原理 编辑:程序博客网 时间:2024/05/29 03:39

android 强势来袭,开发中出现了很多新的特性的类和控件,如recyclerview , cardview ,floatingactionbutton,coordinationlayout等等

其中toolbar就比actionbar强大多,toolbar就是谷歌用来取代actionbar的控件,也是一个容器,可以直接往里面设置控件

appbarlayout则是toolbar的一个辅助新控件,让toolbar为所欲为

这里就我个人分析了一个recyclerview控件的使用和一下功能,因为此控件太强的功能也很多需要慢慢发掘【微笑】

recyclerview 继承与viewgroup控件,能做到listview,gridview高级控件能做到的效果,同时实现了 瀑布流 的效果

耦合性很低的插件式控件,本身实现convertView 的重用,节省内存已经显示速度更快

使用recyclerview控件,需要到recyclerview包,包的位置,support-v7里面

recyclerview的显示方式主要份为三中

linearlayoutmanager:把recyclerview设置成linearlayout布局一样,也有linearlayoutmanager.vertical和horizontal水平和垂直方向

gridlayoutmanager:跟gridlayout布局很相似,也有vertical和horizontal两个方向的设置

staggeredGridlayoutmanager:就是实现瀑布流的布局

效果图:        

这里实现了侧滑所以与viewpager滑动冲突,这里我没有做修改了,所以要点击标题栏选择fragment

第一张图效果:实现的是recyclerview的跨列显示

/** * Created by yuantongqin on 2016/1/22. */public class GLLVSpanFragment extends Fragment implements Constant {    private GridLayoutManager llmv;    private Activity activity;    private List<ViewEntry> lists;    private LinearAdapter mAdapter;    @Nullable    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        activity = getActivity();        adddata();        View view = inflater.inflate(R.layout.fragment_main, container, false);        RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerview);        //context:上下文,spanCount:设置recyclerview几列 ,orientation:线性布局的方向, reverseLayout:数据反转        llmv = new GridLayoutManager(activity,3,GridLayoutManager.VERTICAL,false);        recyclerView.setLayoutManager(llmv);//        //传入recyclerview适配器数据        mAdapter = new LinearAdapter(activity,lists);        Log.i("test", "==gllvspan==" + lists.size());        //设置夸列显示---合并横向单元格        llmv.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {            @Override            public int getSpanSize(int position) {                //返回值:跨列数                int column = llmv.getSpanCount() -position % llmv.getSpanCount();                return  column;            }        });        //适配器的设置了        recyclerView.setAdapter(mAdapter);        RecyclerItemDecoration itemDecoration = new RecyclerItemDecoration(activity);        recyclerView.addItemDecoration(itemDecoration);        return view;    }    //添加数据    public void adddata(){        lists = new ArrayList<ViewEntry>();        for (int i=0;i<50;i++){            ViewEntry e = new ViewEntry();            e.setTitle("item"+i);            e.setImageuri(imageuris[i]);            lists.add(e);        }    }

用的setSpanSizeLookup 其中pisition的recyclerview的item下标,return的是一个item跨几列


第二张图片:使用的是Gridlayoutmanager同时设置列数

recyclerview没有向listview那样可以设置listview的divider分割线属性,也没有setdivider(drawable),setdividerHeght(int )方式

所以谷歌提供一个用于设置分割线的类Recyclerview.itemdecoration
 非常的好用,可以自己绘制,为所欲为.

callback类实现了item的移动,长按拖拽,效果很炫酷

/** * Created by yuantongqin on 2016/1/22. */public class GLVFragment extends Fragment implements Constant{    private List<ViewEntry> lists;    @Nullable    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        Activity activity = getActivity();        adddata();        View view = inflater.inflate(R.layout.fragment_main, container, false);        RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerview);        //context:上下文,spanCount:设置recyclerview几列 ,orientation:线性布局的方向, reverseLayout:数据反转        GridLayoutManager llmv = new GridLayoutManager(activity,3,GridLayoutManager.VERTICAL,false);        recyclerView.setLayoutManager(llmv);        LinearAdapter adapter = new LinearAdapter(activity,lists);        Log.i("test", "==gllvs==" + lists.size());                //给每一个item添加分割线 recyclerview没有像listview那样可以设置devider属性        RecyclerItemDecoration itemDecoration = new RecyclerItemDecoration(activity);        recyclerView.addItemDecoration(itemDecoration);        recyclerView.setAdapter(adapter);        //条目动作的具体实现        ItemTouchHelper.Callback callback  = new RecyclerItemTouchHelper(adapter);        //ItemTouchHelper 继承了recyclerview.itemdecoration 接受回调        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);        //itemtouchhelper依附与recyclerview 形成关联        itemTouchHelper.attachToRecyclerView(recyclerView);        return view;    }

第三张图片效果:瀑布流效果

staggeridgridlayoumanager跟gridlayoumanager的却别不大,这里就是需要你给每一个item设置高度

/** * Created by yuantongqin on 2016/1/22. */public class StaggeredFragment extends Fragment implements Constant{    private ArrayList<ViewEntry> lists;    @Nullable    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        Activity activity = getActivity();        adddata();        View view = inflater.inflate(R.layout.fragment_main, container, false);        RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerview);        //spanCount:设置recyclerview几列 ,orientation:线性布局的方向        //通过staggered 可以实现瀑布流的效果        StaggeredGridLayoutManager llmv = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);        recyclerView.setLayoutManager(llmv);        StaggerAdapter adapter = new StaggerAdapter(activity,lists);        Log.i("test", "==stagger==" + lists.size());        RecyclerItemDecoration itemDecoration = new RecyclerItemDecoration(activity);        recyclerView.addItemDecoration(itemDecoration);        recyclerView.setAdapter(adapter);        return view;    }    //添加数据    public void adddata(){        lists = new ArrayList<ViewEntry>();        for (int i=0;i<50;i++){            ViewEntry e = new ViewEntry();            e.setTitle("item" + i);            e.setImageuri(imageuris[i]);            e.setHeight(200+new Random().nextInt(100));            lists.add(e);        }    }

第四张效果图:

布局方式的linearlayoutmanager,itemdecoration实现item分割线,callback不仅仅有拖拽移动和设置了,类似QQ的侧滑删除效果

其中recyclerview.addonscrolllistener()监听recyclerview的滑动状态

以为这里使用到了imagerloader进行了图片的加载,在recyclerview滑动的时候停止图片的加载,

在recyclerview停止的时候,恢复图片的加载,这里不能用pauseonscrolllistener 因为它实现的是abslistview的onscrolllistener监听

/** * Created by yuantongqin on 2016/1/22. */public class LLVFragment extends Fragment implements Constant {    List<ViewEntry> lists;    @Nullable    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        Activity activity = getActivity();        adddata();        View view = inflater.inflate(R.layout.fragment_main, container, false);        RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerview);        //context:上下文,orientation:线性布局的方向, reverseLayout:数据反转        LinearLayoutManager llmv = new LinearLayoutManager(getActivity(),LinearLayoutManager.VERTICAL,false);        recyclerView.setLayoutManager(llmv);//设置recyclerview显示的方式        RecyclerItemDecoration docoration = new RecyclerItemDecoration(activity);        recyclerView.addItemDecoration(docoration);        LinearAdapter mAdapter = new LinearAdapter(activity,lists);        Log.i("test", "==lllvs==" + lists.size());        recyclerView.setAdapter(mAdapter);        //条目动作的具体实现        ItemTouchHelper.Callback callback = new RecyclerItemTouchHelper(mAdapter);        //ItemTouchHelper 继承了recyclerview.itemdecoration 接受回调        ItemTouchHelper itemTouchHelper  = new ItemTouchHelper(callback);        //itemtouchhelper依附与recyclerview 形成关联        itemTouchHelper.attachToRecyclerView(recyclerView);       recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {           @Override           public void onScrollStateChanged(RecyclerView recyclerView, int newState) {               switch (newState){                   case RecyclerView.SCROLL_STATE_IDLE://recyclerview 静止                       ImageLoader.getInstance().resume();                       break;                   case RecyclerView.SCROLL_STATE_DRAGGING:                       ImageLoader.getInstance().pause();                       break;               }               super.onScrollStateChanged(recyclerView, newState);           }       });        return view;    }


recyclerview使用的适配器为recyclerview.adapter

adapter 本身就实现了convertview的重用,其中适配器中的通知要比一般的适配器要强大得多

同时性能方面也会好很多:简单介绍

        //使用比较多//        notifyItemMoved(frompostiontoposition);从那一个位置移到那个位置//        notifyItemChanged(frompostiontoposition);在某个范围内改变//        notifyItemInserted(position);插入一条数据//        notifyItemRemoved();移除一条数据
他避免了适配器中整体的刷新,大大的优化了性能


/** * Created by yuantongqin on 2016/1/22. */public class LinearAdapter extends RecyclerView.Adapter<RecyclerViewHolder> implements ItemTouchHelperAdaperCallback{    private final List<ViewEntry> lists;    private final Context context;    private final LayoutInflater inflater;    public LinearAdapter(Context context,List<ViewEntry> lists){        this.context = context;        if(lists!= null && lists.size()>0){            this.lists = lists;        }else{            this.lists = new ArrayList<ViewEntry>();        }        inflater = LayoutInflater.from(context);    }    @Override    public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        View view = inflater.inflate(R.layout.item_main, parent, false);        RecyclerViewHolder holder = new RecyclerViewHolder(view);        //recyclerview自动实现了contextview的重用        return holder;    }    @Override    public void onBindViewHolder(RecyclerViewHolder holder, int position) {        holder.item_title.setText(lists.get(position).getTitle());        //加载图片进行图片的显示        ImageLoader.getInstance().displayImage(lists.get(position).getImageuri(),holder.item_image);    }    @Override    public int getItemCount() {        return lists.size();    }    //当条目发生移动的时候适配器中要进行位置更换    @Override    public boolean onItemMove(int fromPosition, int toPosition) {        //你移动的item从那个位置到那个位置去        Collections.swap(lists, fromPosition, toPosition);        notifyItemMoved(fromPosition, toPosition);        return false;    }    @Override    public boolean onItemDismiss(int position) {            // 侧滑删除 先删除list集合中的数据,然后通知适配器改变        lists.remove(position);        notifyItemRemoved(position);        return true;    }




demo的下载链接

http://download.csdn.net/detail/change987654321/9414686

apk的下载链接:

http://download.csdn.net/detail/change987654321/9414696







0 0
原创粉丝点击