Android自定義View實(shí)現(xiàn)風(fēng)車(chē)效果
本文實(shí)例為大家分享了Android自定義View實(shí)現(xiàn)風(fēng)車(chē)效果的具體代碼,供大家參考,具體內(nèi)容如下
效果圖:

畫(huà)桿
public class WindmillRodView extends View {
? ? private int mWidth;
? ? private int mHeight;
? ? private Paint mPaint;
? ? public WindmillRodView(Context context) {
? ? ? ? this(context, null);
? ? }
? ? public WindmillRodView(Context context, AttributeSet attrs) {
? ? ? ? this(context, attrs, 0);
? ? }
? ? public WindmillRodView(Context context, AttributeSet attrs, int defStyleAttr) {
? ? ? ? super(context, attrs, defStyleAttr);
? ? ? ? init();
? ? }
? ? private void init() {
? ? ? ? mPaint = new Paint();
? ? ? ? mPaint.setColor(Color.WHITE);
? ? ? ? mPaint.setStyle(Paint.Style.FILL);
? ? ? ? mPaint.setAntiAlias(true);
? ? ? ? mPaint.setDither(true);
? ? }
? ? @Override
? ? protected void onSizeChanged(int w, int h, int oldw, int oldh) {
? ? ? ? super.onSizeChanged(w, h, oldw, oldh);
? ? ? ? mWidth = getMeasuredWidth();
? ? ? ? mHeight = getMeasuredHeight();
? ? }
? ? private int _rod_width = dp2px(2);
? ? @Override
? ? protected void onDraw(Canvas canvas) {
? ? ? ? int xCenter = mWidth / 2;
? ? ? ? int yCenter = mHeight / 3;
? ? ? ? int radius = mHeight / 3 * 2;
? ? ? ? drawRod(canvas, xCenter, yCenter, radius);
? ? }
? ? private void drawRod(Canvas canvas, int xCenter, int yCenter, int radius) {
? ? ? ? Path path = new Path();
? ? ? ? path.moveTo(xCenter - _rod_width, yCenter);
? ? ? ? path.lineTo(xCenter - 2 * _rod_width, radius - dp2px(5));
? ? ? ? path.lineTo((xCenter + 2 * _rod_width), radius - dp2px(5));
? ? ? ? path.lineTo(xCenter + _rod_width, yCenter);
? ? ? ? path.close();
? ? ? ? canvas.drawPath(path, mPaint);
? ? ? ? RectF rectF = new RectF(xCenter - 2 * _rod_width,
? ? ? ? ? ? ? ? radius - dp2px(8),
? ? ? ? ? ? ? ? xCenter + 2 * _rod_width,
? ? ? ? ? ? ? ? radius - dp2px(3));
? ? ? ? canvas.drawOval(rectF, mPaint);
? ? }
? ? private int dp2px(int dp) {
? ? ? ? return (int) (Resources.getSystem().getDisplayMetrics().density * dp + 0.5);
? ? }
}先畫(huà)風(fēng)車(chē)的桿,再在底部畫(huà)一個(gè)橢圓
畫(huà)風(fēng)車(chē)
public class WindmillView extends View {
? ? private int mWidth;
? ? private int mHeight;
? ? private Paint mPaint;
? ? private ObjectAnimator mRotationAnim;
? ? public WindmillView(Context context) {
? ? ? ? this(context, null);
? ? }
? ? public WindmillView(Context context, AttributeSet attrs) {
? ? ? ? this(context, attrs, 0);
? ? }
? ? public WindmillView(Context context, AttributeSet attrs, int defStyleAttr) {
? ? ? ? super(context, attrs, defStyleAttr);
? ? ? ? init();
? ? }
? ? private void init() {
? ? ? ? mPaint = new Paint();
? ? ? ? mPaint.setColor(Color.WHITE);
? ? ? ? mPaint.setStyle(Paint.Style.FILL);
? ? ? ? mPaint.setAntiAlias(true);
? ? ? ? mPaint.setDither(true);
? ? }
? ? @Override
? ? protected void onSizeChanged(int w, int h, int oldw, int oldh) {
? ? ? ? super.onSizeChanged(w, h, oldw, oldh);
? ? ? ? mWidth = getMeasuredWidth();
? ? ? ? mHeight = getMeasuredHeight();
? ? }
? ? @Override
? ? protected void onDraw(Canvas canvas) {
? ? ? ? int xCenter = mWidth / 2;
? ? ? ? int yCenter = mHeight / 3;
? ? ? ? int radius = mHeight / 3 * 2;
? ? ? ? canvas.drawCircle(xCenter, yCenter - dp2px(7), dp2px(4), mPaint);
? ? ? ? setPivotX(xCenter);
? ? ? ? setPivotY(yCenter - dp2px(7));
? ? ? ? canvas.save();
? ? ? ? for (int i = 0; i < 3; i++) {
? ? ? ? ? ? Path path = new Path();
? ? ? ? ? ? path.moveTo(xCenter, 0);
? ? ? ? ? ? path.lineTo(xCenter, yCenter - dp2px(11));
? ? ? ? ? ? path.lineTo(xCenter + dp2px(8), yCenter - dp2px(26));
? ? ? ? ? ? path.close();
// ? ? ? ?mPaint.setStrokeJoin(Paint.Join.ROUND);
? ? ? ? ? ? CornerPathEffect cornerPathEffect = new CornerPathEffect(30);
? ? ? ? ? ? mPaint.setPathEffect(cornerPathEffect);
? ? ? ? ? ? canvas.drawPath(path, mPaint);
? ? ? ? ? ? canvas.rotate(360 / 3, xCenter, yCenter - dp2px(7));
? ? ? ? }
? ? ? ? canvas.restore();
? ? ? ? startAnim();
? ? }
? ? private int dp2px(int dp) {
? ? ? ? return (int) (Resources.getSystem().getDisplayMetrics().density * dp + 0.5);
? ? }
? ? public void startAnim() {
? ? ? ? if (mRotationAnim != null && mRotationAnim.isRunning()) return;
? ? ? ? mRotationAnim = ObjectAnimator.ofFloat(this, "Rotation", 360f)
? ? ? ? ? ? ? ? .setDuration(3000);
? ? ? ? mRotationAnim.setRepeatCount(-1);
? ? ? ? mRotationAnim.setInterpolator(new LinearInterpolator());
? ? ? ? mRotationAnim.start();
? ? }
? ? public void stopAnim() {
? ? ? ? if (mRotationAnim != null && mRotationAnim.isRunning()) {
? ? ? ? ? ? mRotationAnim.cancel();
? ? ? ? ? ? mRotationAnim = null;
? ? ? ? }
? ? }
}這里使用畫(huà)面的旋轉(zhuǎn)方法,繪制扇頁(yè)
旋轉(zhuǎn)
使用屬性動(dòng)畫(huà)來(lái)旋轉(zhuǎn)
....
?public void startAnim() {
? ? ? ? if (mRotationAnim != null && mRotationAnim.isRunning()) return;
? ? ? ? mRotationAnim = ObjectAnimator.ofFloat(this, "Rotation", 360f)
? ? ? ? ? ? ? ? .setDuration(3000);
? ? ? ? mRotationAnim.setRepeatCount(-1);
? ? ? ? mRotationAnim.setInterpolator(new LinearInterpolator());
? ? ? ? mRotationAnim.start();
? ? }
? ? public void stopAnim() {
? ? ? ? if (mRotationAnim != null && mRotationAnim.isRunning()) {
? ? ? ? ? ? mRotationAnim.cancel();
? ? ? ? ? ? mRotationAnim = null;
? ? ? ? }
? ? }
?....在布局文件中使用
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" ? ? android:layout_width="match_parent" ? ? android:layout_height="match_parent" ? ? android:background="#000000"> ? ? <com.example.windmill.WindmillRodView ? ? ? ? android:layout_width="200dp" ? ? ? ? android:layout_height="200dp" ? ? ? ? android:layout_centerInParent="true" /> ? ? <com.example.windmill.WindmillView ? ? ? ? android:layout_width="200dp" ? ? ? ? android:layout_height="200dp" ? ? ? ? android:layout_centerInParent="true" /> </RelativeLayout>
這里只是介紹了如何繪制類(lèi)似的效果,很多計(jì)算都是寫(xiě)死的,如果要實(shí)際使用的話,最好寫(xiě)成自定義屬性通過(guò)xml屬性聲明傳進(jìn)去。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android?自定義View?加?lifecycle?簡(jiǎn)單使用詳解
本文介紹了自定義View的基本使用方法,包括onMeasure、onDraw、自定義樣式和lifecycle的使用,通過(guò)了解MeasureSpec的作用和lifecycle的控制,可以更好地管理View的生命周期,避免內(nèi)存泄露問(wèn)題,感興趣的朋友一起看看吧2025-03-03
Android app會(huì)crash的原因及解決方法
這篇文章主要介紹了Android app會(huì)crash的原因及解決方法,幫助大家更好的進(jìn)行Android開(kāi)發(fā),感興趣的朋友可以了解下2020-12-12
Android RecycleView 實(shí)現(xiàn)左滑上下分層示例代碼(自定義功能)
這篇文章主要介紹了Android RecycleView 實(shí)現(xiàn)左滑上下分層示例代碼(自定義功能),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03
Android使用URLConnection提交請(qǐng)求的實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Android使用URLConnection提交請(qǐng)求的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10
loadavg數(shù)據(jù)異常引發(fā)問(wèn)題起源分析
這篇文章主要為大家介紹了loadavg數(shù)據(jù)異常引發(fā)問(wèn)題起源分析詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11
Flutter質(zhì)感設(shè)計(jì)之彈出菜單
這篇文章主要為大家詳細(xì)介紹了Flutter質(zhì)感設(shè)計(jì)之彈出菜單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08
Android app啟動(dòng)時(shí)黑屏或者白屏的原因及解決辦法
這篇文章主要介紹了Android app啟動(dòng)時(shí)黑屏或者白屏的原因及解決辦法的相關(guān)資料,需要的朋友可以參考下2016-09-09
使用OkHttp包在Android中進(jìn)行HTTP頭處理的教程
HTTP頭部處理是HTTP網(wǎng)絡(luò)編程中的基本操作,安卓中使用OkHttp包(github.com/square/okhttp)進(jìn)行相關(guān)操作當(dāng)然也是得心應(yīng)手,這里我們就來(lái)看一下使用OkHttp包在Android中進(jìn)行HTTP頭處理的教程2016-07-07

