一步一步学android控件(之二十三)—— ProgressBar
来源:互联网 发布:php活动报名系统源码 编辑:程序博客网 时间:2024/05/19 19:34
android中内置了多种风格的ProgressBar(进度条) ,通过style属性设置其样式:
默认的样式
圆形稍大一点的ProgressBar , style="?android:attr/progressBarStyleLarge"
水平的ProgressBar , style="?android:attr/progressBarStyleHorizontal"
我们可以将ProgressBar的样式分为两大类型:
1、圆形动画: 一般用于一些未知“长度”的任务,仅仅表示正在处理任务,但是不知道任务进行到了何处 。
2、水平进度条:一般用于要显示中间进度。条件:知道任务的长度;当前任务完成度。
本文结合两个实例来学习progressBar。
1、定位 + 自定义 圆形动画的 progressBar
点击“位置服务”时,启动一个线程去加载用户的位置信息,同时显示圆形动画的progressBar。位置信息加载“完成”后发送一个消息更新UI——显示用户位置信息或者显示定位出错信息。
2、文件读取 + 自定义样式的水平progressBar + 文件内容显示
点击“文件操作”时,启动一个线程读取文件中的信息。所有读取出来的信息,一个字符一个字符的写到TextView中(为了能够清晰的看清楚操作进度 , 每写一个字符线程休眠500毫秒:
下面一步一步实现上述功能。
1、准备一个文件test_file.txt放到assets目录下
中文测试字符。First line .second line .third line .forth line .fifth line .sixth line .seventh line .eighth line .ninth line .tenth line .2、创建布局文件widget_progressbar_layout.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/load_location_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/str_location_service" /> <Button android:id="@+id/load_file_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/str_file_op" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="50dp" android:orientation="horizontal" > <ProgressBar android:id="@+id/location_progress_bar" style="@style/customer_progress_style" android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="invisible" /> <TextView android:id="@+id/location_text_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:visibility="invisible" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="150dp" android:orientation="vertical" > <ProgressBar android:id="@+id/file_reader_progress" android:layout_width="match_parent" android:layout_height="wrap_content" android:visibility="invisible" style="@style/customer_progress_style_horizontal" /> <!-- style="?android:attr/progressBarStyleHorizontal" --> <TextView android:id="@+id/file_content_text_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:visibility="visible" /> </LinearLayout></LinearLayout>布局文件中有两个progressBar :
2.1 自定义圆形动画的progressBar : android:id="@+id/location_progress_bar" 为位置服务的progressBar 其使用了样式 style="@style/customer_progress_style" ,该样式定义在res/values/styles.xml 中
<style name="customer_progress_style" > <item name="android:indeterminateDrawable">@drawable/progress_style_circle_anim</item> </style>
style中使用了自定义的drawable ——progress_style_circle_anim.xml , 其内容如下:
<?xml version="1.0" encoding="utf-8"?><rotate xmlns:android="http://schemas.android.com/apk/res/android" android:duration="500" android:fromDegrees="0" android:pivotX="50%" android:pivotY="50%" android:repeatCount="-1" android:repeatMode="reverse" android:toDegrees="360" > <shape xmlns:android="http://schemas.android.com/apk/res/android" android:dither="true" android:innerRadiusRatio="4" android:shape="ring" android:thicknessRatio="20" android:useLevel="false" > <padding android:bottom="5dp" android:left="5dp" android:right="5dp" android:top="5dp" /> <stroke android:dashGap="3dp" android:dashWidth="7dp" android:color="#FFFF00" /> <gradient android:centerColor="@color/pregress_style_center_color" android:centerX="50%" android:centerY="50%" android:endColor="@color/pregress_style_end_color" android:startColor="@color/pregress_style_start_color" android:type="sweep" /> </shape></rotate>2.2 自定义水平样式的progressBar : android:id="@+id/file_reader_progress" 为显示文件操作进度的progressBar , 其使用了样式 style="@style/customer_progress_style_horizontal" ,该样式定义在res/values/styles.xml 中
<style name="customer_progress_style_horizontal" parent="android:Widget.ProgressBar.Horizontal"> <item name="android:progressDrawable">@drawable/horizontal_progress_bar_style</item> <item name="android:indeterminateOnly">false</item> <item name="android:minHeight">10dip</item><item name="android:maxHeight">10dip</item> </style>style中使用自定义的progressDrawable——horizontal_progress_bar_style,其内容如下:
<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@android:id/background"> <shape> <corners android:radius="3dip" /> <gradient android:angle="270" android:centerColor="#ffBBBBBB" android:centerY="0.75" android:endColor="#ffCC66FF" android:startColor="#ffDDDDDD" /> </shape> </item> <item android:id="@android:id/secondaryProgress"> <clip> <shape> <corners android:radius="3dip" /> <gradient android:angle="270" android:centerColor="#ffffb600" android:centerY="0.75" android:endColor="#ffffcb00" android:startColor="#ffffd300" /> </shape> </clip> </item> <item android:id="@android:id/progress"> <clip> <shape> <corners android:radius="5dip" /> <gradient android:angle="90" android:centerColor="#ff00ff00" android:centerY="0.75" android:endColor="#ffffffff" android:startColor="#3fF0ff30" /> </shape> </clip> </item></layer-list>
3、 创建activity——WidgetProgressBarActivity.java
package com.xy.zt.selfdefinewieget;import android.app.Activity;import android.content.Context;import android.content.res.AssetManager;import android.location.Address;import android.location.Geocoder;import android.location.Location;import android.location.LocationListener;import android.location.LocationManager;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ProgressBar;import android.widget.TextView;import android.widget.Toast;import org.apache.http.util.EncodingUtils;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.util.List;public class WidgetProgressBarActivity extends Activity implements OnClickListener, LocationListener { public static final int MSG_REFRESH_LOCATION_UI = 1; public static final int MSG_REFRESH_FILE_OP_UI = 2; private Button mLocationBtn; private Button mFileBtn; private ProgressBar mLocationProgress; private ProgressBar mFileProgress; private TextView mLcationTv; private TextView mFileTv; private LocationManager mLocManager; private LocationTaskThread mLocationThread; private FileReaderThread mFileThread; private Handler mRefreshHandler = new Handler() { private boolean isProMaxSetted = false; @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_REFRESH_LOCATION_UI: mLcationTv.setText((String) msg.obj); mLocationProgress.setVisibility(View.GONE); mLcationTv.setVisibility(View.VISIBLE); mFileBtn.setClickable(true); break; case MSG_REFRESH_FILE_OP_UI: Bundle data = msg.getData(); if (data == null || !data.containsKey(READ_CHARACTOR)) { Toast.makeText(WidgetProgressBarActivity.this, (String) msg.obj, Toast.LENGTH_SHORT).show(); } else { mFileTv.setVisibility(View.VISIBLE); int count, size; char charactor; count = data.getInt(FILE_READ_LENGTH_KEY); size = data.getInt(FILE_LENGTH_KEY); charactor = data.getChar(READ_CHARACTOR); if (!isProMaxSetted) { mFileProgress.setMax(size); } mFileProgress.setProgress(count); mFileProgress.setSecondaryProgress(1 + count); mFileTv.setText(mFileTv.getText().toString() + charactor); if (count >= size) { mLocationBtn.setClickable(true); } } break; } } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.widget_progressbar_layout); init(); mLocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); try { mLocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000l, 0f, this); mLocManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000l, 0f, this); } catch (IllegalArgumentException e) { } } private void init() { mFileProgress = (ProgressBar) findViewById(R.id.file_reader_progress); mLocationProgress = (ProgressBar) findViewById(R.id.location_progress_bar); mLocationBtn = (Button) findViewById(R.id.load_location_btn); mLocationBtn.setOnClickListener(this); mFileBtn = (Button) findViewById(R.id.load_file_btn); mFileBtn.setOnClickListener(this); mLcationTv = (TextView) findViewById(R.id.location_text_view); mFileTv = (TextView) findViewById(R.id.file_content_text_view); } public void onClick(View v) { switch (v.getId()) { case R.id.load_location_btn: if (mLocationThread == null || mLocationThread.isThreadEnd) { mLocationThread = new LocationTaskThread(this, mLocManager, mRefreshHandler.obtainMessage(MSG_REFRESH_LOCATION_UI), this); mLocationThread.start(); } else { Toast.makeText(this, "后台线程正在加载位置信息,请稍等 !...", Toast.LENGTH_SHORT).show(); return; } mFileProgress.setVisibility(View.GONE); mFileTv.setVisibility(View.GONE); mLocationProgress.setVisibility(View.VISIBLE); mFileBtn.setClickable(false); break; case R.id.load_file_btn: if (mFileThread == null || mFileThread.isTeminated) { mFileThread = new FileReaderThread(this, mRefreshHandler.obtainMessage(MSG_REFRESH_FILE_OP_UI)); mFileThread.start(); } else { Toast.makeText(this, "后台线程正在读取文件信息,请稍等 !...", Toast.LENGTH_SHORT).show(); return; } mFileTv.setText(""); mFileProgress.setVisibility(View.VISIBLE); mFileTv.setVisibility(View.VISIBLE); mLocationProgress.setVisibility(View.GONE); mLcationTv.setVisibility(View.GONE); mLocationBtn.setClickable(false); break; } } public void onLocationChanged(Location location) { } public void onProviderDisabled(String provider) { } public void onProviderEnabled(String provider) { } public void onStatusChanged(String provider, int status, Bundle extras) { } static class LocationTaskThread extends Thread { LocationManager mLM; Message mMessage; LocationListener mLL; public boolean isThreadEnd; private Context mContext; public LocationTaskThread(Context context, LocationManager lm, Message msg, LocationListener ll) { mContext = context; mLM = lm; mMessage = msg; mLL = ll; } @Override public void run() { isThreadEnd = false; List<Address> curAddress = null; Location l = mLM.getLastKnownLocation(LocationManager.GPS_PROVIDER); if (l == null) { l = mLM.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); } if (l == null) { mMessage.obj = "Get location information failure !..."; mMessage.sendToTarget(); isThreadEnd = true; return; } else { l.getLatitude(); Geocoder coder = new Geocoder(mContext); for (int i = 0; i < 7; i++) { try { curAddress = coder.getFromLocation( l.getLatitude(), l.getLongitude(), 1); if (curAddress != null) { break; } } catch (IOException e) { Log.w("WidgetProgressBarActivity", i + " get location failed !..."); } } } if (curAddress != null) { Address address = curAddress.get(0); System.out.println(address.toString()); mMessage.obj = address.toString(); mMessage.sendToTarget(); } else { mMessage.obj = "Get location address failure !..."; mMessage.sendToTarget(); } isThreadEnd = true; } } public static final String FILE_LENGTH_KEY = "FileTotalSize"; public static final String FILE_READ_LENGTH_KEY = "ReadCount"; public static final String READ_CHARACTOR = "Charactor"; static class FileReaderThread extends Thread { private Message mMsg; private Context mContext; public boolean isTeminated; Handler mHandler; public FileReaderThread(Context context, Message msg) { mContext = context; mMsg = msg; mHandler = mMsg.getTarget(); } @Override public void run() { isTeminated = false; InputStream is = null; Bundle data = new Bundle(); try { AssetManager assets = mContext.getAssets(); is = assets.open("test_file.txt"); int lenByte = is.available(); byte[] buffer = new byte[lenByte]; is.read(buffer); String str = EncodingUtils.getString(buffer, "utf-8"); int len = str.length(); data.putInt(FILE_LENGTH_KEY, len); int count = 0; char charactor; for (int i = 0; i < len; i++) { mMsg = mHandler.obtainMessage(MSG_REFRESH_FILE_OP_UI); charactor = str.charAt(i); data.putInt(FILE_READ_LENGTH_KEY, ++count); data.putChar(READ_CHARACTOR, charactor); mMsg.setData(data); mMsg.sendToTarget(); sleep(500); } } catch (FileNotFoundException e) { mMsg.obj = "没有找到您所指定的文件!..."; mMsg.sendToTarget(); } catch (IOException e) { mMsg.obj = "读取文件数据失败!..."; mMsg.sendToTarget(); } catch (InterruptedException e) { mMsg.obj = "读取文件数据线程被异常中断!..."; mMsg.sendToTarget(); } finally { try { if (is != null) { is.close(); } } catch (IOException e) { } } isTeminated = true; } }}代码中没有太多可以说的,只有两点需要注意:
3.1 在文件操作中需要重复的想handler发送消息
for (int i = 0; i < len; i++) { mMsg = mHandler.obtainMessage(MSG_REFRESH_FILE_OP_UI); charactor = str.charAt(i); data.putInt(FILE_READ_LENGTH_KEY, ++count); data.putChar(READ_CHARACTOR, charactor); mMsg.setData(data); mMsg.sendToTarget(); sleep(500); }开始的时候没有添加如下代码
mMsg = mHandler.obtainMessage(MSG_REFRESH_FILE_OP_UI);mMsg.sendToTarget();结果老是出现NullPointerException 。
3.2 在操作assets目录下的文件时一定要用AssetsManager,使用样例代码如下
AssetManager assets = mContext.getAssets(); is = assets.open("test_file.txt");
4、 老规矩在ViewData.java中添加如下代码(此部分内容可选)
public static final int PROGRESS_BAR_ID = GRID_ID + 1; public static final String PROGRESS_BAR_NAME = "ProgressBar";private static final ViewData mProgressBar = new ViewData(PROGRESS_BAR_NAME, PROGRESS_BAR_ID);View_Datas.add(mProgressBar);
在WidgetsAdapter的handleItemClicked方法中添加如下代码
case ViewData.PROGRESS_BAR_ID: intent.setClass(mContext, WidgetProgressBarActivity.class); mContext.startActivity(intent); break;
ProgressBar控件就学到这里,下一个控件RatingBar。
- 一步一步学android控件(之二十三)—— ProgressBar
- 一步一步学android控件(之十三) —— TimePicker
- 一步一步学android控件(之二) —— TextView
- 一步一步学android控件(之二十)—— ScrollView & HorizontalScrollView
- 一步一步学android控件(之二十一)—— ListView & ExpandableListView
- 一步一步学android控件(之二十二)—— GridView
- 一步一步学android控件(之二十四)—— RatingBar
- 一步一步学android控件(之二十五)—— SeekBar
- 一步一步学android控件(之二十六)—— QuickContacBadge
- 一步一步学android控件(之二十七)—— SlidingDrawer
- 一步一步学android控件(之二十八)—— ViewFlipper
- 一步一步学android控件(之二十九)—— SearchView
- 一步一步学android控件(之三) —— Button
- 一步一步学android控件(之四) —— EditText
- 一步一步学android控件(之五) —— AutoCompleteTextView
- 一步一步学android控件(之六) —— MultiAutoCompleteTextView
- 一步一步学android控件(之七) —— Toast
- 一步一步学android控件(之八) —— ImageView
- 毕业设计
- 山寨腾讯“爱消除”游戏之声音效果
- windows2008服务器安全常规设置
- python多线程破解zip文件
- DataSource,数据库连接池
- 一步一步学android控件(之二十三)—— ProgressBar
- Visual Studio / MSBuild - 编译时根据编译条件动态引用项目及复制重命名编译输出文件
- ubuntu配置HOST
- 文本文件和二进制文件
- swing组合边框(CompoundBorder)
- Linux 入门第一篇
- Linux系统信息查看命令大全
- nginx 编译参数详解
- linux下svn命令大全