編輯:關於Android編程
1.本文將向你介紹自定義進度條的寫法,比較簡單,但還是有些知識點是需要注意的:
invalidate()方法
RectF方法的應用
onMeasure方法的應用
2.原理
畫3層圓角矩形,底層為黑色,第二層為灰色,最上一層為進度條顏色,示例圖如下:
3.效果圖
實現圓角進度條還有很多其他方法,比如在Progress控件裡填充圓角圖片,通過拉伸圖片來達到預想的效果,雖然聽起來很簡單,但實現起來還是有些麻煩的。
4.解說方法
(1)invalidate()方法
invalidate()是用來刷新View的,必須是在UI線程中進行工作。比如在修改某個view的顯示時, 調用invalidate()才能看到重新繪制的界面。invalidate()的調用是把之前的舊的view從主UI線程隊列中pop掉。一般在自定義控件中會用到這個方法。
(2)RectF方法的應用
RectF是用來繪畫矩形的方法。
RectF(left,top,right,bottom),四個參數的含義分別是父控件距離矩形左上右下邊距的距離,以下用圖來說明:
drawRoundRect方法是用來繪制圓角矩形的,它的參數如下:
參數說明
rect:RectF對象。
rx:x方向上的圓角半徑。
ry:y方向上的圓角半徑。
paint:繪制時所使用的畫筆。
(3)onMeasure方法
指定自定義控件在屏幕上的大小,onMeasure方法的兩個參數是由上一層控件 傳入的大小,而且是模式和尺寸混合在一起的數值,需要MeasureSpec.getMode(widthMeasureSpec) 得到模式,MeasureSpec.getSize(widthMeasureSpec)得到尺寸。
onMeasure的幾種模式分別為EXACTLY,AT_MOST,UNSPECIFIED。
[1]MeasureSpec.EXACTLY
MeasureSpec.EXACTLY是精確尺寸,當我們將控件的layout_width或layout_height指定為具體數值時如andorid:layout_width=”50dip”,或者為FILL_PARENT是,都是控件大小已經確定的情況,都是精確尺寸。
[2]MeasureSpec.AT_MOST
MeasureSpec.AT_MOST是最大尺寸,當控件的layout_width或layout_height指定為WRAP_CONTENT時,控件大小一般隨著控件的子空間或內容進行變化,此時控件尺寸只要不超過父控件允許的最大尺寸即可。因此,此時的mode是AT_MOST,size給出了父控件允許的最大尺寸。
[3]MeasureSpec.UNSPECIFIED
MeasureSpec.UNSPECIFIED是未指定尺寸,這種情況不多,一般都是父控件是AdapterView,通過measure方法傳入的模式。
5.activity_main.xml文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.progresstest.MainActivity" tools:ignore="MergeRootFrame" > <com.example.progresstest.ProgressViewTest android:id="@+id/progressbar" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
6.ProgressViewTest.java文件
package com.example.progresstest; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.util.AttributeSet; import android.view.View; public class ProgressViewTest extends View { /**進度條最大值*/ private float maxCount; /**進度條當前值*/ private float currentCount; /**畫筆*/ private Paint mPaint; private int mWidth,mHeight; public ProgressViewTest(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub } public ProgressViewTest(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } public ProgressViewTest(Context context) { super(context); // TODO Auto-generated constructor stub } /*** * 設置最大的進度值 * @param maxCount */ public void setMaxCount(float maxCount) { this.maxCount = maxCount; } /** * 得到最大進度值 */ public double getMaxCount(){ return maxCount; } /*** * 設置當前的進度值 * @param currentCount */ public void setCurrentCount(float currentCount) { this.currentCount = currentCount > maxCount ? maxCount : currentCount; /** * invalidate()是用來刷新View的,必須是在UI線程中進行工作。比如在修改某個view的顯示時, * 調用invalidate()才能看到重新繪制的界面。invalidate()的調用是把之前的舊的view從主UI * 線程隊列中pop掉。 */ invalidate(); } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); mPaint = new Paint(); //設置抗鋸齒效果 mPaint.setAntiAlias(true); //設置畫筆顏色 mPaint.setColor(Color.BLACK); int round = mHeight/2; /** * RectF:繪制矩形,四個參數分別是left,top,right,bottom * 類型是單精度浮點數 */ RectF rf = new RectF(0, 0, mWidth, mHeight); /*繪制圓角矩形,背景色為畫筆顏色*/ canvas.drawRoundRect(rf, round, round, mPaint); /*設置progress內部是灰色*/ mPaint.setColor(Color.rgb(211, 211, 211)); RectF rectBlackBg = new RectF(2, 2, mWidth-2, mHeight-2); canvas.drawRoundRect(rectBlackBg, round, round, mPaint); //設置進度條進度及顏色 float section = currentCount/maxCount; RectF rectProgressBg = new RectF(3, 3, (mWidth-3)*section, mHeight-3); if(section!=0.0f){ mPaint.setColor(Color.GREEN); }else{ mPaint.setColor(Color.TRANSPARENT); } canvas.drawRoundRect(rectProgressBg, round, round, mPaint); } //dip * scale + 0.5f * (dip >= 0 ? 1 : -1) private int dipToPx(int dip){ float scale = getContext().getResources().getDisplayMetrics().density; return (int) (dip * scale + 0.5f * (dip >= 0 ? 1 : -1));//加0.5是為了四捨五入 } /**指定自定義控件在屏幕上的大小,onMeasure方法的兩個參數是由上一層控件 * 傳入的大小,而且是模式和尺寸混合在一起的數值,需要MeasureSpec.getMode(widthMeasureSpec) * 得到模式,MeasureSpec.getSize(widthMeasureSpec)得到尺寸 * */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec); int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec); //MeasureSpec.EXACTLY,精確尺寸 if (widthSpecMode == MeasureSpec.EXACTLY || widthSpecMode == MeasureSpec.AT_MOST) { mWidth = widthSpecSize; } else { mWidth = 0; } //MeasureSpec.AT_MOST,最大尺寸,只要不超過父控件允許的最大尺寸即可,MeasureSpec.UNSPECIFIED未指定尺寸 if (heightSpecMode == MeasureSpec.AT_MOST || heightSpecMode == MeasureSpec.UNSPECIFIED) { mHeight = dipToPx(20); } else { mHeight = heightSpecSize; } //設置控件實際大小 setMeasuredDimension(mWidth, mHeight); } }
MainActivity.java文件
package com.example.progresstest; import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.os.Handler; import android.os.Message; public class MainActivity extends ActionBarActivity { private ProgressViewTest progress; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); progress = (ProgressViewTest) findViewById(R.id.progressbar); progress.setMaxCount(100); new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub for (int i = 0; i <=progress.getMaxCount(); i++) { Message msg = new Message(); msg.arg1 = i; msg.what = 0x01; handler.sendMessage(msg); try { //每隔0.1秒進度前進1 Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }).start(); } Handler handler = new Handler(){ public void handleMessage(Message msg) { if(msg.what==0x01){ progress.setCurrentCount(msg.arg1); } }; }; }
以上所述是小編給大家介紹的Android自定義進度條的圓角橫向進度條實例詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對本站網站的支持!
流程圖盜張網上的流程圖源碼分析構建RequestQueueVolley 的調用比較簡單,通過 newRequestQueue(…) 函數新建並啟動一個請求隊
環境主機:WIN 7開發環境:Android Studio2.2.2步驟安裝NDK打開Tools->Android->SDK Manager->SDK
1、前言 等級信號狀態的View在現在的Android系統中非常的常見,比如手機右上角的電池狀態的圖標就非常的經典,有幾種狀態,到了快沒電的時候有些還會閃爍提示用戶充電;
引言前面一篇文章介紹了二級Preference的使用和特點,接下來進入系統給我提供的底級Preference的使用CheckBox選擇項CheckBoxPreferenc