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

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

生活随笔

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

编程问答

仿QQ计步器效果的实现

發(fā)布時(shí)間:2024/3/13 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 仿QQ计步器效果的实现 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

效果展示

仿QQ計(jì)步器的效果展示

思路分析

1、固定不動(dòng)藍(lán)色的大圓弧 color borderWidth

2、可以變化的小圓弧(紅色) color borderWidth

3、中間的步數(shù)文字 color textSize

這里,因?yàn)閮?nèi)外圓弧寬度寬度一樣,所以,可統(tǒng)一命名為 borderWidth

開(kāi)始碼字

第一步:自定義控件類(lèi)的創(chuàng)建?繼承自 View

?

第二步:自定義屬性文件的創(chuàng)建,及內(nèi)容的編寫(xiě)

<?xml version="1.0" encoding="utf-8"?> <resources><declare-styleable name="QQStepView"><attr name="outerColor" format="color"/><attr name="innerColor" format="color"/><attr name="borderWidth" format="dimension"/><attr name="stepTextSize" format="dimension"/><attr name="stepTextColor" format="color"/></declare-styleable> </resources>

如何創(chuàng)建自定義屬性文件,我前面有講解?,不懂得可自行復(fù)習(xí)

第三步:在布局文件中應(yīng)用

<?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.example.qqstepview.QQStepViewandroid:id="@+id/step_view"android:background="@color/colorAccent"android:layout_width="match_parent"android:layout_height="match_parent"app:outerColor="@color/colorPrimaryDark"app:innerColor="#f00"app:borderWidth="20dp"app:stepTextColor="#f00"app:stepTextSize="50sp"/></RelativeLayout>

第四步:在自定義組件類(lèi) 中 獲取自定義屬性 并編寫(xiě)相關(guān)方法

package com.example.qqstepview;import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; import android.util.AttributeSet; import android.view.View;import androidx.annotation.Nullable;public class QQStepView extends View {private int mOuterColor = Color.parseColor("#3700B3");private int mInnerColor = Color.parseColor("#ff0000");private int mBorderWidth = 20; //20pxprivate int mStepTextSize = 14; //14pxprivate int mStepTextColor;private Paint mOutPaint,mInnerPaint,mTextPaint;private Context mContext;//總共的,當(dāng)前的步數(shù)private int mStepMax = 100;private int mCurrentStep = 50;public QQStepView(Context context) {this(context,null);}public QQStepView(Context context, @Nullable AttributeSet attrs) {this(context, attrs,0);}public QQStepView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);this.mContext = context;//1、分析效果 2、確定自定義屬性 編寫(xiě)attrs.xml 3、在布局中使用 4、在自定義View中獲取自定義屬性TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.QQStepView);mOuterColor = typedArray.getColor(R.styleable.QQStepView_outerColor, mOuterColor);mInnerColor = typedArray.getColor(R.styleable.QQStepView_innerColor, mInnerColor);mBorderWidth = (int) typedArray.getDimension(R.styleable.QQStepView_borderWidth,mBorderWidth);mStepTextSize = typedArray.getDimensionPixelSize(R.styleable.QQStepView_stepTextSize,mStepTextSize);mStepTextColor = typedArray.getColor(R.styleable.QQStepView_stepTextColor,mStepTextColor);typedArray.recycle();//初始化數(shù)據(jù)initData();//5、onMeasure()//6、畫(huà)外圓弧 內(nèi)圓弧 文字//7、其他}private void initData() {mOutPaint = new Paint();mOutPaint.setAntiAlias(true);mOutPaint.setStrokeWidth(mBorderWidth);mOutPaint.setColor(mOuterColor);mOutPaint.setStyle(Paint.Style.STROKE);mOutPaint.setStrokeCap(Paint.Cap.ROUND);mInnerPaint = new Paint();mInnerPaint.setAntiAlias(true);mInnerPaint.setStrokeWidth(mBorderWidth);mInnerPaint.setColor(mInnerColor);mInnerPaint.setStyle(Paint.Style.STROKE);mInnerPaint.setStrokeCap(Paint.Cap.ROUND);mTextPaint = new Paint();mTextPaint.setAntiAlias(true);mTextPaint.setTextSize(mStepTextSize);mTextPaint.setColor(mStepTextColor);}//5、onMeasure()@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);//調(diào)用者在布局文件中可能 wrap_content 寬度高度不一致int width = MeasureSpec.getSize(widthMeasureSpec) + getPaddingLeft() + getPaddingRight();int height = MeasureSpec.getSize(heightMeasureSpec) + getPaddingTop() +getPaddingBottom();int widthMode = MeasureSpec.getMode(widthMeasureSpec);int heightMode = MeasureSpec.getMode(heightMeasureSpec);if (widthMode == MeasureSpec.AT_MOST){}if (heightMode == MeasureSpec.AT_MOST){}setMeasuredDimension(width>height?height:width,width>height?height:width);}//6、畫(huà)外圓弧 內(nèi)圓弧 文字@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);int center = getWidth()/2;int radius = getWidth()/2 - mBorderWidth/2;//6.1 畫(huà)外圓弧RectF rectF = new RectF(center - radius ,center - radius ,center + radius ,center + radius ); //第一種寫(xiě)法//RectF rectF = new RectF(mBorderWidth/2,mBorderWidth/2,getWidth() - mBorderWidth/2,getWidth() - mBorderWidth/2); //第二種寫(xiě)法canvas.drawArc(rectF,135,270,false,mOutPaint);//6.2 畫(huà)內(nèi)圓弧 怎么畫(huà)肯定不能寫(xiě)死 百分比 是使用者設(shè)置的 從外面?zhèn)鱏ystem.out.println("mCurrentStep:"+mCurrentStep+"mStepMax:"+mStepMax);if (mStepMax == 0)return;float sweepAngle = (float)mCurrentStep/mStepMax;canvas.drawArc(rectF,135,sweepAngle*270,false,mInnerPaint);//6.3 畫(huà)文字String stepText = mCurrentStep + "";//基線(xiàn)Paint.FontMetricsInt fontMetricsInt = mTextPaint.getFontMetricsInt();int dy = (fontMetricsInt.bottom - fontMetricsInt.top)/2 - fontMetricsInt.bottom;int baseLine = getHeight()/2 + dy;//文字起始位置Rect textBounds = new Rect();mTextPaint.getTextBounds(stepText,0,stepText.length(),textBounds);int dx = textBounds.width();float x = getWidth()/2 - dx/2; //dx表示文字寬度canvas.drawText(stepText,x,baseLine,mTextPaint);}//7,其他,寫(xiě)幾個(gè)方法動(dòng)起來(lái)public synchronized void setStepMax (int stepMax){this.mStepMax = stepMax;}public synchronized void setCurrentStep (int currentStep){this.mCurrentStep = currentStep;//不斷繪制invalidate();} }

里面有一些冗余代碼,比如初始化畫(huà)筆可以封裝,我就不在此優(yōu)化了

第五步:在使用了自定義組件的 類(lèi)中 調(diào)用

package com.example.qqstepview;import androidx.appcompat.app.AppCompatActivity;import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.os.Bundle; import android.view.View; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.BounceInterpolator; import android.view.animation.DecelerateInterpolator;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);final QQStepView step_view = findViewById(R.id.step_view);step_view.setStepMax(4000);//值動(dòng)畫(huà)ValueAnimator valueAnimator = ObjectAnimator.ofFloat(0, 3000);valueAnimator.setDuration(1000);valueAnimator.setInterpolator(new DecelerateInterpolator());valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {float currentStep = (float) animation.getAnimatedValue();step_view.setCurrentStep((int) currentStep);}});valueAnimator.start();} }

源碼連接:QQStepView

總結(jié)

以上是生活随笔為你收集整理的仿QQ计步器效果的实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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