自定義控制元件 輪盤 來源於GITHUB(記錄,筆記)
阿新 • • 發佈:2018-11-17
自定義控制元件:輪盤抽獎
-------邏輯程式碼(輪盤的類)首先要寫一個類繼承SurfaceView 實現Callback和Runnable方法:
//所使用的包
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
/*
*/
public class SurfaceViewTemp extends SurfaceView implements SurfaceHolder.Callback ,Runnable{
SurfaceHolder mHolder;
Canvas mCanvas;
boolean mIsDrawing;
public SurfaceViewTemp(Context context) {
this(context,null);//呼叫自身的方法null不影響下一個方法的值
}
public SurfaceViewTemp(Context context, AttributeSet attrs) {
this( context, attrs,0);//呼叫自身的方法0不影響下一個方法的值
}
public SurfaceViewTemp(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//初始化
initView();
}
private void initView() {//初始化
mHolder = getHolder();
mHolder.addCallback(this );
setFocusable(true);
setFocusableInTouchMode(true);
setKeepScreenOn(true);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mIsDrawing = true;
new Thread(this).start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
@Override
public void run() {
}
}
------書寫Lunpan的具體類,主要功能和邏輯都在這個裡邊,要繼承上一個類--SurfaceViewTemp
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.SurfaceHolder;
public class LuckyPan extends SurfaceViewTemp {
int mRadius;
Paint mArcPaint;
Paint mTextPaint;
RectF mRange;
int mSpeed = 0;
boolean isShouldEnd;
private float mTextSize = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics());
private String[] mStrs = new String[] { "單反相機", "IPAD", "恭喜發財", "IPHONE",
"妹子一隻", "恭喜發財" };
private int [] mColors = new int[] { 0xFFFFC300, 0xFFF17E01, 0xFFFFC300,
0xFFF17E01, 0xFFFFC300, 0xFFF17E01};
private int [] mBitmaps = new int[]{R.drawable.danfan, R.drawable.ipad, R.drawable.f015, R.drawable.iphone, R.drawable.meizi, R.drawable.f040};
private Bitmap [] mImgs;
private int mItemCount = 6;
public LuckyPan(Context context) {
super(context);
}
public LuckyPan(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void run() {
while(mIsDrawing) {
long start = System.currentTimeMillis();
draw();
long end = System.currentTimeMillis();
try {
if ((end - start)< 50){
Thread.sleep( 50 - (end-start));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
float mStartAngle = 0;
public void draw() {
try {
mCanvas = mHolder.lockCanvas();
if (mCanvas != null) {
//先畫背景
drawBg();
//畫arc
// drawArc();
float tmpAngle = mStartAngle;
mCanvas.save();
mCanvas.translate(mCenter, mCenter);
RectF r = new RectF(-1 * mRadius/2, -1 * mRadius/2, mRadius/2 , mRadius/2);
for(int i = 0; i < mItemCount; i ++){
mArcPaint.setColor(mColors[i]);
mCanvas.drawArc(r, tmpAngle, 60, true, mArcPaint);
drawText2(tmpAngle, 60, mStrs[i]);
drawIcon2(tmpAngle, i);
mCanvas.rotate(60);
}
mCanvas.restore();
mStartAngle += mSpeed;
if (isShouldEnd){
mSpeed -= 1;
}
if (mSpeed < 0){
mSpeed = 0;
isShouldEnd = false;
}
// calInExactArea(mStartAngle);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (mCanvas != null){
mHolder.unlockCanvasAndPost(mCanvas);
}
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
super.surfaceCreated(holder);
//畫弧的筆
mArcPaint = new Paint();
mArcPaint.setAntiAlias(true);
mArcPaint.setDither(true);
mRange = new RectF(getPaddingLeft(), getPaddingLeft(), mRadius + getPaddingLeft(), mRadius + getPaddingLeft());
//畫文字的筆
mTextPaint = new Paint();
mTextPaint.setTextSize(mTextSize);
mTextPaint.setColor(Color.WHITE);
mImgs = new Bitmap[mItemCount];
for(int i = 0; i < mItemCount; i ++){
mImgs[i]= BitmapFactory.decodeResource(getResources(), mBitmaps[i]);
}
}
//中心點
int mCenter;
//邊距
int mPadding;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = Math.min(getMeasuredHeight(), getMeasuredWidth());
//直徑
mRadius = width - getPaddingLeft() - getPaddingRight();
mCenter = width/2;
mPadding = getPaddingLeft();
setMeasuredDimension(width, width);
}
//背景圖片
Bitmap mBgBitmap;
//畫背景
public void drawBg(){
mBgBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg2);
mCanvas.drawColor(0XFFFFFFFF);
mCanvas.drawBitmap(mBgBitmap, null, new Rect(mPadding /2, mPadding /2 ,
getMeasuredWidth() - mPadding/2, getMeasuredHeight() - mPadding /2), null);
}
public void drawText(float startAngle, float item, String title){
Path path = new Path();
path.addArc(mRange, startAngle, item);
float textWidth = mTextPaint.measureText(title);
float h = (float) (Math.PI * mRadius /mItemCount/2 - textWidth/2);
float v = mPadding * 3/2;
mCanvas.drawTextOnPath(title, path, h, v, mTextPaint);
}
//旋轉的方式得到
public void drawText2(float startAngle, float gapAngle, String title){
RectF r = new RectF(-1 * mRadius/2, -1 * mRadius/2, mRadius/2, mRadius/2);
Path p = new Path();
p.addArc(r, startAngle , gapAngle);
float textWidth = mTextPaint.measureText(title);
float hoffset = (float) (Math.PI * mRadius /mItemCount/2 - textWidth/2);
float voffset = mPadding * 3/2;
mCanvas.drawTextOnPath(title, p, hoffset, voffset, mTextPaint);
}
public void drawIcon(float startAngle, int i){
int imgWidth = mRadius/2/4;
float angle = (float)( (30 + startAngle) * (Math.PI / 180));
int x = (int)(mCenter + mRadius /2 /2 * Math.cos(angle));
int y = (int)( mCenter + mRadius /2/2 * Math.sin(angle));
Rect rect = new Rect(x - imgWidth/2, y - imgWidth/2, x+ imgWidth/2, y + imgWidth/2);
mCanvas.drawBitmap(mImgs[i], null, rect, null);
}
public void drawIcon2(float startAngle, int i){
int imgWidth = mRadius/2/4;
float angle = (float) ((mStartAngle + 30) * (Math.PI/180));
int x = (int) (mRadius/4 * Math.cos(angle));
int y = (int) (mRadius/4 * Math.sin(angle));
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), mBitmaps[i]);
Rect r = new Rect(x - imgWidth/2, y - imgWidth/2, x + imgWidth/2 , y+imgWidth/2);
mCanvas.drawBitmap(bitmap, null, r, null);
}
public boolean isStart(){
return mSpeed != 0;
}
public boolean isShouldEnd(){
return isShouldEnd;
}
}
接下來就是在佈局檔案中寫入該自定義方法
佈局方法是RelativeLayout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.liu.get.lunpan.LuckyPan
android:id="@+id/pan"
android:layout_width="match_parent"
android:layout_centerInParent="true"
android:padding="20dp"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/start"/>
</RelativeLayout>
最後一步:在Activity中寫點選監聽
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
ImageView iv;
LuckyPan luckyPan;
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
luckyPan = (LuckyPan) findViewById(R.id.pan);
iv = (ImageView) findViewById(R.id.btn);
iv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!luckyPan.isStart()) {
iv.setImageResource(R.drawable.stop);
luckyPan.mSpeed = 38;
} else {
iv.setImageResource(R.drawable.start);
luckyPan.isShouldEnd = true;
}
}
});
}
}