以前在遇到要添加列表的地方一直习惯使用ListView,但是RecyclerView出来已经很久了,据说用过的人都说好,既然大家都这样说,那我也花了一点时间来学习RecyclerView,在看了很多大牛的博客后,感觉RecyclerView的确比ListView强大得多,通过设置LayoutManager就可以随意改变列表的样式,item的增删也自带动画,不多说,直接来看代码吧。
首先编辑的当然是布局了,先是MainActivity的布局,因为我要用到下拉刷新,所以加了一个SwipeRefreshLayout,两个按钮用来进行增删
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="demo.yang.com.recyclerview.MainActivity">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/additem"
android:text="add"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/removeitem"
android:text="remove"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swiperefreshlayout"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
然后是适配器的item布局,这里就直接加了一个背景色,以及text居中
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:gravity="center"
android:background="#44ff00"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv"
android:text="a"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="50dp" />
</LinearLayout>
接着是显示上拉加载状态的FootView的布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="45dp"
>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="45dp"
android:orientation="horizontal"
android:gravity="center">
<ProgressBar
android:layout_width="25dp"
android:layout_height="25dp"
/>
<TextView
android:id="@+id/foot_view_item_tv"
android:layout_marginLeft="4dp"
android:text="上拉加载更多..."
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
所有的布局文件就这些,接下来就是RecyclerView的适配器的编写了, 先上代码
package demo.yang.com.recyclerview;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.List;
/**
* Created by yxy on 2017/1/6.
* email:1084625746@qq.com
*/
public class MyRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private List<String> mDatas;
private Context context;
private OnItemClickListener onItemClickListener;
public static final int PULLUP_LOAD_MORE = 0;//上拉加载更多
public static final int LOADING_MORE = 1;//正在加载中
private int load_more_status = 0;//上拉加载更多状态,默认为0
private static final int TYPE_ITEM = 0;//普通Item View
private static final int TYPE_FOOTER = 1;//底部Foot View
public MyRecyclerAdapter(List<String> mDatas, Context context) {
this.mDatas = mDatas;
this.context = context;
}
@Override
public int getItemViewType(int position) {
if (position + 1 == getItemCount()){
return TYPE_FOOTER;
}else {
return TYPE_ITEM;
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_ITEM){
MyViewHolder holder = new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item,parent,false));
return holder;
}else {
FootViewHolder holder = new FootViewHolder(LayoutInflater.from(context).inflate(R.layout.foot_view,parent,false));
return holder;
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
if (holder instanceof MyViewHolder){
((MyViewHolder)holder).tv.setText(mDatas.get(position));
}else {
switch (load_more_status){
case PULLUP_LOAD_MORE:
((FootViewHolder)holder).foot_view_item.setText("你倒是继续拉啊!");
break;
case LOADING_MORE:
((FootViewHolder)holder).foot_view_item.setText("我在努力加载...");
break;
}
}
}
@Override
public int getItemCount() {
return mDatas.size()+1;
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView tv;
public MyViewHolder(View itemView) {
super(itemView);
tv = (TextView) itemView.findViewById(R.id.tv);
}
}
class FootViewHolder extends RecyclerView.ViewHolder {
private TextView foot_view_item;
public FootViewHolder(View itemView) {
super(itemView);
foot_view_item = (TextView) itemView.findViewById(R.id.foot_view_item_tv);
}
}
public void addItem(List<String> newDatas){
newDatas.addAll(mDatas);
mDatas.removeAll(mDatas);
mDatas.addAll(newDatas);
notifyDataSetChanged();
}
public void addMoreItem(List<String> newDatas){
mDatas.addAll(newDatas);
notifyDataSetChanged();
}
public void changeMoreStatus(int status){
load_more_status = status;
notifyDataSetChanged();
}
public void addItemButton(String data,int position){
mDatas.add(position,data);
notifyItemInserted(position);
}
public void removeItemButton(int position){
mDatas.remove(position);
notifyItemRemoved(position);
}
}
有注释的地方就不多做解释了,从上往下看getItemViewType用来判断item的情况,如果是最后一行就返回TYPE_FOOTER,其他情况就返回TYPE_ITEM,onCreateViewHolder进行视图的创建,onBindViewHolder进行数据绑定,getItemCount返回列表的行数,MyViewHolder是item的ViewHolder,FootViewHolder是上拉加载的ViewHolder,addItem用来添加下拉刷新时产生的新数据,addMoreItem用来添加上拉加载时产生的新数据,changeMoreStatus用来接收activity传递过来的上拉加载的状态,addItemButton添加一个item到list中的某个位置,removeItemButton删除list某个位置上的item。
最后是MainActivity
package demo.yang.com.recyclerview;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
/**
* Created by yxy on 2017/1/6.
* email:1084625746@qq.com
*/
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private MyRecyclerAdapter mAdapter;
private List<String> mDatas;
private LinearLayoutManager manager;
private SwipeRefreshLayout swipeRefreshLayout;
private int lastVisibleItem;
private Button add,remove;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
mRecyclerView = (RecyclerView) findViewById(R.id.recycler);
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swiperefreshlayout);
add = (Button) findViewById(R.id.additem);
remove = (Button) findViewById(R.id.removeitem);
//设置刷新按钮的背景色
swipeRefreshLayout.setProgressBackgroundColorSchemeColor(getResources().getColor(android.R.color.white));
//设置刷新箭头的颜色,最多可以设置四种
swipeRefreshLayout.setColorSchemeColors(getResources().getColor(android.R.color.holo_blue_light),
getResources().getColor(android.R.color.holo_red_light),
getResources().getColor(android.R.color.holo_orange_light),
getResources().getColor(android.R.color.holo_green_light));
//第一个参数true表示缩放,圆形进度图像会从小到大展示出来,第二个参数是圆形图像出来的位置,第三个参数是旋转的位置
swipeRefreshLayout.setProgressViewOffset(true,0,100);
manager = new LinearLayoutManager(this);
manager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(manager);
//添加分割线
mRecyclerView.addItemDecoration(new LinearItemDecoration(this,R.drawable.divider_bg,R.dimen.dividersize));
//设置默认动画
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mRecyclerView.setAdapter(mAdapter = new MyRecyclerAdapter(mDatas,this));
//增加一行
add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mAdapter.addItemButton("add item",5);
}
});
//删除一行
remove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mAdapter.removeItemButton(5);
}
});
//设置下拉刷新
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
List<String> newDatas = new ArrayList<String>();
for (int i = 0;i < 5;i++){
int index = i + 1;
newDatas.add("new item" + index);
}
mAdapter.addItem(newDatas);
swipeRefreshLayout.setRefreshing(false);
Toast.makeText(MainActivity.this,"更新了五条数据...",Toast.LENGTH_SHORT).show();
}
},1000);
}
});
//设置上拉加载
mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE && lastVisibleItem + 1 == mAdapter.getItemCount()){
mAdapter.changeMoreStatus(MyRecyclerAdapter.LOADING_MORE);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
List<String> newDatas = new ArrayList<String>();
for (int i = 0;i < 5;i++){
int index = i + 1;
newDatas.add("more item" + index);
}
mAdapter.addMoreItem(newDatas);
mAdapter.changeMoreStatus(MyRecyclerAdapter.PULLUP_LOAD_MORE);
}
},1000);
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
lastVisibleItem = manager.findLastVisibleItemPosition();
}
});
}
private void initData(){
mDatas = new ArrayList<>();
for (int i = 'A';i < 'z';i++){
mDatas.add(""+(char)i);
}
}
}
注释全都写在了相应位置,思路应该比较清晰了,这只是浅谈RecyclerView,欢迎各路大神进行指导!