首先***步就是往布局文件里拖一个Button控件,当然自己码出来也可以。XML布局如下

创新互联一直秉承“诚信做人,踏实做事”的原则,不欺瞒客户,是我们最起码的底线! 以服务为基础,以质量求生存,以技术求发展,成交一个客户多一个朋友!为您提供成都做网站、成都网站制作、成都网页设计、微信小程序开发、成都网站开发、成都网站制作、成都软件开发、重庆APP软件开发是成都本地专业的网站建设和网站设计公司,等你一起来见证!
- xmlns:tools="http://schemas.android.com/tools"
 - android:layout_width="match_parent"
 - android:layout_height="match_parent"
 - >
 
当然,一个控件的布局属性还有很多,这些都是需要我们多用多熟悉才行。
然后再在程序中调用它
- 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控件就完成了。但当然,这不是我们今天要讲的重点,重点是我们如何自定义一个按钮,而不是使用系统给我们的按钮。
二、自定义按钮
我们先来看看效果图吧
这是一个自带进度条的按钮,它可以显示异步任务的进度,当完成后结束操作。我们来看看具体是怎么实现的吧。
- 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);
 
分享题目:Android入门篇——Button控件+自定义Button控件
分享路径:http://wtcwzsj.com/article/djddise.html
Copyright © 2009-2022 www.wtcwzsj.com 青羊区广皓图文设计工作室(个体工商户) 版权所有 蜀ICP备19037934号