效果图(图片api全部来自 http://gank.io/api )
首先加入依赖包
compile 'com.android.support:recyclerview-v7:23.1.0'
compile 'com.android.support:cardview-v7:21.0.+'
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.github.bumptech.glide:glide:3.7.0'
前两个不用多说,第三个是retrofit2的网络加载框架,第四个是glide图片加载框架(具体不在这里细说,有兴趣的同学可以去网上学习一下用法)
然后在注册文件中添加联网权限
RecyclerView的常用方法
recyclerView.setLayoutManager(RecyclerView.LayoutManager);//设置布局管理器,有瀑布式,网格式和线性,本文使用的是瀑布式
recyclerView.addItemDecoration(ItemDecoration);//设置边框
recyclerView.addOnScrollListener(RecyclerView.OnScrollListener);//设置滑动监听,主要用于实现底端自动加载
recyclerView.setItemAnimator(ItemAnimator);//设置新增或删除item动画效果,官方有几种写好的效果,也可以自己实现
接下来不多说,看程序
activity_main.xml(只有一个RecyclerView)
list_item.xml
MainActivity.java
public class MainActivity extends AppCompatActivity {
private int lastVisibleItem;
private int nowPage=1;
private CardView cardView;
private List datalist;
private RecyclerView recyclerView;
/*
本文采用了瀑布式StaggeredGridLayoutManager,其他还有网格式和线性布局
*/
private StaggeredGridLayoutManager gridLayoutManager;
private MyAdapter myAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView= (RecyclerView) findViewById(R.id.recycler);
//gridLayoutManager=new GridLayoutManager(this,3,GridLayoutManager.HORIZONTAL,false);
gridLayoutManager=new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.HORIZONTAL);
//HORIZONTAL代表横向滑动
recyclerView.addItemDecoration(new SpaceItemD(10));
getData();
recyclerView.setLayoutManager(gridLayoutManager);
setFreshListener();
// recyclerView.setItemAnimator();
}
public void setFreshListener(){
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
Log.i("-------last ",String.valueOf(lastVisibleItem));
if(newState == RecyclerView.SCROLL_STATE_IDLE
&&lastVisibleItem+1==gridLayoutManager .getItemCount()){
addData();
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int[] positions=gridLayoutManager.findLastVisibleItemPositions(null);
lastVisibleItem =Math.max(positions[0],positions[1]);
}
});
}
public void getData(){
datalist=new ArrayList();
//new GetData().execute();
// for (int i=0;i<30;i++){
// datalist.add("data-----------: "+String.valueOf(i));
// Log.i("----------------- i : ",String.valueOf(i));
// }
myAdapter=new MyAdapter(this,datalist);
Random random=new Random();
nowPage=random.nextInt(30);
addData();
recyclerView.setAdapter(myAdapter);
}
class SpaceItemD extends RecyclerView.ItemDecoration{
int mSpace;
public SpaceItemD(int s){
mSpace=s;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
outRect.left=mSpace;
outRect.bottom=mSpace;
}
}
public void addData(){
//下面为retrofit部分,看不懂的同学可以去学习retrofit框架或者略过
Retrofit retrofit=new Retrofit.Builder()
.baseUrl("http://gank.io/api/data/福利/")
.build();
GetPage getPage=retrofit.create(GetPage.class);
if(nowPage<=50) {
Call call = getPage.getPageData("10", nowPage);
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
String json = null;
try {
json = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
//自己定义的Json解析器,根据不同结构Json来解析
List list = JsonParser.parserServerResult(json);
for (String s : list) {
datalist.add(s);
//Log.i("-----------url: ",s);
}
nowPage++;
myAdapter.notifyItemRangeInserted(lastVisibleItem,10);
}
@Override
public void onFailure(Call call, Throwable t) {
t.printStackTrace();
}
});
}
}
}
MyAdapter.java
public class MyAdapter extends RecyclerView.Adapter {
private Context context;
private List data;
//private List mWidth=new ArrayList();
MyAdapter(Context c,List l){
context=c;
data=l;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= LayoutInflater.from(context).inflate(R.layout.list_item,parent,false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
View v=holder.itemView;
CardView cardView= (CardView) v.findViewById(R.id.card_view);
//TextView textView= (TextView) v.findViewById(R.id.item_text);
ImageView imageView= (ImageView) v.findViewById(R.id.image_view);
//使用glide加载图片到imageview
Glide.with(context).load(data.get(position).toString()).into(imageView);
//给每个item设置监听器,这里为了实现方便,点击图片后打开浏览器,既有图片放大查看还有保存功能
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i=new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(data.get(position).toString()));
context.startActivity(i);
}
});
//textView.setText(data.get(position).toString());
//textView.setWidth(200+position%3*30);
// ((MyViewHolder)holder).textView.setText(data.get(position).toString());
// ((MyViewHolder) holder).textView.setWidth(200+position%3*30);
}
@Override
public int getItemCount() {
return data.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
// private CardView cardView;
// private TextView textView;
public MyViewHolder(View itemView) {
super(itemView);
// cardView= (CardView) itemView.findViewById(R.id.card_view);
// textView = (TextView) itemView.findViewById(R.id.item_text);
}
}
}
总结
在重用item时候会根据大小重新设置item宽度,就会有一种在乱跳的效果。有一种解决方案是将每个data的宽度存起来,onBindViewHolder()中直接设置为这个宽度。如果不是特别需要的话还是使用线性或者网格式吧,坑比较少。