转载 http://blog.csdn.net/lmj623565791/article/details/45059587;
本文出自:【张鸿洋的博客】
概述
RecyclerView出现已经有一段时间了,相信大家肯定不陌生了,大家可以通过导入support-v7对其进行使用。
据官方的介绍,该控件用于在有限的窗口中展示大量数据集,其实这样功能的控件我们并不陌生,例如:ListView、GridView。
那么有了ListView、GridView为什么还需要RecyclerView这样的控件呢?整体上看RecyclerView架构,提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManager,ItemDecoration , ItemAnimator实现令人瞠目的效果。
- 你想要控制其显示的方式,请通过布局管理器LayoutManager
- 你想要控制Item间的间隔(可绘制),请通过ItemDecoration
- 你想要控制Item增删的动画,请通过ItemAnimator
- 你想要控制点击、长按事件,请自己写(擦,这点尼玛。
和普通的ListView的适配器不同,要自己实现RecycleView.Adapter<ViewHolder>
基本使用
鉴于我们对于ListView的使用特别的熟悉,对比下RecyclerView的使用代码:
mRecyclerView = findView(R.id.id_recyclerview); //设置布局管理器 mRecyclerView.setLayoutManager(layout); //设置adapter mRecyclerView.setAdapter(adapter) //设置Item增加、移除动画 mRecyclerView.setItemAnimator(new DefaultItemAnimator()); //添加分割线 mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.HORIZONTAL_LIST));
操作的步骤:
1.基本和常见的控件一样,可以对比ListView的事件去写,现在先去操作写作的步骤,实现公司项目中类似的左右可以拖动的效果,并且实现可以点击的事件,
直接看代码:
先上MainActivity的布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/backgroud_white"> <android.support.v7.widget.RecyclerView android:id="@+id/id_recyclerview" android:layout_width="match_parent" android:layout_height="86dp"/> </RelativeLayout>
这里限制了整个RecycleView的高度仅仅为86dp
再去写适配器:
直接上代码:
package com.fightzhao.recyclerdemo.ui.adapter; import android.content.Context; import android.graphics.Paint; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.fightzhao.recyclerdemo.R; import com.fightzhao.recyclerdemo.dao.Product; import com.fightzhao.recyclerdemo.utils.Units; import com.fightzhao.recyclerdemo.utils.ViewUtils; import java.util.ArrayList; import java.util.List; /** * Created by fightzhao on 15-9-29. */ public class ProductRecyclerAdapter extends RecyclerView.Adapter<ProductRecyclerAdapter.ViewHolder> { private final List<Product> data; private Context context; private OnItemClickLitener onItemClickLitener; // 点击事件的接口设置 public interface OnItemClickLitener { void onItemClick(View view, int position); void onItemLongClick(View view, int position); } public void setOnItemClickLitener(OnItemClickLitener mOnItemClickLitener) { this.onItemClickLitener = mOnItemClickLitener; } public ProductRecyclerAdapter(Context context, List<Product> data) { this.context = context; this.data = data == null ? new ArrayList<Product>() : new ArrayList<Product>(data); } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { ViewHolder holder = new ViewHolder(LayoutInflater.from(context).inflate(R.layout.item_product_grid, parent,false)); return holder; } @Override public void onBindViewHolder(final ViewHolder holder, final int position) { Product product = data.get(position); // if (product != null) { // holder.name.setText(product.getName()); // holder.price.setText(Units.wrapPrice(product.getPrice())); // holder.oldPrice.setText(Units.wrapPrice(product.getOldPrice())); // holder.shopName.setText(product.getShopName()); // holder.shopDistance.setText(product.getShopDistance()); // // ViewUtils.setGone(holder.discountingBadge, !product.isDiscounting()); // } else { // holder.name.setText(null); // holder.price.setText(null); // holder.oldPrice.setText(null); // ViewUtils.setGone( holder.discountingBadge, true); // } holder.bind(product); if (onItemClickLitener != null) { holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onItemClickLitener.onItemClick(holder.itemView, position); } }); holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { //int pos = holder.getLayoutPosition(); onItemClickLitener.onItemLongClick(holder.itemView, position); return false; } }); } } @Override public int getItemCount() { return data.size(); } public class ViewHolder extends RecyclerView.ViewHolder { final TextView name; final TextView price; final TextView oldPrice; final ImageView homeDeliveryBadge; final ImageView discountingBadge; final TextView shopName; final TextView shopDistance; public ViewHolder(View view) { super(view); name = (TextView) view.findViewById(R.id.product_name); price = (TextView) view.findViewById(R.id.product_price); oldPrice = (TextView) view.findViewById(R.id.product_old_price); homeDeliveryBadge = (ImageView) view.findViewById(R.id.product_home_delivery_badge); discountingBadge = (ImageView) view.findViewById(R.id.product_discounting_badge); shopName = (TextView) view.findViewById(R.id.product_shop_name); shopDistance = (TextView) view.findViewById(R.id.product_shop_distance); oldPrice.setPaintFlags(oldPrice.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); } /** * 给每个商品绑定数据 * * @param product */ public void bind(Product product) { if (product != null) { name.setText(product.getName()); price.setText(Units.wrapPrice(product.getPrice())); oldPrice.setText(Units.wrapPrice(product.getOldPrice())); ViewUtils.setGone(discountingBadge, !product.isDiscounting()); shopName.setText(product.getShopName()); shopDistance.setText(product.getShopDistance()); } else { name.setText(null); price.setText(null); oldPrice.setText(null); ViewUtils.setGone(discountingBadge, true); } } } }
子布局:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="144dp" android:layout_height="86dp" android:gravity="center_vertical" android:background="@mipmap/dg_ad_product_grid_item_background" android:paddingLeft="10dp" android:paddingRight="10dp"> <LinearLayout android:id="@+id/product_badge_container" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true"> <ImageView android:id="@+id/product_discounting_badge" android:layout_width="@dimen/dg_badge_icon_width" android:layout_height="@dimen/dg_badge_icon_height" android:layout_marginLeft="2dp" android:src="@mipmap/dg_ic_badge_discounting" /> <ImageView android:id="@+id/product_home_delivery_badge" android:layout_width="@dimen/dg_badge_icon_width" android:layout_height="@dimen/dg_badge_icon_height" android:layout_marginLeft="2dp" android:src="@mipmap/dg_ic_badge_home_delivery" /> </LinearLayout> <TextView android:id="@+id/product_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_toLeftOf="@id/product_badge_container" android:ellipsize="end" android:maxLines="1" android:textColor="@color/dg_colorAccent" android:textSize="13dp" /> <TextView android:id="@+id/product_price" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/product_name" android:layout_centerHorizontal="true" android:maxLines="1" android:textColor="@color/dg_colorAccent" android:textSize="22dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@+id/product_price" android:layout_toLeftOf="@+id/product_price" android:layout_marginTop="4dp" android:textColor="@color/dg_colorAccent" android:textSize="13dp" android:text="@string/dg_product_price_rmb" /> <TextView android:id="@+id/product_old_price" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignRight="@id/product_price" android:layout_below="@id/product_price" android:layout_centerHorizontal="true" android:layout_marginRight="-12dp" android:layout_marginTop="-6dp" android:ellipsize="end" android:maxLines="1" android:textColor="#3D3D3D" android:textSize="14dp" /> <TextView android:id="@+id/product_shop_distance" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_below="@id/product_old_price" android:layout_marginTop="-4dp" android:textColor="#3D3D3D" android:textSize="11dp" /> <TextView android:id="@+id/product_shop_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@id/product_shop_distance" android:layout_alignParentLeft="true" android:layout_toLeftOf="@id/product_shop_distance" android:maxLines="1" android:ellipsize="end" android:textColor="#3D3D3D" android:textSize="11dp" /> </RelativeLayout>
使用:
按照前面一开始的四个步骤就可以了.
package com.fightzhao.recyclerdemo; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.StaggeredGridLayoutManager; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Toast; import com.fightzhao.recyclerdemo.dao.Product; import com.fightzhao.recyclerdemo.ui.adapter.ProductRecyclerAdapter; import java.util.ArrayList; import java.util.List; public class HomeActivity extends ActionBarActivity { private RecyclerView mRecyclerView; private List<String> mDatas; private HomeAdapter mAdapter; // 产品 private List<Product> productDatas; private ProductRecyclerAdapter productRecyclerAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_single_recyclerview); initData(); mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerview); // mAdapter = new HomeAdapter(this, mDatas); // mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(4, // StaggeredGridLayoutManager.VERTICAL)); // mRecyclerView.setAdapter(mAdapter); productRecyclerAdapter = new ProductRecyclerAdapter(this,productDatas); mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.HORIZONTAL)); mRecyclerView.setAdapter(productRecyclerAdapter); // mRecyclerView.addItemDecoration(new DividerGridItemDecoration(this)); // 设置item动画 mRecyclerView.setItemAnimator(new DefaultItemAnimator()); // initEvent(); productRecyclerAdapter.setOnItemClickLitener(new ProductRecyclerAdapter.OnItemClickLitener() { @Override public void onItemClick(View view, int position) { Toast.makeText(getApplicationContext(),"点击了"+position,Toast.LENGTH_SHORT).show(); } @Override public void onItemLongClick(View view, int position) { Toast.makeText(getApplicationContext(),"长按了",Toast.LENGTH_SHORT).show(); } }); } // private void initEvent() { // mAdapter.setOnItemClickLitener(new HomeAdapter.OnItemClickLitener() { // @Override // public void onItemClick(View view, int position) { // Toast.makeText(HomeActivity.this, position + " click", // Toast.LENGTH_SHORT).show(); // } // // @Override // public void onItemLongClick(View view, int position) { // Toast.makeText(HomeActivity.this, position + " long click", // Toast.LENGTH_SHORT).show(); // } // }); // } protected void initData() { mDatas = new ArrayList<String>(); for (int i = 'A'; i < 'z'; i++) { mDatas.add("" + (char) i); } productDatas = new ArrayList<Product>(); productDatas.add(new Product(true,"耳机","神州数码","5",100.00,120.09)); productDatas.add(new Product(false,"笔记本","中关村","15",200.23,220.78)); productDatas.add(new Product(true,"相机","腾讯","25",300,320)); productDatas.add(new Product(true,"苹果手机","腾讯","25",300,320)); productDatas.add(new Product(true,"红米1","腾讯","25",300,320)); productDatas.add(new Product(true,"小米Note","腾讯","25",300,320)); productDatas.add(new Product(true,"魅族","腾讯","25",300,320)); productDatas.add(new Product(true,"相机","腾讯","25",300,320)); productDatas.add(new Product(true,"相机","腾讯","25",300,320)); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.id_action_add: mAdapter.addData(1); break; case R.id.id_action_delete: mAdapter.removeData(1); break; case R.id.id_action_gridview: mRecyclerView.setLayoutManager(new GridLayoutManager(this, 4)); break; case R.id.id_action_listview: mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); break; case R.id.id_action_horizontalGridView: mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.HORIZONTAL)); break; case R.id.id_action_staggeredgridview: Intent intent = new Intent(this, StaggeredGridLayoutActivity.class); startActivity(intent); break; } return true; } }
还有剩下的item点击事件,以及点击某个item消失等等上下来再去总结!!!
现在对点击事件的总结:
可以在Adapter中设置接口去回调.:比如这里:
class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder> { private List<String> mDatas; private LayoutInflater mInflater; private OnItemClickLitener mOnItemClickLitener; public interface OnItemClickLitener { void onItemClick(View view, int position); void onItemLongClick(View view, int position); } public void setOnItemClickLitener(OnItemClickLitener mOnItemClickLitener) { this.mOnItemClickLitener = mOnItemClickLitener; } public HomeAdapter(Context context, List<String> datas) { mInflater = LayoutInflater.from(context); mDatas = datas; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { MyViewHolder holder = new MyViewHolder(mInflater.inflate( R.layout.item_home, parent, false)); return holder; } @Override public void onBindViewHolder(final MyViewHolder holder, final int position) { holder.tv.setText(mDatas.get(position)); // 如果设置了回调,则设置点击事件 if (mOnItemClickLitener != null) { holder.itemView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mOnItemClickLitener.onItemClick(holder.itemView, position); } }); holder.itemView.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { //int pos = holder.getLayoutPosition(); mOnItemClickLitener.onItemLongClick(holder.itemView, position); removeData(position); return false; } }); } }
要是实现对UI的更改:思路就是对集合进行增删,之后通知UI改变:
public void addData(int position) { mDatas.add(position, "Insert One"); notifyItemInserted(position); } public void removeData(int position) { mDatas.remove(position); notifyItemRemoved(position); }