Android UI高级之自定义控件
2016-05-20 17:41
351 查看
在android中有许多控件,比如editview、button等,但是,有时这些控件并不能满足我们的需求,这时,我们就需要去自定义一个控件来满足我们的需要,下面给出一个仿360加速球的demo.
1、首先,来看一下360加速球的效果
2、 下面给出一个自定义的view,加速球(Accelerating ball )
3、activity布局
4、activity
5、效果
1、首先,来看一下360加速球的效果
2、 下面给出一个自定义的view,加速球(Accelerating ball )
package com.example.houjie.studyapk.studyview.custom; import android.annotation.TargetApi; 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.PorterDuff; import android.graphics.PorterDuffXfermode; import android.os.Build; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.Log; import android.view.View; import java.util.Random; /** * 仿360加速球的自定义控件 * Created by hj on 2016/5/19. */ public class CustomViewAccBall extends View{ private Paint paintCircle,paintText,paintLine;//三个画笔, private int r,width,height;//加速球的半径,view的宽和高 private int dWidth,dHeight,bCount = 5,bHeight=50;//贝塞尔曲线的一些决定量,可以自己设置,我不太会用 private Random random;//产生随机数,加速球的波浪效果 private Path path;// private final int maxProgress = 100;//当前的进度 private int progress=0; private Bitmap bitmap;//位图 private Canvas bitmapCanvas;//位图画板 public int getProgress() { return progress; }// public void setProgress(int progress) { this.progress = progress; invalidate();//实时更新进度 } public int getMaxProgress() { return maxProgress; } //构造器,必须实现 public CustomViewAccBall(Context context) { super(context); init(); } public CustomViewAccBall(Context context, AttributeSet attrs) { super(context, attrs); init(); } public CustomViewAccBall(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } @TargetApi(Build.VERSION_CODES.LOLLIPOP)//取消版本限制 public CustomViewAccBall(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); init(); } private void init(){ //初始化圆的画笔 paintCircle = new Paint(); paintCircle.setStrokeWidth(1); paintCircle.setAntiAlias(true); paintCircle.setColor(Color.argb(0xff,0x2b,0x84,0x62)); paintCircle.setStyle(Paint.Style.FILL); //初始化文字的画笔 paintText = new Paint(); paintText.setTextSize(50f); paintText.setAntiAlias(true); paintText.setTextAlign(Paint.Align.CENTER); paintText.setColor(Color.WHITE); //初始化波浪线的画笔 paintLine = new Paint(); paintLine.setStyle(Paint.Style.FILL); paintLine.setColor(Color.argb(0xff,0x4e,0xc8,0x63)); paintLine.setStrokeWidth(1); paintLine.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); // android.graphics.PorterDuff.Mode.SRC_IN:只在源图像和目标图像相交的地方绘制源图像 path = new Path(); //初始化path } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); bitmapCanvas.drawCircle(width/2,height/2,r,paintCircle);//绘制圆 //通过Path绘制贝塞尔曲线,此处贝塞尔曲线不是太懂,所以画的东西不是太好,望高手指点 path.reset();//清除path内容 path.moveTo(0, height); path.lineTo(0, ((float) maxProgress-progress)/100*height);//此处若在定义时若是int,则必须强制转换,否则结果为零,聪明的你一定能理解。 for (int i = 0; i < bCount; i++) { path.rQuadTo(random.nextFloat()*bHeight, random.nextFloat()*dWidth/2,random.nextFloat()*dWidth, 0); // path.rQuadTo(20, -5, 40, 0);//可以是这样的固定值 } path.lineTo(width, ((float) maxProgress-progress)/100*((float)height)); Log.e("(maxProgrerogressheight","----------------"+((float) maxProgress-progress)/100*height); path.lineTo(width, height); path.close(); //将贝塞尔曲线绘制到Bitmap的Canvas上 bitmapCanvas.drawPath(path, paintLine); //将Bitmap绘制到View的Canvas上 bitmapCanvas.drawText(progress * 100f / maxProgress + "%", width / 2, height / 2, paintText); canvas.drawBitmap(bitmap, 0, 0, null); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); width = this.getMeasuredWidth();//得到宽和高 height = this.getMeasuredWidth(); setMeasuredDimension(width, height); r = width/2;//设置圆的半径 dHeight = height/5; dWidth = width/5; bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);//设置图片的大小 bitmapCanvas = new Canvas(bitmap); random = new Random(); } }
3、activity布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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" android:orientation="vertical" tools:context="com.example.houjie.studyapk.studyview.custom.ActivityCustomViewAccBall"> <com.example.houjie.studyapk.studyview.custom.CustomViewAccBall android:layout_width="200dp" android:layout_height="200dp" android:id="@+id/viewAccBall" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btnCustomAccBall" android:text="开启动画" /> </LinearLayout>
4、activity
import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import com.example.houjie.studyapk.R; /** * 仿360加速球显示的activity */ public class ActivityCustomViewAccBall extends AppCompatActivity { private Button btnCustomAccBall; private CustomViewAccBall viewAccBall; private int i = 0; private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); if(i<=100){ viewAccBall.setProgress(i);//延时1秒改变加速球进度 sendEmptyMessageDelayed(1,1000); i+=10; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_activity_custom_view_acc_ball); viewAccBall = (CustomViewAccBall) findViewById(R.id.viewAccBall); btnCustomAccBall = (Button) findViewById(R.id.btnCustomAccBall); btnCustomAccBall.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { i = 0; handler.sendEmptyMessageDelayed(1,1000);//开启动画 } }); } }
5、效果
相关文章推荐
- UIAlertController的使用
- iOS UITableView拉伸图片,悬停控件和渐变导航栏效果
- 测试rest接口的两个工具使用详解(restclient+soapUI)
- Vue.js-----轻量高效的MVVM框架(六、Class与Style绑定)
- 设计模式 - Builder模式
- Query获取Select
- Java中 obj.toString()和String.valueof()
- Android UiAutomator UiSelector类
- 我的arduino theme文件
- FFmpeg Filtering Guide
- Tensorflow source build on MAC EI Capitain
- .NET UIAutomation实现Word文档加密暴力破解
- Parquet的timestamp类型转为long
- ugui制作弧形血条
- iOS开发 UITableView 常用细节
- UIScrollView的基本设置
- Vue.js-----轻量高效的MVVM框架(五、计算属性)
- Angular2 and Electron - The definitive guide
- ios学习--UIStepper
- iOS UIScrollView的使用