RecyclerView

一、简单介绍

这个是谷歌官方出的控件。使我们能够很easy的做出列表装的一个控件,当然recyclerview的功能不止这些,它还能够做出瀑布流的效果,这是一个很强大的控件,内部自带viewholder能够使我们很easy的完毕很多操作,正在一步一步代替listview这个控件。当然它也有一些小的缺点。那就是谷歌官方并没有直接给我写出它的点击事件的接口,可是这并难不倒我们,我们能够自己写一个回调的接口。实现点击事件。在这里我不仅要为大家介绍recyclerview的item的点击事件,还要为大家介绍,一个item中局部的点击事件,还有加入header、footer,还有加入不同类别的item的布局。能够说彻底的读懂了这篇文章,我们对recyclerview就有了一个新的认识了。

二、涉及到的知识点

  • item的点击事件
  • item里面内容的点击事件
  • 为recycler view加入header和footer
  • 为item加入不同的布局

三、实现代码

/**
* Created by linSir on 16/7/24.管理地址界面的适配器
*/
public class ManageAddressAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {//在这里我们要继承自官方为我们写好的适配器 public OnTitleClickListener mListener;
private List<AllAddress> mList; //用户列表 public ManageAddressAdapter() {
mList = new ArrayList<>();
} public void setList(List<AllAddress> list) {//从外界传入一个list
mList.clear();
mList.addAll(list);
notifyDataSetChanged();
} @Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {//重写方法,用上我们以下写好的viewHoler
return new ManageAddressViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_manage_address, parent, false));
} @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {//在这里我们将数据和控件绑定起来
ManageAddressViewHolder mHolder = (ManageAddressViewHolder) holder;
mHolder.userName.setText(mList.get(position).getShipName());
mHolder.userTel.setText(mList.get(position).getPhone()); String address = mList.get(position).getProvince() + " " + mList.get(position).getCity()
+ " " + mList.get(position).getArea() + " " + mList.get(position).getDetail();
mHolder.address.setText(address); mHolder._default.setOnClickListener(new ClickListener(String.valueOf(position)));//在这里我们设置了点击事件 } @Override public int getItemCount() {
return mList.size();
} public static class ManageAddressViewHolder extends RecyclerView.ViewHolder { private TextView userName;
private TextView userTel;
private TextView address;
private TextView _default; public ManageAddressViewHolder(View itemView) {
super(itemView);
userName = (TextView) itemView.findViewById(R.id.manage_userName);
userTel = (TextView) itemView.findViewById(R.id.manage_userTel);
address = (TextView) itemView.findViewById(R.id.manage_userAddress);
_default = (TextView) itemView.findViewById(R.id.manage_default); }
} public class ClickListener implements View.OnClickListener {//在这里我们重写了点击事件
private String id; public ClickListener(String id) {
this.id = id;
} @Override public void onClick(View view) {
if (mListener != null) {
mListener.onTitleClick(id);
}
}
} public void setOnTitleClickListener(OnTitleClickListener listener) {//自己写了一个方法,用上我们的接口
mListener = listener;
} public interface OnTitleClickListener {//自己写了一个点击事件的接口
void onTitleClick(String id);
} }

通过以上的代码,我们已经为recyclerView里面的item里面的textview加入成功了点击事件,我们仅仅须要在调用它的界面实现这个接口。然后重写点击事件的方法。就能够实现这个textview的点击事件了,以下我们一起看一下代码:

/**
* Created by linSir on 16/7/24.管理地址界面
*/
public class ManageAddressActivity extends AppCompatActivity implements ManageAddressAdapter.OnTitleClickListener {//实现上文我们写好的点击事件的接口 private ManageAddressAdapter mAdapter;
private List<AllAddress> list;
@BindView(R.id.manage_address_recyclerView) RecyclerView mRecyclerView; @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage);
ButterKnife.bind(this);
list = new ArrayList<AllAddress>();
mAdapter = new ManageAddressAdapter();
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
mAdapter.setOnTitleClickListener(this);//声明一下
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setLayoutManager(linearLayoutManager);//这里千万不要了为recyclerview设置布局 } @OnClick(R.id.back_manage_address)
public void back() {
finish();
} @OnClick(R.id.manage_add_address)
public void add() {
Intent intent = new Intent(ManageAddressActivity.this, EditAddress.class);
startActivity(intent);
} @Override
protected void onResume() {
super.onResume();
final HttpResultListener<List<AllAddress>> listener; listener = new HttpResultListener<List<AllAddress>>() {
@Override
public void onSuccess(List<AllAddress> allAddresses) {
Toast.makeText(ManageAddressActivity.this, "获取收货成功", Toast.LENGTH_SHORT).show();
mAdapter.setList(allAddresses);
list = allAddresses; } @Override
public void onError(Throwable e) {
Log.i("lin", "----lin----> 获取收货地址失败 " + e.toString());
}
};
ApiService5.getInstance().allAddress(listener, 1);
} @Override public void onTitleClick(String id) {//这里便是我们重写了的点击事件
Log.i("lin", "----lin----> onTitleClick 的 id " + id);
}
}

以上的代码,我们实现了,为recyclerView的一个item中的textview加入的点击事件,以下我要为大家介绍一下,怎样为recyclerView中item加入不同的布局文件,而且怎样为item整个加入点击事件:

/**
* Created by lin_sir on 2016/7/7.部分商品的展示,的适配器
*/
public class BuyerRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { public static final int FOOTER_TYPE = 0;//最后一个的类型
public static final int HAS_IMG_TYPE = 1;//有图片的类型 private List<FamousPageModel> dataList; private ProgressBar mProgress;
private TextView mNoMore; public BuyerRecyclerAdapter() {
dataList = new ArrayList<>();
} public void addData(List<FamousPageModel> list) {
dataList.addAll(list);
notifyDataSetChanged();
} @Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == FOOTER_TYPE) {
return new FooterItemViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer, parent, false));
} else {
return new BuyerItemViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_buyer, parent, false));
} } @Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
int type = getItemViewType(position);
if (type == FOOTER_TYPE) {
bindFooterView((FooterItemViewHolder) holder);
} else {
bindView((BuyerItemViewHolder) holder, dataList.get(position));
}
} @Override
public int getItemViewType(int position) {
if (position + 1 == getItemCount()) {
return FOOTER_TYPE;
} else {
FamousPageModel news = dataList.get(position);
return HAS_IMG_TYPE;
}
} private void bindView(BuyerItemViewHolder holder, FamousPageModel data) { String productName = data.getProductName();
String[] products = productName.split(" ");
if (products.length != 1) {
productName = products[1] + " 等商品";
} String count = data.getNum();
int sum = 0;
String[] counts = count.split(" ");
if (counts.length == 2) {
sum = Integer.parseInt(counts[0]) + Integer.parseInt(counts[1]);
count = String.valueOf(sum);
} if (counts.length == 3) {
sum = Integer.parseInt(counts[0]) + Integer.parseInt(counts[1]) + Integer.parseInt(counts[2]);
count = String.valueOf(sum);
} holder.count.setText(count);
holder.goods_name.setText(productName);
holder.price.setText(data.getTotal());
if (data.getUser() != null) {
holder.user_name.setText(data.getUser().getName()); } String imgUrl = data.getPicture(); if (imgUrl != null) {
ImageUtil.requestImg(BaseApplication.get().getAppContext(), imgUrl, holder.img);
} // Picasso.with(BaseApplication.get().getAppContext()).load(data.getPicture()).into(holder.img);
} @Override
public int getItemCount() {
return dataList == null ? 0 : dataList.size() + 1;
} public static class BuyerItemViewHolder extends RecyclerView.ViewHolder { private ImageView img;
private TextView price;
private TextView goods_name;
private TextView count;
private TextView user_name; public BuyerItemViewHolder(View itemView) { super(itemView); img = (ImageView) itemView.findViewById(R.id.iv_user_item_buyer2);
price = (TextView) itemView.findViewById(R.id.tv_product_price);
goods_name = (TextView) itemView.findViewById(R.id.tv_product_name);
count = (TextView) itemView.findViewById(R.id.tv_product_number);
user_name = (TextView) itemView.findViewById(R.id.tv_user_name); }
} /**
* 刷新列表
*/
public void refreshList(List<FamousPageModel> list) {
dataList.clear();
dataList.addAll(list);
notifyDataSetChanged();
} /**
* 载入很多其它
*/
public void loadMoreList(List<FamousPageModel> list) {
dataList.addAll(list);
notifyDataSetChanged();
} /**
* 显示没有很多其它
*/
public void showNoMore() {
if (getItemCount() > 0) {
if (mProgress != null && mNoMore != null) {
mNoMore.setVisibility(View.VISIBLE);
mProgress.setVisibility(View.GONE);
}
}
} /**
* 显示载入很多其它
*/
public void showLoadMore() {
if (mProgress != null && mNoMore != null) {
mProgress.setVisibility(View.VISIBLE);
mNoMore.setVisibility(View.GONE);
}
} private void bindFooterView(FooterItemViewHolder viewHolder) {
mProgress = viewHolder.mProgress;
mNoMore = viewHolder.tvNoMore;
} public static class FooterItemViewHolder extends RecyclerView.ViewHolder { private ProgressBar mProgress;
private TextView tvNoMore; public FooterItemViewHolder(View itemView) {
super(itemView);
mProgress = (ProgressBar) itemView.findViewById(R.id.pb_footer_load_more);
tvNoMore = (TextView) itemView.findViewById(R.id.tv_footer_no_more);
}
} /**
* 获取点击的 item,假设是最后一个,则返回 null
*/
public FamousPageModel getClickItem(int position) {
if (position < dataList.size()) {
return dataList.get(position);
} else {
return null;
}
} }

在这里我们首先重写了getItemViewType。这里面我眼下仅仅写了两种类型。那就是带有图片的类型。和不带有图片的类型,而且我让不带图片的类型出如今了最后面,当然大家能够任意的设置。我们仅仅须要依据它们的特征为他们分好类,然后依据不同的类型载入不同的布局文件就可以。

/**
* Created by lin_sir on 2016/7/7. buyer界面
*/
public class FragmentBuyer extends Fragment implements SwipeRefreshLayout.OnRefreshListener { private static int CURRENT_PAGE = 1; //获取须要请求的页号
private RecyclerView recyclerView; //recyclerView
private BuyerRecyclerAdapter madapter; //适配器
private List<FamousPageModel> mlist; //一个装载数据的集合
private LinearLayoutManager linearLayoutManager; //linearLayoutManger
private HttpResultListener<List<FamousPageModel>> listener; //数据请求的回调接口
private SwipeRefreshLayout refreshLayout; //下拉刷新控件
private boolean isLoadMore; //是否载入很多其它 @Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_buyer, container, false);
initviews(view);
initListener();
refreshData();
ButterKnife.bind(this, view);
return view;
} private void initListener() {
listener = new HttpResultListener<List<FamousPageModel>>() {
@Override
public void onSuccess(List<FamousPageModel> list) {
Log.i("lin", "----lin----> refresh success");
refreshLayout.setRefreshing(false);
if (isLoadMore) {
mlist = list;
madapter.loadMoreList(mlist);
madapter.notifyDataSetChanged();
madapter.showNoMore();
} else {
mlist = list;
madapter.refreshList(list);
madapter.notifyDataSetChanged();
}
} @Override
public void onError(Throwable e) {
Log.i("lin", "----lin----> refresh error " + e.toString());
refreshLayout.setRefreshing(false);
madapter.showNoMore();
}
};
} private void initviews(View view) { mlist = new ArrayList<>(); refreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.refresh_news);
recyclerView = (RecyclerView) view.findViewById(R.id.rv_buyer); refreshLayout.setColorSchemeResources(R.color.blue_500, R.color.purple_500, R.color.green_500);
refreshLayout.setOnRefreshListener(this);
linearLayoutManager = new LinearLayoutManager(getActivity());
linearLayoutManager.setOrientation(OrientationHelper.VERTICAL); madapter = new BuyerRecyclerAdapter();
madapter.addData(mlist); recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(madapter);
recyclerView.addOnScrollListener(new OnRecyclerScrollListener());
recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(getActivity(), onItemClickListener));
} /**
* 刷新时,默认请求第一页的数据
*/
private void refreshData() {
refreshLayout.setRefreshing(true);
isLoadMore = false;
CURRENT_PAGE = 1;
requestData(1);
} /**
* 载入很多其它
*/
private void loadMoreData() {
refreshLayout.setRefreshing(false);// 载入很多其它与刷新不能同一时候存在
isLoadMore = true;
requestData(++CURRENT_PAGE);
} public class OnRecyclerScrollListener extends RecyclerView.OnScrollListener { int lastVisibleItem = 0; @Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState); if (madapter != null && newState == RecyclerView.SCROLL_STATE_IDLE && lastVisibleItem + 1 == madapter.getItemCount()) {
loadMoreData();
}
} @Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
}
} /**
* 请求数据
*/
private void requestData(int page) {
madapter.showLoadMore();
ApiService2.getInstance().famous(listener, page);
} @Override
public void onRefresh() {
refreshData();
} private RecyclerItemClickListener.OnItemClickListener onItemClickListener = new RecyclerItemClickListener.OnItemClickListener() {//这里我们便实现了点击事件
@Override
public void onItemClick(View view, int position) {
Toast.makeText(getActivity(), "您点击的是: " + position, Toast.LENGTH_SHORT).show(); }
}; @OnClick(R.id.release_distance_buyer)
public void release() {
Intent intent = new Intent(getActivity(), ReleaseOrderActivity.class);
startActivity(intent); } @Override public void onDestroy() {
super.onDestroy();
} }

以上便是依据我近期做的项目粗略的整理了一下。recyclerview的简单使用方法。在这里我也用到了,下拉刷新,上拉载入很多其它,等等等等的方法,写这些也是为了让自己在以后遇到相同的需求的时候,能够很快的写出,假设大家也有这些小问题的能够和我一起交流。

05-11 20:03