可以直接使用Glide套件下載會更方便
可以參考如何使用Glide
在之前如何從網路下載圖片的文章是下載一張圖片,
那如果要在listview內下載圖片,
又不想要影響滑動怎麼辦呢?
在網路圖片還沒下載好之前, 就先用預設圖片來裝一下就好。
可以自由滑動直到網路圖片下載完畢再更新。
根據如何從網路下載圖片的程式碼修改
public void handleWebPic(final String url, final int index){
ThreadPoolManager.getInstance()
.addSelectPhotoTask(new Thread(new Runnable(){
@Override
public void run() {
Bitmap bmp = getUrlPic(url);
bmpList.add(index, bmp);
runOnUiThread(new Runnable(){
@Override
public void run() {
if(mMyAdapter != null){
mMyAdapter.notifyDataSetChanged();
}
}
});
}
}));
}
public synchronized Bitmap getUrlPic(String url) {
Bitmap webImg = null;
try {
URL imgUrl = new URL(url);
HttpURLConnection httpURLConnection
= (HttpURLConnection) imgUrl.openConnection();
httpURLConnection.connect();
InputStream inputStream = httpURLConnection.getInputStream();
int length = (int) httpURLConnection.getContentLength();
int tmpLength = 512;
int readLen = 0,desPos = 0;
byte[] img = new byte[length];
byte[] tmp = new byte[tmpLength];
if (length != -1) {
while ((readLen = inputStream.read(tmp)) > 0) {
System.arraycopy(tmp, 0, img, desPos, readLen);
desPos += readLen;
}
webImg = BitmapFactory.decodeByteArray(img, 0,img.length);
if(desPos != length){
throw new IOException("Only read" + desPos +"bytes");
}
}
httpURLConnection.disconnect();
}
catch (IOException e) {
Log.e("IOException",e.toString());
}
return webImg;
}
當抓完網路圖片以後, 則丟到一個圖片陣列內
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = getApplicationContext();
mListView = (ListView) findViewById(R.id.listview);
bmpList = new ArrayList<Bitmap>();
for(int i = 0; i < 100; i++){
bmpList.add(null);
handleWebPic("https://dl.dropboxusercontent.com/u/24682760/drawable/raccoon.png", i);
}
mMyAdapter = new MyAdapter();
mListView.setAdapter(mMyAdapter);
}
一開始宣告一個listview 跟 adapter, 然後假設我們要抓一百張圖片,
因為我懶所以抓同一張, 不影響結果。
那如果他一開始還沒有圖片, 就讓這個bitmap為null。
private class MyAdapter extends BaseAdapter{
@Override
public int getCount() {
// TODO Auto-generated method stub
return bmpList.size();
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View view, ViewGroup arg2) {
View v = view;
Holder holder;
if(v == null){
v = LayoutInflater.from(mContext).inflate(R.layout.listview_item, null);
holder = new Holder();
holder.img = (ImageView) v.findViewById(R.id.img);
v.setTag(holder);
} else{
holder = (Holder) v.getTag();
}
if(bmpList.get(position) == null){
holder.img.setImageResource(R.drawable.ic_launcher);
} else{
holder.img.setImageBitmap(bmpList.get(position));
}
return v;
}
class Holder{
ImageView img;
}
}
關鍵字就是圖片為null的時候, 表示還沒下載完, 所以就讓他為預設圖片,
否則就刷新呈現出來。
至於thradpool要怎麼使用呢?
public class ThreadPoolManager {
private static ThreadPoolManager mThreadPoolManager;
private final int KEEP_ALIVE_TIME = 3;
// Sets the Time Unit to seconds
private final TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
// Creates a thread pool manager
private ThreadPoolManager(){}
public static ThreadPoolManager getInstance(){
if(null == mThreadPoolManager){
mThreadPoolManager = new ThreadPoolManager();
}
return mThreadPoolManager;
}
private final BlockingQueue<Runnable> mPhotoQueue = new LinkedBlockingQueue<Runnable>();
private ThreadPoolExecutor mPhotoExcutor = new ThreadPoolExecutor(
4, // Initial pool size
5, // Max pool size
KEEP_ALIVE_TIME,
KEEP_ALIVE_TIME_UNIT,
mPhotoQueue);
public void addSelectPhotoTask(Runnable runnable){
mPhotoExcutor.execute(runnable);
}
}
寫一個獨體模式 讓他去跑thread 利用內建的排程LinkedBlockingQueue (還有很多種)
讓他用佇列一個一個跑完以後, 就對畫面做更新。
這樣就完成一個簡單的排程。