package com.example.ex01_1;
成都創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供劍河網(wǎng)站建設(shè)、劍河做網(wǎng)站、劍河網(wǎng)站設(shè)計、劍河網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、劍河企業(yè)網(wǎng)站模板建站服務(wù),10年劍河做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.content.DialogInterface;
import android.database.CursorJoiner.Result;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity
{
private ArrayList
private ArrayList
private MyAdapater myadapater;
// String PATH = "http://192.168.56.1:8080/server/";
String PATH = "http://192.168.56.1:8080/server/";
private ListView listView;
/**
問題:圖片下載完成,上下滑動ListView,圖片重新下載
原因:上下滑動,觸發(fā)getView()方法,新建異步任務(wù),重新下載
解決:創(chuàng)建一個容器,保存已經(jīng)下載的Bitmap對象
為了防止重復(fù)下載,把以及下載的圖片放在imgmap這個容器中
*/
HashMap
/**
* 問題:下載過程中,上下滑動ListView,等待下載完成,圖片多次下載
原因:上下滑動ListView,觸發(fā)getView()方法,判斷圖片還未下載完成,創(chuàng)
建新的異步任務(wù).
解決:創(chuàng)建一個容器保存已經(jīng)開始執(zhí)行的AsyncTask對象
創(chuàng)建一個容器用于保存已經(jīng)開始的異步任務(wù)
*/
HashMap
/**問題是:某一行下載完成后,上下滑動ListView, 其他未點擊下載的行會出現(xiàn)前面?zhèn)€行的狀態(tài)。
引用容器保存文件下載狀態(tài),
我們通過下載狀態(tài)的區(qū)別來更新控件的狀態(tài),得以解決這個問題。創(chuàng)建一個容器用來保存當(dāng)前行的文件的下載狀態(tài),用來解決文件下載時,復(fù)用View帶來的Bug
*/
//
HashMap
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 首先找到activity_mian.xml里面的listView1
listView = (ListView) findViewById(R.id.listView1);
myadapater = new MyAdapater();
listView.setAdapter(myadapater);
// 添加圖片
for (int i = 1; i < 16; i++)
{
dataList.add(PATH + "ic" + i + ".png");
}
// 添加文件
for (int i = 1; i < 16; i++)
{
fileurl.add(PATH + "ic" + i + ".rar");
}
}
// 得到一段保存地址
private String getSavePath(String fileurl)
{
String sdcard = Environment.getExternalStorageDirectory() + "";
// 截取一段地址
int lastIndexOf = fileurl.lastIndexOf("/");
String savename = fileurl.substring(lastIndexOf);
String savePath = sdcard + savename;
return savePath;
}
// 創(chuàng)建一個適配器的類
class MyAdapater extends BaseAdapter {
private ImgAsy asy;
// 獲得行數(shù)
@Override
public int getCount()
{
return 15;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position)
{
return 0;
}
@Override
// 得到每一行控件的樣式和內(nèi)容,則對每一行的控件的內(nèi)容和樣式的修改都在這里進行
public View getView(final int position, View convertView, ViewGroup parent)
{
View view = null;
ViewHolder holder = null;
// 繼續(xù)優(yōu)化,優(yōu)化1復(fù)用布局,防止重復(fù)下載,浪費不必要的流量
if (convertView == null) // convertView:消失的行布局
{
// 找到XML文件轉(zhuǎn)換器
LayoutInflater inflater = getLayoutInflater();
// 把每一行的樣式轉(zhuǎn)換成VIEW對象
view = inflater.inflate(R.layout.listview, null);
// 優(yōu)化2,減少控件的查找.封裝一個類包含所有的控件
holder = new ViewHolder();
holder.iv = (ImageView) view.findViewById(R.id.p_w_picpathView1);
holder.btn = (Button) view.findViewById(R.id.button1);
holder.tv = (TextView) view.findViewById(R.id.textView1); holder.pb = (ProgressBar)view.findViewById(R.id.progressBar1);
view.setTag(holder);
} else
{
view = convertView;
holder = (ViewHolder) view.getTag();// 優(yōu)化2
}
/** 問題:ListView某一行下載完成之后,上下滑動ListView,還未下載的行數(shù)顯示圖片
原因:復(fù)用造成
解決:還未下載完成的行數(shù),設(shè)置默認(rèn)圖片顯示*/
// 把沒有參與下載的行的圖片設(shè)置為默認(rèn)圖片,解決未下載的圖片提前顯示出來的問題
holder.iv.setImageResource(R.drawable.ic_launcher);
// 這兩行代碼是為了判斷當(dāng)前行圖片是否下載完成和異步任務(wù)是否開啟而寫的
Bitmap bitmap = imgmap.get(dataList.get(position));
ImgAsy asy = asymap.get(dataList.get(position));
if (bitmap == null)
{
// 圖片尚未下載,判斷當(dāng)前行的異步任務(wù)是否開始
if (asy == null)
{ // 這是一個構(gòu)造方法
asy = new ImgAsy(holder.iv, position);
asy.execute(dataList.get(position));
asymap.put(dataList.get(position), asy);
}
// 解決上下滑動過程中,ImageView對象創(chuàng)建了,卻沒有創(chuàng)建新的異步任務(wù)的問題。
asy.changView(holder.iv);
} else {
holder.iv.setImageBitmap(bitmap);
}
//根據(jù)下載狀態(tài)設(shè)置各控件的顯示狀態(tài)
Boolean state=stateMap.get(position);
if (state==null)
{
holder.btn.setEnabled(true);
holder.pb.setProgress(0);
holder.tv.setText("未下載");
holder.btn.setText("下載");
}else
{ if (state==true)
{
holder.btn.setEnabled(false);
holder.pb.setProgress(100);
holder.tv.setText("下載完成");
holder.btn.setText("下載完成");
}else
{
holder.btn.setEnabled(false);
holder.tv.setText("下載中");
holder.btn.setText("下載中");
}
}
final ProgressBar pb = holder.pb;
final TextView tv = holder.tv;
final Button btn = holder.btn;
//用匿名內(nèi)部類的方法寫按鈕的監(jiān)聽事件
holder.btn.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
//文件下載異步事件的創(chuàng)建與開啟
FileAsy fileAsy = new FileAsy(tv, pb, btn, position);
fileAsy.execute(fileurl.get(position));//帶上了行號。
}
});
return view;
}
}
// 下載文件的異步任務(wù)
class FileAsy extends AsyncTask
{
TextView tv;
ProgressBar pb;
Button btn;// 把Button 傳入到下載文件的異步任務(wù)里,為了能夠控制Button的狀態(tài)
private int position;
public FileAsy(TextView tv, ProgressBar pb, Button btn, int position) {
super();
this.tv = tv;
this.pb = pb;
this.btn = btn;
this.position = position;
}
// 保存路徑
String savepath = Environment.getExternalStorageDirectory() + "/wenjian.apk";
private String result;
// 執(zhí)行在doInBackgound之前
@Override
protected void onPreExecute()
{
btn.setEnabled(false);
btn.setText("下載");
stateMap.put(position, false);//文件每一行的下載狀態(tài)
super.onPreExecute();
}
@SuppressWarnings("resource")
@Override
protected String doInBackground(String... params)
{
try {
URL url = new URL(params[0]);
// 打開鏈接
URLConnection connection = url.openConnection();
int length = connection.getContentLength();
InputStream is = connection.getInputStream();
// File file = new File(savepath);
String savePath3 = getSavePath(params[0]);
FileOutputStream fos = new FileOutputStream(savePath3);
byte[] buffer = new byte[1024];
int len = 0;
int dllength = 0;// 要寫在這里
while (-1 != (len = is.read(buffer)))// 先讀取數(shù)據(jù)
{
fos.write(buffer, 0, len);// 在寫出數(shù)據(jù)
// 推送進度
dllength += len;
publishProgress(dllength * 100 / length);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
result = "下載失敗";
e.printStackTrace();
}
result = "下載成功";
return result;
}
protected void onProgressUpdate(Integer... values) {
//該判斷語句為了解決BUG:文件在下載過程中,緩慢上下滑動LiseView,沒有點下載的行出現(xiàn)了對應(yīng)的下載的狀態(tài)。
//只要Button當(dāng)前行去
if (isVisiablePositon(listView, position)) {
pb.setProgress(values[0]);
tv.setText("已下載" + values[0] + "%");
}
super.onProgressUpdate(values);
}
// 下載完成后,根據(jù)位圖去更新圖片
protected void onPostExecute(String result)
{
Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
if (isVisiablePositon(listView, position))
{
btn.setEnabled(true);
btn.setText("下載完成");
}
stateMap.put(position, true);
super.onPostExecute(result);
}
}
// 下載圖片
class ImgAsy extends AsyncTask
{
private Bitmap bitmap;
private ImageView iv;
private int position;// 加入一個行號的參數(shù)
public ImgAsy(ImageView iv, int position) {
super();
this.iv = iv;
this.position = position;
}
/**
* 問題:下載過程中,上下滑動ListView,等待下載完成,有些行的圖片不顯示
原因:上下滑動ListView,創(chuàng)建新的ImageView對象,沒有創(chuàng)建新的 AsyncTask
解決: 1.寫一個方法重新給AsyncTask中的ImageView賦值
* 通知AsyncTask更新ImageView對象
* 2.在getView()中調(diào)用
*/
public void changView(ImageView iv) {
this.iv = iv;
}
@Override
protected Bitmap doInBackground(String... params) {
try {
URL url = new URL(params[0]);
InputStream is = url.openStream();// 開流
bitmap = BitmapFactory.decodeStream(is);// 下載位圖
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bitmap;// 相當(dāng)于handlermessage
}
// 下載完成后,根據(jù)位圖去更新圖片(寫在內(nèi)部類里)
protected void onPostExecute(Bitmap bitmap) {
isVisiablePositon(listView, position);
if (isVisiablePositon(listView, position)) {
iv.setImageBitmap(bitmap);
}
imgmap.put(dataList.get(position), bitmap);// 保存
super.onPostExecute(bitmap);
}
}
// 寫一個方法判斷當(dāng)前行是否可見。讓數(shù)據(jù)更新只在當(dāng)前行進行。返回值是Boolean類型
public Boolean isVisiablePositon(ListView listView, int position) {
// 獲得可見行第一行行號
int fp = listView.getFirstVisiblePosition();
// 獲得可見行最后一行行號
int lp = listView.getLastVisiblePosition();
// 在構(gòu)造方法里面去添加position
// 判斷當(dāng)前行是否在可見范圍
if (position >= fp && position <= lp) {// 讓可見行去更新控件
// iv.setImageBitmap(bitmap);
return true;//返回真,結(jié)束方法
}
return false;
}
// 優(yōu)化2,減少控件的查找.封裝一個類包含所有的控件
class ViewHolder {
ImageView iv;
Button btn;
TextView tv;
ProgressBar pb;
}
}