1.RecyclerView的使用
首先介绍下RecyclerView的基本使用,这是5.0的新组件,前几天说到ListView,同事说low不low,现在都用RecyclerView了。
好吧,之前都不知道这东西,看来就是用来代替ListView的,官方文档说RecyclerView用起来方便,但是我觉得比ListView麻烦啊,但是不管了,早晚ListView会被划上横线的,超讨厌那横线
优化ListView要用到什么?HoldView。
RecyclerView是自带HoldView的,这是主要的区别
strings是要添加到RecyclerView的数组
RecyclerView有还有两个重要的类:
RecyclerView.Adapter //重写这个类,注意不是一般的Adapter
RecyclerView.LayoutManager //可以不重写,LinearLayoutManager是线性布局,可以设置水平方向,当然还有其他布局方式
public class MainActivity extends ActionBarActivity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
String[] strings={"123","456","789","111"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
// use a linear layout manager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
// specify an adapter (see also next example)
mAdapter = new MyAdapter(strings);
mRecyclerView.setAdapter(mAdapter);
}
这是RecyclerView中item的布局,只有个TextView
<?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="match_parent">
<TextView
android:id="@+id/photo_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
重写RecyclerView.Adapter
重写内部类RecyclerView.ViewHolder
onCreateViewHolder
onBindViewHolder
class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{
String[] strings;
MyAdapter(String[] strings) {
this.strings=strings;
}
@Override
public long getItemId(int position) {
return super.getItemId(position);
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
LinearLayout linearLayout= (LinearLayout) getLayoutInflater().inflate(R.layout.layout_photo_item,viewGroup,false);
MyViewHolder myViewHolder = new MyViewHolder(linearLayout);
return myViewHolder;
}
@Override
public void onBindViewHolder(MyViewHolder viewHolder, int i) {
viewHolder.textView.setText(strings[i]);
}
@Override
public int getItemCount() {
return strings.length;
}
class MyViewHolder extends RecyclerView.ViewHolder
{
TextView textView;
public MyViewHolder(View itemView) {
super(itemView);
textView= (TextView) itemView.findViewById(R.id.photo_info);
}
}
}
效果图,内容只有4条String
2.RecyclerView+Volley实现照片墙
ok,下面开始实现照片墙,先看下效果图
用到新工具Volley,可以在下方链接下载到一个jar包
http://download.csdn.net/detail/silver__lining/8714097
jar包放到项目的libs目录下,导入
我用的是Android Studio,如何导入看链接
http://blog.csdn.net/silver__lining/article/details/44118969
首先要修改Adapter,前面是小实验,因为第一次用RecyclerView,里面的items是String
这里的items是Bitmap
跟之前差不多,只是TexttView换成ImageView
class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.MyViewHolder> {
Bitmap[] bitmaps;
class MyViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
public MyViewHolder(View itemView) {
super(itemView);
imageView = (ImageView) itemView.findViewById(R.id.photo_info);
}
}
ImageAdapter(Bitmap[] bitmaps) {
this.bitmaps = bitmaps;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LinearLayout linearLayout = (LinearLayout) getLayoutInflater().inflate(R.layout.layout_photp_item, parent, false);
MyViewHolder viewHolder = new MyViewHolder(linearLayout);
return viewHolder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.imageView.setImageBitmap(bitmaps[position]);
}
@Override
public int getItemCount() {
return bitmaps.length;
}
}
下面是一个图片类,里面是一堆图片的url
package com.example.administrator.photowall;
/**
* Created by Administrator on 2015/2/10.
*/
public class Images {
public final static String[] imageThumbUrls = new String[] {
"https://img-my.csdn.net/uploads/201407/26/1406383299_1976.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383291_6518.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383291_8239.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383290_9329.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383290_1042.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383275_3977.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383265_8550.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383264_3954.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383264_4787.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383264_8243.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383248_3693.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383243_5120.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383242_3127.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383242_9576.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383242_1721.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383219_5806.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383214_7794.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383213_4418.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383213_3557.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383210_8779.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383172_4577.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383166_3407.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383166_2224.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383166_7301.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383165_7197.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383150_8410.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383131_3736.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383130_5094.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383130_7393.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383129_8813.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383100_3554.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383093_7894.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383092_2432.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383092_3071.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383091_3119.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383059_6589.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383059_8814.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383059_2237.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383058_4330.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383038_3602.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382942_3079.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382942_8125.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382942_4881.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382941_4559.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382941_3845.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382924_8955.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382923_2141.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382923_8437.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382922_6166.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382922_4843.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382905_5804.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382904_3362.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382904_2312.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382904_4960.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382900_2418.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382881_4490.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382881_5935.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382880_3865.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382880_4662.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382879_2553.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382862_5375.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382862_1748.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382861_7618.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382861_8606.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382861_8949.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382841_9821.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382840_6603.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382840_2405.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382840_6354.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382839_5779.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382810_7578.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382810_2436.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382809_3883.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382809_6269.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382808_4179.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382790_8326.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382789_7174.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382789_5170.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382789_4118.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382788_9532.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382767_3184.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382767_4772.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382766_4924.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382766_5762.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406382765_7341.jpg"
};
}
用Volley下载图片分三步:
1. 创建一个RequestQueue对象。
2. 创建一个ImageRequest对象。
3. 将ImageRequest对象添加到RequestQueue里面。
下面的代码是第二部,创建 ImageRequest
ImageRequest有6个参数,分别是:
URL,重写的Response.Listener,图片宽(int),图片高(int),图片的颜色属性,重写的Response.ErrorListener
我们这第一个参数是上面Images类里的第n张图片的URL
判断有没有越界,没有就再执行这个方法,下载下一张图片
public void downLoadPhoto(int n) {
ImageRequest imageRequest = new ImageRequest(Images.imageThumbUrls[n], new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap bitmap) {
bitmaps[finishedNumbers] = bitmap;//bitmaps是Bitmap的数组,放到RecyclerView里,里面有默认图片,下载完成后替代默认图片
finishedNumbers++;
mAdapter.notifyDataSetChanged();//刷新RecyclerView
if (finishedNumbers < Images.imageThumbUrls.length)
DownLoadPhoto(finishedNumbers);//继续下载下一张
}
}, 0, 0, Bitmap.Config.RGB_565, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Log.e("SJJ", volleyError.toString());
}
});
requestQueue.add(imageRequest);//第三步,<span style="color: rgb(51, 51, 51); font-family: Arial; font-size: 14px; line-height: 26px;">ImageRequest</span><span style="color: rgb(51, 51, 51); font-family: Arial; font-size: 14px; line-height: 26px;">对象添加到RequestQueue里面</span>
}
下面是全部代码,看得清楚点
public class MainActivity extends ActionBarActivity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
String[] strings = {"123", "456", "789", "111"};
Bitmap[] bitmaps;
int finishedNumbers = 0;//已经下载完的图片数
RequestQueue requestQueue;
private boolean isFirstBoot = true;//判断第一次启动,开始下载图片
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bitmaps = new Bitmap[Images.imageThumbUrls.length];
for (int i = 0; i < Images.imageThumbUrls.length; i++) {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.polaroids);
bitmaps[i] = bitmap;//设置默认图片
}
requestQueue = Volley.newRequestQueue(MainActivity.this);//获取RequestQueue实例
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
// use a linear layout manager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
// specify an adapter (see also next example)
//mAdapter = new MyAdapter(strings);
mAdapter = new ImageAdapter(bitmaps);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (mRecyclerView.getScrollState() == RecyclerView.SCROLL_STATE_IDLE) {
Log.i("SJJ", "SCROLL_STATE_IDLE");
requestQueue.start();//如果没有滚动,状态是idle,那就下载图片
} else {
requestQueue.stop();//如果开始滚动,停止下载
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
});
if (isFirstBoot) {
downLoadPhoto(finishedNumbers);//开始下载,从第0张开始
isFirstBoot=false;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void downLoadPhoto(int n) {
ImageRequest imageRequest = new ImageRequest(Images.imageThumbUrls[n], new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap bitmap) {
bitmaps[finishedNumbers] = bitmap;
finishedNumbers++;
mAdapter.notifyDataSetChanged();
if (finishedNumbers < Images.imageThumbUrls.length)
downLoadPhoto(finishedNumbers);
}
}, 0, 0, Bitmap.Config.RGB_565, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Log.e("SJJ", volleyError.toString());
}
});
requestQueue.add(imageRequest);
}
class DownLoadPhotoTask extends AsyncTask<String, Integer, Bitmap> {
Bitmap bm;
@Override
protected Bitmap doInBackground(String... params) {
RequestQueue requestQueue = Volley.newRequestQueue(MainActivity.this);
ImageRequest imageRequest = new ImageRequest(params[0], new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap bitmap) {
bm = bitmap;
}
}, 0, 0, Bitmap.Config.RGB_565, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Log.e("SJJ", volleyError.toString());
}
});
requestQueue.add(imageRequest);
return bm;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
bitmaps[finishedNumbers] = bitmap;
finishedNumbers++;
mAdapter.notifyDataSetChanged();
}
}
class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.MyViewHolder> {
Bitmap[] bitmaps;
class MyViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
public MyViewHolder(View itemView) {
super(itemView);
imageView = (ImageView) itemView.findViewById(R.id.photo_info);
}
}
ImageAdapter(Bitmap[] bitmaps) {
this.bitmaps = bitmaps;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LinearLayout linearLayout = (LinearLayout) getLayoutInflater().inflate(R.layout.layout_photp_item, parent, false);
MyViewHolder viewHolder = new MyViewHolder(linearLayout);
return viewHolder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.imageView.setImageBitmap(bitmaps[position]);
}
@Override
public int getItemCount() {
return bitmaps.length;
}
}