Android ListView內嵌ProgressBar最簡示例

沒廢話,先上效果圖,再貼代碼,可直接移植到自己軟件工程中!

Android ListView內嵌ProgressBar最簡示例


  • 第一步,創建佈局文件(activity_main.xml)
<code>
<relativelayout> android:layout_width="match_parent"
android:layout_height="match_parent">
<listview> android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
/<listview>
/<relativelayout>/<code>
  1. 第二步,創建MainActivity,用於啟動程序和模擬數據源
<code>import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.activity_main);

ListView listView = findViewById(R.id.list_view);

// 模擬 ListView 顯示的數據源
List<lvrowdata> lvRowDataList = new ArrayList<>();
for (int i = 0; i < 20; i++) {
LVRowData lvRowData = new LVRowData();
lvRowData.status = LVRowData.NOACTION;
lvRowData.progress = -1;
lvRowDataList.add(lvRowData);
}

// ListView 數據容器

LVAdapter lvAdapter = new LVAdapter(this, lvRowDataList);
listView.setAdapter(lvAdapter);
}

}/<lvrowdata>/<code>
  • 第三步,創建ListView每一行佈局文件(listview_item.xml)
<code>
<linearlayout> android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:orientation="horizontal">

<relativelayout> android:id="@+id/rl_pro"
android:layout_width="100dp"
android:layout_height="25dp"
android:layout_marginEnd="12dp"
android:layout_gravity="center"
android:gravity="center">

<progressbar> android:id="@+id/progress_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/progressBar_multiDownload"
android:max="100"
android:minHeight="25dp"
android:progressDrawable="@drawable/progress_bg_list" />

<textview> android:id="@+id/tv_donwload"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="下載"
android:textColor="#F88C08" />
/<textview>/<progressbar>/<relativelayout>
/<linearlayout>/<code>
  • 第四步,創建ProgressBar的顯示效果
<code>    <style><br>        <item name="android:indeterminateOnly">false</item>    <!--  屬性表示進度值是否確定,true表示不確定,false表示確定  --><br>        <item name="android:progressDrawable">@drawable/progressbar_multidownload_progress</item>    <!--  設置進度中的背景顏色和進度顏色 --><br>        <item name="android:indeterminateDrawable">@drawable/progressbar_multidownload_indeterminate</item>   <!--  設置進度的動畫效果 --><br>        <item name="android:minHeight">20dip</item><br>        <item name="android:maxHeight">20dip</item><br>    /<style>/<code> 
<code>
<layer-list>

<item>
<shape>
<corners>
<gradient> android:startColor="#ff9d9e9d"
android:centerColor="#ff5a5d5a"
android:centerY="0.75"
android:endColor="#ff747674"
android:angle="270"
/>
/<gradient>/<shape>
/<item>

<item>
<clip>
<shape>
<corners>
<gradient> android:startColor="#80ffd300"
android:centerColor="#80ffb600"
android:centerY="0.75"
android:endColor="#a0ffcb00"
android:angle="270"
/>
/<gradient>/<shape>
/<clip>
/<item>

<item>
<clip>
<shape>
<corners>
<gradient> android:startColor="#ffffd300"
android:centerColor="#ffffb600"
android:centerY="0.75"
android:endColor="#ffffcb00"
android:angle="270"
/>
/<gradient>/<shape>
/<clip>
/<item>

/<layer-list>

/<code>
<code> 

<layer-list>

<item>
<shape>
<corners>
<gradient> android:startColor="#ff9d9e9d"
android:centerColor="#ff5a5d5a"
android:centerY="0.75"
android:endColor="#ff747674"
android:angle="270"
/>
/<gradient>/<shape>
/<item>

<item>
<clip>
<shape>
<corners>
<gradient> android:startColor="#80ffd300"
android:centerColor="#80ffb600"
android:centerY="0.75"
android:endColor="#a0ffcb00"
android:angle="270"
/>
/<gradient>/<shape>
/<clip>
/<item>

<item>
<clip>
<shape>
<corners>
<gradient> android:startColor="#ffffd300"
android:centerColor="#ffffb600"
android:centerY="0.75"
android:endColor="#ffffcb00"
android:angle="270"
/>
/<gradient>/<shape>
/<clip>
/<item>

/<layer-list>

/<code>
  • 第五步,創建每一行的數據類(LVRowData)
<code>/**
* ListView 每一行對應的數據,封裝在一個類中,用於保存每一行的數據
*/
class LVRowData {
static final int NOACTION = -1;
static final int WAITING = 1000;
static final int DOWNLOADING = 2000;
static final int PAUSE = 2001;
static final int DONE = 2002;
static final int EXIT = 3000;
static final int EXCEPTION = 4000;

Integer progress; // 用於保存下載進度
String text; // 用於保存按鈕文字
Integer status; // 進度條標誌
}/<code>
  • 第六步,創建數據容器(LVAdapter)
<code>import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ProgressBar;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class LVAdapter extends BaseAdapter {
private Context mContext;
private List<lvrowdata> lvRowDataList; // 需要顯示的數據源
private List<view> lvRowViewList; // 存放每一行的View,通過這個 view 根據 position 就可以找到對應的具體控件

public LVAdapter(Context context, List<lvrowdata> lvRowDataList) {
this.mContext = context;

this.lvRowViewList = new ArrayList<>();
this.lvRowDataList = lvRowDataList;
}

@Override
public int getCount() {
return lvRowDataList.size();
}

@Override
public Object getItem(int position) {
return lvRowDataList.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder; // 將當前 convertView 內控件全部放入 ViewHolder 類中保存
// 初始化控件
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.listview_item, parent, false);

viewHolder = new ViewHolder();
viewHolder.progressBar = convertView.findViewById(R.id.progress_bar);
viewHolder.textView = convertView.findViewById(R.id.tv_donwload);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}

// 添加當前 convertView 內各個控件的顯示內容
final LVRowData lvRowData = lvRowDataList.get(position);
switch (lvRowData.status) {
case LVRowData.DONE: viewHolder.textView.setText("下載完成"); break;
case LVRowData.DOWNLOADING: viewHolder.textView.setText("下載中"); break;
case LVRowData.EXCEPTION: viewHolder.textView.setText("異常"); break;
case LVRowData.EXIT: viewHolder.textView.setText("退出"); break;
case LVRowData.NOACTION: viewHolder.textView.setText("開始"); break;
case LVRowData.PAUSE: viewHolder.textView.setText("下載暫停"); break;
case LVRowData.WAITING: viewHolder.textView.setText("等待下載"); break;
default: break;

}
viewHolder.progressBar.setProgress(lvRowData.progress);

// 事件處理
viewHolder.textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

switch(lvRowData.status) {
case LVRowData.NOACTION:
if(lvRowData.progress <= 0) {
lvRowData.status = LVRowData.WAITING;
((TextView)view).setText("等待下載");
}

if(lvRowData.progress == -1) {
lvRowData.progress = 0;
lvRowData.status = LVRowData.WAITING;
AsyncUpdateProBar asyncTask = new AsyncUpdateProBar(lvRowViewList, position); // 如果未開始下載,啟動異步下載任務
asyncTask.executeOnExecutor(AsyncUpdateProBar.THREAD_POOL_EXECUTOR, lvRowData); // 添加THREAD_POOL_EXECUTOR可啟動多個異步任務
}
break;
case LVRowData.WAITING: lvRowData.status = (lvRowData.progress > 0) ? LVRowData.DOWNLOADING : LVRowData.WAITING; break;
case LVRowData.DOWNLOADING: lvRowData.status = (lvRowData.progress > 0 && lvRowData.progress < 100) ? LVRowData.PAUSE : lvRowData.status; break;
case LVRowData.PAUSE: lvRowData.status = (lvRowData.progress > 0 && lvRowData.progress < 100) ? LVRowData.DOWNLOADING : lvRowData.status; break;
case LVRowData.DONE: break;
case LVRowData.EXIT: break;
case LVRowData.EXCEPTION: break;
default:
}
}
});

// 將 list_view 的ID作為 Tag 的Key值,position作為值記錄在 RowView組件中
convertView.setTag(R.id.list_view, position);
lvRowViewList.add(convertView);

return convertView;
}

/**
* 用於緩存 rowView
*/
class ViewHolder {
ProgressBar progressBar;

TextView textView;
}
}/<lvrowdata>/<view>/<lvrowdata>/<code>
  • 第七步,創建多線程,動態更新ListView(AsyncUpdateProBar)
<code>import android.os.AsyncTask;
import android.view.View;
import java.util.List;


public class AsyncUpdateProBar extends AsyncTask<lvrowdata> {
private LVRowData lvRowData; // 單個數據,用於完成後的處理
private List<view> lvRowViewList; // 視圖對象集合,用於設置樣式
private Integer rowViewPosition; // 視圖標識,用於匹配視圖對象

public AsyncUpdateProBar(List<view> lvRowViewList, Integer rowViewPosition) {
this.lvRowViewList = lvRowViewList;
this.rowViewPosition = rowViewPosition;
}

@Override
protected void onPreExecute() {
super.onPreExecute();
}

@Override
protected Void doInBackground(LVRowData... params) {

this.lvRowData = params[0];

// 動態更新進度條
for (int i = 0; i <= 100; ) {
try {
Thread.sleep(100);
publishProgress(i); // 更新界面
if(this.lvRowData.status != LVRowData.PAUSE) {
i++;
if(i< 100) {
this.lvRowData.status = LVRowData.DOWNLOADING;
} else {
this.lvRowData.status = LVRowData.DONE;

}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}

@Override
protected void onProgressUpdate(Integer... values) {
View rowView = null;

// 匹配 rowView 編號,確定更新哪個 rowView
for (int i = 0; i < lvRowViewList.size(); i++) {
if (lvRowViewList.get(i).getTag(R.id.list_view) == rowViewPosition) { // 檢查所有視圖ID,如果ID匹配則取出該對象
rowView = lvRowViewList.get(i);
break;
}
}

if (rowView != null) {
LVAdapter.ViewHolder viewHolder = (LVAdapter.ViewHolder) rowView.getTag(); // 將視圖對象中緩存的ViewHolder對象取出,並使用該對象對控件進行更新
viewHolder.progressBar.setProgress(values[0]);

switch (lvRowData.status) {
case LVRowData.NOACTION: viewHolder.textView.setText("開始"); break;
case LVRowData.WAITING: viewHolder.textView.setText("等待下載"); break;
case LVRowData.DOWNLOADING: viewHolder.textView.setText(values[0] + "%"); break;
case LVRowData.PAUSE: viewHolder.textView.setText("下載暫停"); break;
case LVRowData.DONE: viewHolder.textView.setText("下載完成"); break;
case LVRowData.EXIT: viewHolder.textView.setText("退出"); break;
case LVRowData.EXCEPTION: viewHolder.textView.setText("異常"); break;
default: break;
}
}
lvRowData.progress = values[0];
}

@Override
protected void onPostExecute(Void aVoid) {
lvRowData.progress = 100; // 更新數據源信息

}
}/<view>/<view>/<lvrowdata>/<code>
  • 第八步,運行


分享到:


相關文章: