您好,登錄后才能下訂單哦!
Android中怎么自定義Button控件,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
首先***步就是往布局文件里拖一個Button控件,當然自己碼出來也可以。XML布局如下
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:id="@+id/button1" <!-- button按鈕的id號,程序通過這個id號來查找相應的控件 --> android:layout_width="wrap_content" <!-- button按鈕的寬度 當前意思是 根據內容自動拉伸,其他的還有match_parent,表示根據父控件來調整大小--> android:layout_height="wrap_content" <!-- button按鈕的長度--> android:layout_alignParentTop="true" <!-- RelativeLayout布局中,將控件的上邊緣和父控件的上邊緣對齊 --> android:layout_centerHorizontal="true"<!-- RelativeLayout布局中,水平居中的意思 --> android:layout_marginTop="150dp" <!-- RelativeLayout布局中,距離父控件頂端的距離 --> android:text="Button" /> <!-- button按鈕上顯示的文字信息 --> </RelativeLayout>
當然,一個控件的布局屬性還有很多,這些都是需要我們多用多熟悉才行。
然后再在程序中調用它
public class MainActivity extends Activity { private Button myButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //通過id尋找控件,記得尋找控件前一定要先設置好布局文件 myButton = (Button)findViewById(R.id.button1); myButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub //這里填寫單擊按鈕后要執行的事件 } }); myButton.setOnTouchListener(new OnTouchListener(){...});//設置觸碰到按鈕的監聽器 myButton.setOnLongClickListener(new OnLongClickListener(){...});//設置長按按鈕的監聽器 myButton.setOnHoverListener(new OnHoverListener(){...});//設置界面覆蓋按鈕時的監聽器 //還有其它的的監聽器,我們可以根據不同的需求來調用相應的監聽器 } }
或者這樣設置監聽器
public class MainActivity extends Activity implements OnClickListener{ private Button myButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //尋找控件,記得尋找控件前一定要先設置好布局文件 myButton = (Button)findViewById(R.id.button1); myButton.setOnClickListener(this); } @Override public void onClick(View v) { // TODO Auto-generated method stub //獲取點擊的View switch(v.getId()){ //根據View的id來進行相關操作 case R.id.button1: //按鈕點擊時處理相關的事件 break; } } }
這樣一個基礎功能的button控件就完成了。但當然,這不是我們今天要講的重點,重點是我們如何自定義一個按鈕,而不是使用系統給我們的按鈕。
二、自定義按鈕
我們先來看看效果圖吧
這是一個自帶進度條的按鈕,它可以顯示異步任務的進度,當完成后結束操作。我們來看看具體是怎么實現的吧。
拆分這個按鈕。仔細觀察上面的效果圖,我們可以把這個按鈕分成3個部分,首先是 最簡單的外面一圈圓,基本上畫出個圓放在那里就行了。接著是中間的三角形,正方形以及完成的勾,這個我們可以使用view里的畫圖類勾勒出來,再使用簡單 的動畫Animation來切換。***的一部分是覆蓋在圓圈上的不斷在表示進度的圓圈,這個我們可以不斷調用這個view的ondraw來刷新進度。這就 是整個按鈕的設計思路。我們來看看實際的代碼吧。
首先是表示進度的圓圈,我們來新建一個CusImage繼承view類,實時的傳入進度參數。
package com.example.mybutton; import android.annotation.SuppressLint; 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.util.DisplayMetrics; import android.util.Log; import android.view.View; @SuppressLint("ViewConstructor") public class CusImage extends View { private ButtonLayout b; private Paint myPaint; private float startAngle, sweepAngle; private RectF rect; // 默認控件大小 private int pix = 160; public CusImage(Context context, ButtonLayout b) { super(context); this.b = b; init(); // TODO Auto-generated constructor stub } public CusImage(Context context, AttributeSet attrs, ButtonLayout b) { super(context, attrs); this.b = b; init(); // TODO Auto-generated constructor stub } private void init() { myPaint = new Paint(); DisplayMetrics metrics = getContext().getResources() .getDisplayMetrics(); int width = metrics.widthPixels; int height = metrics.heightPixels; Log.d("TAG", width + ""); Log.d("TAG", height + ""); float scarea = width * height; pix = (int) Math.sqrt(scarea * 0.0217); //抗鋸齒 myPaint.setAntiAlias(true); //stroke表示空心,Fill表示實心 myPaint.setStyle(Paint.Style.STROKE); //顏色 myPaint.setColor(Color.rgb(0, 161, 234)); //設置線條粗細 myPaint.setStrokeWidth(7); float startx = (float) (pix * 0.05); float endx = (float) (pix * 0.95); float starty = (float) (pix * 0.05); float endy = (float) (pix * 0.95); //矩形區域 rect = new RectF(startx, starty, endx, endy); } @Override protected void onDraw(Canvas canvas) { // 畫弧線 // 在rect這個區域內畫,開始的角度,掃過的度數而不是結束的角度,false表示不與圓心連線,true通常用來畫扇形,畫筆。 canvas.drawArc(rect, startAngle, sweepAngle, false, myPaint); startAngle = -90; //小于1圈 if (sweepAngle < 360 &&b.flg_frmwrk_mode == 2) { invalidate(); }else if(b.flg_frmwrk_mode == 1){ }else {//掃完一圈,調用b.finalAnimation() sweepAngle = 0; startAngle = -90; b.finalAnimation(); } super.onDraw(canvas); } /** * 控制控件的大小 http://blog.csdn.net/pi9nc/article/details/18764863 **/ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int desiredWidth = pix; int desiredHeight = pix; int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int width; int height; // 如果控件寬度是指定大小,寬度為指定的尺寸 if (widthMode == MeasureSpec.EXACTLY) { width = widthSize; } else if (widthMode == MeasureSpec.AT_MOST) { // 沒有限制,默認內容大小 width = Math.min(desiredWidth, widthSize); } else { width = desiredWidth; } // 如果控件高度是指定大小,高度為指定的尺寸 if (heightMode == MeasureSpec.EXACTLY) { height = heightSize; } else if (heightMode == MeasureSpec.AT_MOST) {// 沒有限制,默認內容大小 height = Math.min(desiredHeight, heightSize); } else { height = desiredHeight; } // 設定控件大小 setMeasuredDimension(width, height); } // 傳入參數 public void setupprogress(int progress) { sweepAngle = (float) (progress * 3.6); } public void reset() { startAngle = -90; } }
有了表示進度的view之后,我們要在一個viewgroup控件中組裝各個部分來實現整個按鈕,這里我用的是framelayout
這里代碼寫在一起了,我把它們一個一個拎出來講解。
首先是ImageView的初始化
/** * 創建各個控件 */ private void initialise() { // 按鈕的進度條 cusView = new CusImage(getContext(), this); // 按鈕中間的形狀 buttonimage = new ImageView(getContext()); // 完成進度后顯示的圖像 fillcircle = new ImageView(getContext()); //外面一圈圓 full_circle_image = new ImageView(getContext()); // 設置控件不接受點擊事件 cusView.setClickable(false); buttonimage.setClickable(false); fillcircle.setClickable(false); full_circle_image.setClickable(false); setClickable(true); }
然后是設置動畫
/** * 設置動畫及動畫監聽器 */ private void setAnimation() { // Setting up and defining view animations. // http://blog.csdn.net/congqingbin/article/details/7889778 // RELATIVE_TO_PARENT:與父控件的的中心為重點;RELATIVE_TO_SELF以自己為中心 // 左上角 分別為0.0f 0.0f 中心點為0.5f,0.5f 右下角1.0f,1.0f /* * arcRotation = new RotateAnimation(0.0f, 360.0f, * Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); */ // 持續時間1000ms // arcRotation.setDuration(500); in = new AnimationSet(true); out = new AnimationSet(true); // http://blog.csdn.net/jason0539/article/details/16370405 out.setInterpolator(new AccelerateDecelerateInterpolator()); in.setInterpolator(new AccelerateDecelerateInterpolator()); // http://blog.csdn.net/xsl1990/article/details/17096501 scale_in = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); scale_out = new ScaleAnimation(1.0f, 3.0f, 1.0f, 3.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); // 縮放動畫,起始x軸的縮放為0,y軸的縮放為0,動畫后,x,y軸大小與圖像尺寸相同 // x,y可以把它當做寬度和高度 new_scale_in = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); new_scale_in.setDuration(200); // 透明度的動畫 fade_in = new AlphaAnimation(0.0f, 1.0f); fade_out = new AlphaAnimation(1.0f, 0.0f); scale_in.setDuration(150); scale_out.setDuration(150); fade_in.setDuration(150); fade_out.setDuration(150); // 進入的動畫集 in.addAnimation(scale_in); in.addAnimation(fade_in); // 退出的動畫集 out.addAnimation(fade_out); out.addAnimation(scale_out); out.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { // TODO Auto-generated method stub System.out.println("print this"); } @Override public void onAnimationRepeat(Animation animation) { // TODO Auto-generated method stub } @Override public void onAnimationEnd(Animation animation) { // TODO Auto-generated method stub buttonimage.setVisibility(View.GONE); buttonimage.setImageBitmap(second_icon_bmp); buttonimage.setVisibility(View.VISIBLE); buttonimage.startAnimation(in); full_circle_image.setVisibility(View.VISIBLE); cusView.setVisibility(View.VISIBLE); flg_frmwrk_mode = 2; System.out.println("flg_frmwrk_mode" + flg_frmwrk_mode); } }); new_scale_in.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { // TODO Auto-generated method stub } @Override public void onAnimationRepeat(Animation animation) { // TODO Auto-generated method stub } @Override public void onAnimationEnd(Animation animation) { // TODO Auto-generated method stub cusView.setVisibility(View.GONE); buttonimage.setVisibility(View.VISIBLE); buttonimage.setImageBitmap(third_icon_bmp); flg_frmwrk_mode = 3; buttonimage.startAnimation(in); } }); }
再接著是畫出各個形狀
* 設置各個畫面的路徑 */ private void iconCreate() { // Creating icons using path // Create your own icons or feel free to use these play = new Path(); play.moveTo(pix * 40 / 100, pix * 36 / 100); play.lineTo(pix * 40 / 100, pix * 63 / 100); play.lineTo(pix * 69 / 100, pix * 50 / 100); play.close(); stop = new Path(); stop.moveTo(pix * 38 / 100, pix * 38 / 100); stop.lineTo(pix * 62 / 100, pix * 38 / 100); stop.lineTo(pix * 62 / 100, pix * 62 / 100); stop.lineTo(pix * 38 / 100, pix * 62 / 100); stop.close(); download_triangle = new Path(); download_triangle.moveTo(pix * 375 / 1000, (pix / 2) + (pix * 625 / 10000) - (pix * 3 / 100)); download_triangle.lineTo(pix / 2, (pix * 625 / 1000) + (pix * 625 / 10000) - (pix * 3 / 100)); download_triangle.lineTo(pix * 625 / 1000, (pix / 2) + (pix * 625 / 10000) - (pix * 3 / 100)); download_triangle.close(); download_rectangle = new Path(); download_rectangle.moveTo(pix * 4375 / 10000, (pix / 2) + (pix * 625 / 10000) - (pix * 3 / 100)); download_rectangle.lineTo(pix * 5625 / 10000, (pix / 2) + (pix * 625 / 10000) - (pix * 3 / 100)); download_rectangle.lineTo(pix * 5625 / 10000, (pix * 375 / 1000) + (pix * 625 / 10000) - (pix * 3 / 100)); download_rectangle.lineTo(pix * 4375 / 10000, (pix * 375 / 1000) + (pix * 625 / 10000) - (pix * 3 / 100)); download_rectangle.close(); tick = new Path(); tick.moveTo(pix * 30 / 100, pix * 50 / 100); tick.lineTo(pix * 45 / 100, pix * 625 / 1000); tick.lineTo(pix * 65 / 100, pix * 350 / 1000); } /** * 創建各個bitmap添加到framelayout中 */ public void init() { // Defining and drawing bitmaps and assigning views to the layout FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT); lp.setMargins(10, 10, 10, 10); fillcircle.setVisibility(View.GONE); Bitmap.Config conf = Bitmap.Config.ARGB_8888; // see other conf types Bitmap full_circle_bmp = Bitmap.createBitmap(pix, pix, conf); Bitmap fill_circle_bmp = Bitmap.createBitmap(pix, pix, conf); first_icon_bmp = Bitmap.createBitmap(pix, pix, conf); // Bitmap to draw // first icon( // Default - // Play ) second_icon_bmp = Bitmap.createBitmap(pix, pix, conf); // Bitmap to draw // second icon( // Default - // Stop ) third_icon_bmp = Bitmap.createBitmap(pix, pix, conf); // Bitmap to draw // third icon( // Default - // Tick ) Canvas first_icon_canvas = new Canvas(first_icon_bmp); Canvas second_icon_canvas = new Canvas(second_icon_bmp); Canvas third_icon_canvas = new Canvas(third_icon_bmp); Canvas fill_circle_canvas = new Canvas(fill_circle_bmp); Canvas full_circle_canvas = new Canvas(full_circle_bmp); float startx = (float) (pix * 0.05); float endx = (float) (pix * 0.95); System.out.println("full circle " + full_circle_canvas.getWidth() + full_circle_canvas.getHeight()); float starty = (float) (pix * 0.05); float endy = (float) (pix * 0.95); rect = new RectF(startx, starty, endx, endy); first_icon_canvas.drawPath(play, fill_color); // Draw second icon on // canvas( Default - // Stop ). // *****Set your second // icon here**** second_icon_canvas.drawPath(stop, icon_color); // Draw second icon on // canvas( Default - // Stop ). // *****Set your second // icon here**** third_icon_canvas.drawPath(tick, final_icon_color); // Draw second icon // on canvas( // Default - Stop ). // *****Set your // second icon // here**** full_circle_canvas.drawArc(rect, 0, 360, false, stroke_color); fill_circle_canvas.drawArc(rect, 0, 360, false, fill_color); buttonimage.setImageBitmap(first_icon_bmp); flg_frmwrk_mode = 1; fillcircle.setImageBitmap(fill_circle_bmp); full_circle_image.setImageBitmap(full_circle_bmp); cusView.setVisibility(View.GONE); addView(full_circle_image, lp); addView(fillcircle, lp); addView(buttonimage, lp); addView(cusView, lp); }
***加上點擊按鈕時各個狀態切換的邏輯關系,這個按鈕的布局就完成了。
附上整個類的代碼
package com.example.mybutton; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.RectF; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.view.View; import android.view.View.OnClickListener; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.AnimationSet; import android.view.animation.ScaleAnimation; import android.view.animation.Animation.AnimationListener; import android.widget.FrameLayout; import android.widget.ImageView; public class ButtonLayout extends FrameLayout implements OnClickListener { public CusImage cusView; public int pix = 0; public RectF rect; // 圖像視圖 // ImageView類可以加載各種來源的圖片(如資源或圖片庫),需要計算圖像的尺寸,比便它可以在其他布局中使用,并提供例如縮放和著色(渲染)各種顯示選項。 private ImageView circle_image, buttonimage, fillcircle, full_circle_image; // 可以用他來畫幾何圖形、畫曲線、畫基于路徑的文本。這是個繪圖的路徑類 private Path stop, tick, play, download_triangle, download_rectangle; // 位圖類 private Bitmap third_icon_bmp, second_icon_bmp, first_icon_bmp; // 畫筆類 private Paint stroke_color, fill_color, icon_color, final_icon_color; // AnimationSet類是Android系統中的動畫集合類,用于控制View對象進行多個動作的組合,該類繼承于Animation類 private AnimationSet in, out; // RotateAnimation類是Android系統中的旋轉變化動畫類,用于控制View對象的旋轉動作,該類繼承于Animation類 // private RotateAnimation arcRotation; // 縮放動畫類 private ScaleAnimation new_scale_in, scale_in, scale_out; // 透明度動畫 private AlphaAnimation fade_in, fade_out; public int flg_frmwrk_mode = 0; boolean first_click = false; public ButtonLayout(Context context, AttributeSet attrs) { super(context, attrs); setOnClickListener(this); initialise(); setpaint(); setAnimation(); displayMetrics(); iconCreate(); init(); // TODO Auto-generated constructor stub } public ButtonLayout(Context context) { super(context); setOnClickListener(this); setBackgroundColor(Color.CYAN); initialise(); setpaint(); setAnimation(); displayMetrics(); iconCreate(); init(); } /** * 創建各個控件 */ private void initialise() { // 按鈕的進度條 cusView = new CusImage(getContext(), this); // 按鈕中間的形狀 buttonimage = new ImageView(getContext()); // 完成進度后顯示的圖像 fillcircle = new ImageView(getContext()); //外面一圈圓 full_circle_image = new ImageView(getContext()); // 設置控件不接受點擊事件 cusView.setClickable(false); buttonimage.setClickable(false); fillcircle.setClickable(false); full_circle_image.setClickable(false); setClickable(true); } /** * 設置各類畫筆 */ private void setpaint() { // Setting up color // Paint.ANTI_ALIAS_FLAG是使位圖抗鋸齒的標志 stroke_color = new Paint(Paint.ANTI_ALIAS_FLAG); stroke_color.setAntiAlias(true); stroke_color.setColor(Color.rgb(0, 161, 234)); // Edit this to change stroke_color.setStrokeWidth(3); stroke_color.setStyle(Paint.Style.STROKE); icon_color = new Paint(Paint.ANTI_ALIAS_FLAG); icon_color.setColor(Color.rgb(0, 161, 234)); // 填充 icon_color.setStyle(Paint.Style.FILL_AND_STROKE); // Edit this to change icon_color.setAntiAlias(true); final_icon_color = new Paint(Paint.ANTI_ALIAS_FLAG); final_icon_color.setColor(Color.WHITE); // Edit this to change the final final_icon_color.setStrokeWidth(12); final_icon_color.setStyle(Paint.Style.STROKE); final_icon_color.setAntiAlias(true); fill_color = new Paint(Paint.ANTI_ALIAS_FLAG); fill_color.setColor(Color.rgb(0, 161, 234)); // Edit this to change the fill_color.setStyle(Paint.Style.FILL_AND_STROKE); fill_color.setAntiAlias(true); } /** * 設置動畫及動畫監聽器 */ private void setAnimation() { // Setting up and defining view animations. // http://blog.csdn.net/congqingbin/article/details/7889778 // RELATIVE_TO_PARENT:與父控件的的中心為重點;RELATIVE_TO_SELF以自己為中心 // 左上角 分別為0.0f 0.0f 中心點為0.5f,0.5f 右下角1.0f,1.0f /* * arcRotation = new RotateAnimation(0.0f, 360.0f, * Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); */ // 持續時間1000ms // arcRotation.setDuration(500); in = new AnimationSet(true); out = new AnimationSet(true); // http://blog.csdn.net/jason0539/article/details/16370405 out.setInterpolator(new AccelerateDecelerateInterpolator()); in.setInterpolator(new AccelerateDecelerateInterpolator()); // http://blog.csdn.net/xsl1990/article/details/17096501 scale_in = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); scale_out = new ScaleAnimation(1.0f, 3.0f, 1.0f, 3.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); // 縮放動畫,起始x軸的縮放為0,y軸的縮放為0,動畫后,x,y軸大小與圖像尺寸相同 // x,y可以把它當做寬度和高度 new_scale_in = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); new_scale_in.setDuration(200); // 透明度的動畫 fade_in = new AlphaAnimation(0.0f, 1.0f); fade_out = new AlphaAnimation(1.0f, 0.0f); scale_in.setDuration(150); scale_out.setDuration(150); fade_in.setDuration(150); fade_out.setDuration(150); // 進入的動畫集 in.addAnimation(scale_in); in.addAnimation(fade_in); // 退出的動畫集 out.addAnimation(fade_out); out.addAnimation(scale_out); out.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { // TODO Auto-generated method stub System.out.println("print this"); } @Override public void onAnimationRepeat(Animation animation) { // TODO Auto-generated method stub } @Override public void onAnimationEnd(Animation animation) { // TODO Auto-generated method stub buttonimage.setVisibility(View.GONE); buttonimage.setImageBitmap(second_icon_bmp); buttonimage.setVisibility(View.VISIBLE); buttonimage.startAnimation(in); full_circle_image.setVisibility(View.VISIBLE); cusView.setVisibility(View.VISIBLE); flg_frmwrk_mode = 2; System.out.println("flg_frmwrk_mode" + flg_frmwrk_mode); } }); new_scale_in.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { // TODO Auto-generated method stub } @Override public void onAnimationRepeat(Animation animation) { // TODO Auto-generated method stub } @Override public void onAnimationEnd(Animation animation) { // TODO Auto-generated method stub cusView.setVisibility(View.GONE); buttonimage.setVisibility(View.VISIBLE); buttonimage.setImageBitmap(third_icon_bmp); flg_frmwrk_mode = 3; buttonimage.startAnimation(in); } }); } /** * 設置自定義控件的大小 */ private void displayMetrics() { // Responsible for calculating the size of views and canvas based upon // screen resolution. DisplayMetrics metrics = getContext().getResources() .getDisplayMetrics(); int width = metrics.widthPixels; int height = metrics.heightPixels; float scarea = width * height; pix = (int) Math.sqrt(scarea * 0.0217); } /** * 設置各個畫面的路徑 */ private void iconCreate() { // Creating icons using path // Create your own icons or feel free to use these play = new Path(); play.moveTo(pix * 40 / 100, pix * 36 / 100); play.lineTo(pix * 40 / 100, pix * 63 / 100); play.lineTo(pix * 69 / 100, pix * 50 / 100); play.close(); stop = new Path(); stop.moveTo(pix * 38 / 100, pix * 38 / 100); stop.lineTo(pix * 62 / 100, pix * 38 / 100); stop.lineTo(pix * 62 / 100, pix * 62 / 100); stop.lineTo(pix * 38 / 100, pix * 62 / 100); stop.close(); download_triangle = new Path(); download_triangle.moveTo(pix * 375 / 1000, (pix / 2) + (pix * 625 / 10000) - (pix * 3 / 100)); download_triangle.lineTo(pix / 2, (pix * 625 / 1000) + (pix * 625 / 10000) - (pix * 3 / 100)); download_triangle.lineTo(pix * 625 / 1000, (pix / 2) + (pix * 625 / 10000) - (pix * 3 / 100)); download_triangle.close(); download_rectangle = new Path(); download_rectangle.moveTo(pix * 4375 / 10000, (pix / 2) + (pix * 625 / 10000) - (pix * 3 / 100)); download_rectangle.lineTo(pix * 5625 / 10000, (pix / 2) + (pix * 625 / 10000) - (pix * 3 / 100)); download_rectangle.lineTo(pix * 5625 / 10000, (pix * 375 / 1000) + (pix * 625 / 10000) - (pix * 3 / 100)); download_rectangle.lineTo(pix * 4375 / 10000, (pix * 375 / 1000) + (pix * 625 / 10000) - (pix * 3 / 100)); download_rectangle.close(); tick = new Path(); tick.moveTo(pix * 30 / 100, pix * 50 / 100); tick.lineTo(pix * 45 / 100, pix * 625 / 1000); tick.lineTo(pix * 65 / 100, pix * 350 / 1000); } /** * 創建各個bitmap添加到framelayout中 */ public void init() { // Defining and drawing bitmaps and assigning views to the layout FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT); lp.setMargins(10, 10, 10, 10); fillcircle.setVisibility(View.GONE); Bitmap.Config conf = Bitmap.Config.ARGB_8888; // see other conf types Bitmap full_circle_bmp = Bitmap.createBitmap(pix, pix, conf); Bitmap fill_circle_bmp = Bitmap.createBitmap(pix, pix, conf); first_icon_bmp = Bitmap.createBitmap(pix, pix, conf); // Bitmap to draw // first icon( // Default - // Play ) second_icon_bmp = Bitmap.createBitmap(pix, pix, conf); // Bitmap to draw // second icon( // Default - // Stop ) third_icon_bmp = Bitmap.createBitmap(pix, pix, conf); // Bitmap to draw // third icon( // Default - // Tick ) Canvas first_icon_canvas = new Canvas(first_icon_bmp); Canvas second_icon_canvas = new Canvas(second_icon_bmp); Canvas third_icon_canvas = new Canvas(third_icon_bmp); Canvas fill_circle_canvas = new Canvas(fill_circle_bmp); Canvas full_circle_canvas = new Canvas(full_circle_bmp); float startx = (float) (pix * 0.05); float endx = (float) (pix * 0.95); System.out.println("full circle " + full_circle_canvas.getWidth() + full_circle_canvas.getHeight()); float starty = (float) (pix * 0.05); float endy = (float) (pix * 0.95); rect = new RectF(startx, starty, endx, endy); first_icon_canvas.drawPath(play, fill_color); // Draw second icon on // canvas( Default - // Stop ). // *****Set your second // icon here**** second_icon_canvas.drawPath(stop, icon_color); // Draw second icon on // canvas( Default - // Stop ). // *****Set your second // icon here**** third_icon_canvas.drawPath(tick, final_icon_color); // Draw second icon // on canvas( // Default - Stop ). // *****Set your // second icon // here**** full_circle_canvas.drawArc(rect, 0, 360, false, stroke_color); fill_circle_canvas.drawArc(rect, 0, 360, false, fill_color); buttonimage.setImageBitmap(first_icon_bmp); flg_frmwrk_mode = 1; fillcircle.setImageBitmap(fill_circle_bmp); full_circle_image.setImageBitmap(full_circle_bmp); cusView.setVisibility(View.GONE); addView(full_circle_image, lp); addView(fillcircle, lp); addView(buttonimage, lp); addView(cusView, lp); } public void animation() { // Starting view animation and setting flag values if (flg_frmwrk_mode == 1) { //full_circle_image.setVisibility(View.GONE); buttonimage.startAnimation(out); } } public void finalAnimation() { // Responsible for final fill up animation buttonimage.setVisibility(View.GONE); fillcircle.setVisibility(View.VISIBLE); fillcircle.startAnimation(new_scale_in); } public void stop() { // Responsible for resetting the state of view when Stop is clicked cusView.reset(); buttonimage.setImageBitmap(first_icon_bmp); flg_frmwrk_mode = 1; } @Override public void onClick(View v) { // TODO Auto-generated method stub animation(); } }
按鈕做好了我們可以在Activity中調用它了
首先是寫入到布局文件中
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <com.example.mybutton.ButtonLayout android:id="@+id/ButtonLayout01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:clickable="true" > </com.example.mybutton.ButtonLayout> </RelativeLayout>
然后在activity中設置
public class MainActivity extends Activity { 2 3 private static ButtonLayout buttonLayout; 4 5 @Override 6 protected void onCreate(Bundle savedInstanceState) { 7 super.onCreate(savedInstanceState); 8 setContentView(R.layout.activity_main); 9 buttonLayout = (ButtonLayout) findViewById(R.id.ButtonLayout01); 10 buttonLayout.setOnClickListener(new OnClickListener() { 11 12 @Override 13 public void onClick(View v) { 14 // TODO Auto-generated method stub 15 buttonLayout.animation(); // Need to call this method for 16 // animation and progression 17 18 if (buttonLayout.flg_frmwrk_mode == 1) { 19 20 // Start state. Call any method that you want to execute 21 22 runOnUiThread(new Runnable() { 23 24 @Override 25 public void run() { 26 // TODO Auto-generated method stub 27 Toast.makeText(MainActivity.this, 28 "Starting download", Toast.LENGTH_SHORT) 29 .show(); 30 } 31 }); 32 new DownLoadSigTask().execute(); 33 } 34 if (buttonLayout.flg_frmwrk_mode == 2) { 35 36 // Running state. Call any method that you want to execute 37 38 new DownLoadSigTask().cancel(true); 39 buttonLayout.stop(); 40 runOnUiThread(new Runnable() { 41 42 @Override 43 public void run() { 44 // TODO Auto-generated method stub 45 Toast.makeText(MainActivity.this, 46 "Download stopped", Toast.LENGTH_SHORT) 47 .show(); 48 } 49 }); 50 } 51 if (buttonLayout.flg_frmwrk_mode == 3) { 52 53 // End state. Call any method that you want to execute. 54 55 runOnUiThread(new Runnable() { 56 57 @Override 58 public void run() { 59 // TODO Auto-generated method stub 60 Toast.makeText(MainActivity.this, 61 "Download complete", Toast.LENGTH_SHORT) 62 .show(); 63 } 64 }); 65 } 66 } 67 68 }); 69 } 70 71 static class DownLoadSigTask extends AsyncTask<String, Integer, String> { 72 73 @Override 74 protected void onPreExecute() { 75 76 } 77 78 @Override 79 protected String doInBackground(final String... args) { 80 81 // Creating dummy task and updating progress 82 83 for (int i = 0; i <= 100;) { 84 try { 85 Thread.sleep(50); 86 87 } catch (InterruptedException e) { 88 89 e.printStackTrace(); 90 } 91 if (buttonLayout.flg_frmwrk_mode == 2 &&i<=100){ 92 i++; 93 publishProgress(i); 94 } 95 } 96 97 return null; 98 } 99 100 @Override 101 protected void onProgressUpdate(Integer... progress) { 102 103 // publishing progress to progress arc 104 105 buttonLayout.cusView.setupprogress(progress[0]); 106 } 107 108 } 109 110 }
關于Android中怎么自定義Button控件問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。