閱讀908 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Android 自定義Progress Bar

Android 提供ProgressDialog,可以提示進度,但你也可以自己實現,示例如下:

 


<?xml version="1.0" encoding="utf-8"?>  
<RelativeLayout xmlns:andro  
    android:layout_gravity="center_vertical" android:layout_width="fill_parent"  
    android:layout_height="wrap_content">  
    <ProgressBar android:layout_width="wrap_content"  
        android:layout_height="wrap_content" android:  
        android:scaleType="fitCenter" android:layout_alignParentLeft="true"  
        android:layout_margin="5dip" />  
  
  
    <ProgressBar android:layout_width="fill_parent"  
        android:layout_height="wrap_content"   
        android: android:max="100"  
        android:layout_toRightOf="@id/progressbar_default"  
        android:layout_margin="5dip" />  
    <TextView android:layout_width="fill_parent"  
        android:layout_height="wrap_content" android:  
        android:layout_toRightOf="@id/progressbar_default" android:paddingTop="25dip"  
        android:layout_margin="5dip" android:text="init text"/>  
</RelativeLayout>  

public class ClearProgressDialog extends AlertDialog implements  
        DialogInterface.OnClickListener {  
  
    private ProgressBar progressBar;  
    private int progress = 0;  
  
    protected ClearProgressDialog(Context context) {  
        super(context);  
  
        init();  
    }  
  
    public ClearProgressDialog(Context context, boolean cancelable,  
            OnCancelListener cancelListener) {  
        super(context, cancelable, cancelListener);  
        init();  
    }  
  
    public ClearProgressDialog(Context context, int theme) {  
        super(context, theme);  
        init();  
    }  
  
    public void init() {  
        View view = getLayoutInflater().inflate(R.layout.progresslayout,  
                null);  
        progressBar = (ProgressBar) view.findViewById(R.id.progressbar_Horizontal);  
        setButton(getContext().getText(R.string.stop), this);  
        setIcon(R.drawable.andclear);  
        setTitle(R.string.clear_progress);  
        setView(view);  
        //progressBar = (ProgressBar) findViewById(R.id.progressbar_Horizontal);  
  
    }  
  
    public void onClick(DialogInterface dialog, int which) {  
  
    }  
  
    Handler pHandle = new Handler() {  
        public void handleMessage(Message msg) {  
  
        }  
    };  
  
    public void setProgress(int per, String str) {  
  
    }  
  
    public void stop() {  
  
    }  
  
}  


重寫android.app.ProgressDialog實現自定義進度條彈出框布局

1.簡介係統ProgressDialog的主要特征
1.在ProgressDialog的源碼裏可以明顯的看到,在STYLE_HORIZONTAL和STYLE_SPINNER分別顯示的是不同的XML,這就意味著你的進度條要麼是轉圈,要麼是條形的。
2.不管是上述的任何情況下,係統對各部分文字顯示都已經完全格式化。

2.實際情況
但是實際的應用中,我們或者需要改變文字的位置,或者需要轉圈和條形共存,甚至是做出完全顛覆係統進度條的個性進度條,這個時候我們必須去重新設計屬於你自己的進度條。(個人一直認為應用中的組件盡量不用係統的,而是重寫係統的,這樣做出來的應用才是百家爭鳴)。
下麵就實現我自己的進度條中碰到的幾個可能需要注意的地方給大家交待下:
1.在係統ProgressDialog的構造函數

  1. public ProgressDialog(Context 
  2. context) 
  3. <P p 
  4. {

  5. this(context, 
  6. com.android.internal.R.style.Theme_Dialog_Alert);

  7. }
複製代碼
中涉及了一個theme:com.android.internal.R.style.Theme_Dialog_Alert,這是我當時遇到的第一個問題,開始的時候翻遍源碼,終於在data/res/values/themes.xml裏找到,
  1. <style name="Theme.Dialog.Alert"><item name="windowBackground">@android:color/transparent</item> 

  2. <item name="windowTitleStyle">@android:style/DialogWindowTitle</item> 

  3. <item name="windowIsFloating">true</item> 

  4. <item name="windowContentOverlay">@null</item> 

  5. </style>
複製代碼
但是發現他還關聯其他style,繼續找下去,結果寫到自己的XML裏還是錯誤一大堆,最後仔細看了下,發現不就是個theme嗎,這就簡單了,有2種方向:1.自己寫theme.2.使用係統的theme。我寫的時候是
  1. public ProgressDialog1(Context context) {
  2.        this(context, android.R.style.Theme_Panel);
  3.         mContext = context;
  4.         }
複製代碼
調用係統的android.R.style.Theme_Panel.
注意:找個地方就是你個性釋放的開始。
2.我要實現的是轉圈和條形並存。那麼肯定得在布局文件上下手了。
找個地方分2塊說.第1,布局是XML文件;2,布局是代碼生成。
您可能會問,這有區別嗎?事實上,區別還是蠻大的,不知道你注意到沒有如下屬性

試問,如何代碼實現?
先說第1種,XML的話比較簡單,因為隻需要寫2個ProgressBar,然後再在代碼裏控製visible屬性就ok,在此不贅述。
第2種,style的實現,這是我碰到的第2個難點
最後我在網上找到1篇文章,關於獲取父類私有屬性的文章,利用反射機製實現了style的設置。
以下工具類是轉載網上那位朋友的工具類,大家可以借鑒下!
  1. public class BeanUtils {
  2. private BeanUtils() {
  3. }
  4. public static void setFieldValue(final Object object,
  5.    final String fieldName, final Object value) {
  6.   Field field = getDeclaredField(object, fieldName);
  7.   if (field == null)
  8.    throw new IllegalArgumentException("Could not find field ["
  9.      + fieldName + "] on target [" + object + "]");
  10.   makeAccessible(field);
  11.   try {
  12.    field.set(object, value);
  13.   } catch (IllegalAccessException e) {
  14.   }
  15. }
  16. protected static Field getDeclaredField(final Object object,
  17.    final String fieldName) {
  18.   return getDeclaredField(object.getClass(), fieldName);
  19. }
  20. protected static Field getDeclaredField(final Class clazz,
  21.    final String fieldName) {
  22.   for (Class superClass = clazz; superClass != Object.class; superClass = superClass
  23.     .getSuperclass()) {
  24.    try {
  25.     return superClass.getDeclaredField(fieldName);
  26.    } catch (NoSuchFieldException e) {
  27.    }
  28.   }
  29.   return null;
  30. }
  31. protected static void makeAccessible(Field field) {
  32.   if (!Modifier.isPublic(field.getModifiers())
  33.     || !Modifier.isPublic(field.getDeclaringClass().getModifiers())) {
  34.    field.setAccessible(true);
  35.   }
  36. }
  37. }
複製代碼
有了上麵的工具類,就可以簡單的設置那些私有屬性
比如:        
BeanUtils.setFieldValue(progress_h, "mOnlyIndeterminate", new Boolean(false));
        BeanUtils.setFieldValue(progress_h, "mMinHeight", new Integer(15));


以上就是我重寫進度條的全部心得,希望能對閱讀完得朋友有些許幫助!

最後附上我的demo,裏麵我的調用的布局是代碼實現的,當然也有XML的。

demo說明:功能是前30條形,30-70轉圈,70-100條形  文字跟著變

源碼:https://files.cnblogs.com/shanzei/TestProgress.rar

最後更新:2017-04-03 22:15:27

  上一篇:go Chrome 25 被黑客攻破 Google發布緊急更新
  下一篇:go 13大已被揭穿的IT安全謠言