日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

android 圆形选中,RoundChoiceView

發(fā)布時(shí)間:2024/4/20 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android 圆形选中,RoundChoiceView 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

A widget for round shape choice view with number or cross indicator

先看下效果

說(shuō)在前面的話

開(kāi)發(fā)這個(gè)控件是因?yàn)樵诜绿教降膱D片選擇器組件的時(shí)候,他們有這樣的一個(gè)控件。照貓畫(huà)虎,我也做了一個(gè)。

想來(lái),其實(shí)還是有很多的朋友需要這樣的控件。

所以開(kāi)源出來(lái)給大家使用。

使用方式

項(xiàng)目放在 gihub 上,歡迎使用。

github 地址:https://github.com/klisly/RoundChoiceView

已經(jīng)發(fā)布到 jitpack

源配置

allprojects {

repositories {

jcenter()

maven { url "https://jitpack.io" }

}

}

依賴(lài)配置

compile 'com.github.klisly:RoundChoiceView:v1.1'

設(shè)計(jì)步驟

1.定義樣式屬性

定義了控件的的屬性有如下幾個(gè):

borderColor:border 的顏色

backgroundColor:控件未選中狀態(tài)的時(shí)候的背景顏色

checkedColor:選中狀態(tài)時(shí)控件填充顏色

crossType:選中狀態(tài)時(shí)的類(lèi)型(數(shù)字或者打勾)

crossColor:類(lèi)型是打勾時(shí),勾的顏色

rippleBorderWidth:border 的寬度

rippleduration:選中時(shí)的動(dòng)畫(huà)過(guò)渡時(shí)間

checked:控件選中狀態(tài)

number:如果是 crossType 是數(shù)字時(shí),默認(rèn)顯示的數(shù)字

textSize:數(shù)字的字體 size

2.讀取樣式

這一步驟獲取已經(jīng)定義好的屬性,并初始化所需要的畫(huà)筆

mDensity = getContext().getResources().getDisplayMetrics().density;

scaledDensity = getContext().getResources().getDisplayMetrics().scaledDensity;

// Load attributes

final TypedArray a = getContext().obtainStyledAttributes(

attrs, R.styleable.RoundChoiceView, defStyle, 0);

mUnCheckColor = a.getColor(R.styleable.RoundChoiceView_borderColor, mUnCheckColor);

mCheckColor = a.getColor(R.styleable.RoundChoiceView_checkedColor, mCheckColor);

mCrossColor = a.getColor(R.styleable.RoundChoiceView_crossColor, mCrossColor);

mBgColor = a.getColor(R.styleable.RoundChoiceView_backgroundColor, mBgColor);

mTextSize = a.getDimension(R.styleable.RoundChoiceView_textSize, mTextSize);

int crossType = a.getInt(R.styleable.RoundChoiceView_crossType, TYPE_CROSS_CROSS);

if (crossType == TYPE_CROSS_NUMBER) {

mCrossType = TYPE_CROSS_NUMBER;

} else {

mCrossType = TYPE_CROSS_CROSS;

}

mBorderWidth = a.getDimension(R.styleable.RoundChoiceView_rippleBorderWidth, dp2px(2));

mDuration = a.getInt(R.styleable.RoundChoiceView_rippleduration, mDuration);

mChecked = a.getBoolean(R.styleable.RoundChoiceView_checked, mChecked);

mNumber = a.getInt(R.styleable.RoundChoiceView_number, mNumber);

a.recycle();

mHookDuration = (int) (mDuration * 0.3);

mCircleDuration = mDuration - mHookDuration;

mUncheckPaint = new Paint();

mUncheckPaint.setFlags(Paint.ANTI_ALIAS_FLAG);

mUncheckPaint.setStrokeWidth(mBorderWidth);

mUncheckPaint.setColor(mUnCheckColor);

mUncheckPaint.setStyle(Paint.Style.STROKE);

mCheckPaint = new Paint();

mCheckPaint.setFlags(Paint.ANTI_ALIAS_FLAG);

mCheckPaint.setColor(mCheckColor);

mCheckPaint.setStyle(Paint.Style.STROKE);

isHookShow = mChecked;

mFraction = mChecked ? 1.0f : 0.0f;3.確定尺寸

onSizeChanged 方法回調(diào)的時(shí)候可以獲得控件的最終尺寸,在此可以初始化

勾的起點(diǎn) start,折點(diǎn) middle,終點(diǎn)的坐標(biāo)。

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

width = w;

height = h;

mRectF = new RectF(getPaddingLeft(), getPaddingTop(),

w - getPaddingRight(), h - getPaddingBottom());

mRadius = Math.min(mRectF.width(), mRectF.height()) / 2;

hookStart = new PointF(mRectF.centerX() - mRadius / 2, mRectF.centerY() + mRadius / 10);

hookMiddle = new PointF(mRectF.centerX() - mRadius * 1 / 6, mRectF.centerY() + mRadius * 2 / 5);

hookEnd = new PointF(mRectF.centerX() + mRadius / 2, mRectF.centerY() - mRadius * 1 / 3);

}4.繪制控件

繪制邏輯:

1.繪制未選中狀態(tài)時(shí)的圓形和 border

2.繪制過(guò)渡狀態(tài)的選中的圓形

3.繪制勾或者數(shù)字

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

mUncheckPaint.setColor(mBgColor);

mUncheckPaint.setStyle(Paint.Style.FILL);

canvas.drawCircle(mRectF.centerX(), mRectF.centerY(), mRadius - mBorderWidth, mUncheckPaint);

mUncheckPaint.setColor(mUnCheckColor);

mUncheckPaint.setStyle(Paint.Style.STROKE);

canvas.drawCircle(mRectF.centerX(), mRectF.centerY(), mRadius - mBorderWidth + 1, mUncheckPaint);

if (mChecked || mIsAnimating) {

float stroke = mFraction * mRadius;

if (!mIsAnimating) {

stroke = mRadius;

}

if (mChecked) {

mCheckPaint.setStrokeWidth(stroke);

} else {

mCheckPaint.setStrokeWidth(mRadius - stroke);

}

if (isHookShow) {

mNRectF.left = getPaddingLeft() + mRadius / 2;

mNRectF.top = getPaddingTop() + mRadius / 2;

mNRectF.right = width - getPaddingRight() - mRadius / 2;

mNRectF.bottom = height - getPaddingBottom() - mRadius / 2;

mCheckPaint.setStrokeWidth(mRadius);

} else if (mChecked) {

mNRectF.left = getPaddingLeft() + stroke / 2;

mNRectF.top = getPaddingTop() + stroke / 2;

mNRectF.right = width - getPaddingRight() - stroke / 2;

mNRectF.bottom = height - getPaddingBottom() - stroke / 2;

} else {

mNRectF.left = getPaddingLeft() + (mRadius - stroke) / 2;

mNRectF.top = getPaddingTop() + (mRadius - stroke) / 2;

mNRectF.right = width - getPaddingRight() - (mRadius - stroke) / 2;

mNRectF.bottom = height - getPaddingBottom() - (mRadius - stroke) / 2;

}

canvas.drawArc(mNRectF, 0f, 360f, false, mCheckPaint);

}

mUncheckPaint.setColor(mCrossColor);

if (mCrossType == TYPE_CROSS_NUMBER) {

if (mChecked) {

mUncheckPaint.setTextSize(mTextSize);

mUncheckPaint.setStyle(Paint.Style.FILL);

Paint.FontMetrics metrics = mUncheckPaint.getFontMetrics();

int baseline = (int) ((mRectF.bottom + mRectF.top - metrics.bottom - metrics.top) / 2);

mUncheckPaint.setTextAlign(Paint.Align.CENTER);

canvas.drawText(String.valueOf(mNumber), mRectF.centerX(), baseline, mUncheckPaint);

mUncheckPaint.setStyle(Paint.Style.STROKE);

}

} else {

if (mIsAnimating) {

if (!mChecked && isHookShow) {

mFraction = 1 - mFraction;

}

if (isHookShow && mFraction > 0) {// y1 - x1

Log.i("isHookShow", isHookShow + " " + mFraction);

if (mFraction < 0.4) {

canvas.drawLine(hookStart.x, hookStart.y, getr1x((float) (mFraction / 0.4)), getr1y((float) (mFraction / 0.4)), mUncheckPaint);

} else {

canvas.drawLine(hookStart.x, hookStart.y, hookMiddle.x + 2, hookMiddle.y + 2, mUncheckPaint);

canvas.drawLine(hookMiddle.x, hookMiddle.y, getr2x((float) ((mFraction - 0.4) / 0.6)), getr2y((float) ((mFraction - 0.4f) / 0.6)), mUncheckPaint);

}

}

} else {

if (mChecked && isHookShow) {

canvas.drawLine(hookStart.x, hookStart.y, hookMiddle.x + 2, hookMiddle.y + 2, mUncheckPaint);

canvas.drawLine(hookMiddle.x, hookMiddle.y, getr2x((float) ((1 - 0.4) / 0.6)), getr2y((float) ((1 - 0.4f) / 0.6)), mUncheckPaint);

}

}

}

}4.事件控制

1.在 ACTION_DOWN 時(shí)捕獲事件

2.在 ACTION_UP 中判斷是否處理選中狀態(tài)的監(jiān)聽(tīng),并處理動(dòng)畫(huà)的繪制

@Override

public boolean onTouchEvent(MotionEvent event) {

int x = (int) event.getX();

int y = (int) event.getY();

int action = event.getAction();

switch (action) {

case MotionEvent.ACTION_DOWN:

if (!isEnabled()) {

return false;

}

break;

case MotionEvent.ACTION_MOVE:

break;

case MotionEvent.ACTION_UP:

if (mIsAnimating) {

return true;

}

if (x + getLeft() < getRight() && y + getTop() < getBottom()) {

mChecked = !mChecked;

if (mIsAnimating) {

mFractionAnimator.cancel();

}

if (mChecked) {

initValueAnimator(mCircleDuration);

} else {

initValueAnimator(mHookDuration);

}

mFractionAnimator.start();

if (onCheckedChangeListener != null) {

onCheckedChangeListener.onCheckedChanged(this, mChecked);

}

}

break;

}

return true;

}

總結(jié)

以上是生活随笔為你收集整理的android 圆形选中,RoundChoiceView的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。