AndroidカスタムView-バッテリ
73741 ワード
AndroidカスタムView-バッテリ
概要
最近の仕事の中で1つの需要があって、电量を表示する必要があって、制品は前の开発がすでにしたと言って、别のプロジェクトの中で、コピーしてくれればいいです.はい、それではコピーしましょう.結果を見ると、本当に驚きました.layer-listのdrawableを使っています.中には11種類の状態があります.0から100%です.11%を表示するにはどうすればいいですか?はい、この穴はもうおかしくありません.他の穴に比べて、これは問題ではありません.穴を埋めましょう.
バッテリビューの要件図は1%から100%の電力量を示している. デジタル表示1-100、構成可能; 電池は低電力で、電力量が十分で、充電時に異なる色を表示します. は、バッテリの外枠の色とstrokeサイズを設定することができる. は、横方向表示または縦方向表示のいずれかを選択することができる .
カスタムビュー
このバッテリViewの要件は、Viewを継承してBatteryViewをカスタマイズすることによって実現されます.カスタムビューのコンセプトはこのブログを参考にすることができ、よく書かれています.カスタムビューには、次の4つのカテゴリがあります.カスタムコンビネーションコントロール、例えばカスタム共通ActionBar; は、TextView、LinearLayoutなどのシステムが提供する特定のView、View Groupを継承する. はandroidを継承する.view.Viewは独自のView を実現はandroidを継承する.view.ViewGroupは自分のViewGroupを実現します.
カスタムViewの知識については、ここでは詳しく説明するが、カスタムバッテリViewのニーズを実現するには、3つ目を選択してandroidを継承することができる.view.Viewは、onDrawを書き換え、この方法でバッテリーのニーズを描きます.
BatteryView実装
効率を高めるため、このブログAndroidカスタムバッテリーコントロールに基づいて修正します(paddingといくつかの属性を追加しました).実装手順は次のとおりです.新規attrs.xmlはプロパティファイルを定義し、BatteryViewのプロパティを追加します. はViewを継承し、BatteryViewを実現する. は、構造関数において各属性を解析する. onDrawを書き換え、プロパティに基づいてバッテリのアウトライン、バッテリ電力、バッテリキャップ、および電力パーセントを描画します.
比較的簡単で、直接コードを貼り付けます. attrs.xml BatteryView.java
テストレイアウトファイルにコード を追加するは、Activityにおいてインスタンス化された後、電力量変更時にメソッドを呼び出して電力量値 を変更する.
総括と思考
実装中に注意すべき点は次のとおりです. paddingを考慮しなければならない.そうしないと、ユーザーがpaddingを設定すると左上隅にしか表示されない. 文字を描くときはペイントで文字の幅を計算します.そうしないと劇中にはできません. 必要に応じて、どのような属性が必要かを考慮し、外観をよりよくカスタマイズするには、より多くのことを考慮します.
不足:はフィレットを実現していない. は充電中のアニメーションを提供していません.呼び出し者が自分でアニメーションを書く必要があります.
リファレンス
AndroidカスタムバッテリーコントロールAndroidカスタムView全解
概要
最近の仕事の中で1つの需要があって、电量を表示する必要があって、制品は前の开発がすでにしたと言って、别のプロジェクトの中で、コピーしてくれればいいです.はい、それではコピーしましょう.結果を見ると、本当に驚きました.layer-listのdrawableを使っています.中には11種類の状態があります.0から100%です.11%を表示するにはどうすればいいですか?はい、この穴はもうおかしくありません.他の穴に比べて、これは問題ではありません.穴を埋めましょう.
バッテリビューの要件
カスタムビュー
このバッテリViewの要件は、Viewを継承してBatteryViewをカスタマイズすることによって実現されます.カスタムビューのコンセプトはこのブログを参考にすることができ、よく書かれています.カスタムビューには、次の4つのカテゴリがあります.
カスタムViewの知識については、ここでは詳しく説明するが、カスタムバッテリViewのニーズを実現するには、3つ目を選択してandroidを継承することができる.view.Viewは、onDrawを書き換え、この方法でバッテリーのニーズを描きます.
BatteryView実装
効率を高めるため、このブログAndroidカスタムバッテリーコントロールに基づいて修正します(paddingといくつかの属性を追加しました).実装手順は次のとおりです.
比較的簡単で、直接コードを貼り付けます.
<declare-styleable name="Battery">
<attr name="batteryOrientation">
<enum name="horizontal" value="0"/>
<enum name="vertical" value="1"/>
attr>
<attr name="batteryColor" format="color"/>
<attr name="batteryStrokeWidth" format="dimension" />
<attr name="batteryLowBatteryColor" format="color" />
<attr name="batteryHealthBatteryColor" format="color" />
<attr name="batteryHappyBatteryColor" format="color" />
<attr name="batteryChargingColor" format="color" />
<attr name="batteryPower" format="integer"/>
<attr name="batteryShowPercent" format="boolean" />
<attr name="batteryPercentColor" format="color"/>
<attr name="batteryPercentSize" format="dimension" />
declare-styleable>
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
import androidx.annotation.Dimension;
import androidx.annotation.IntDef;
import com.bottle.app.R;
import com.bottle.app.device.DisplayUtil;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* \
*/
public class BatteryView extends View {
public static final int HORIZONTAL = 0;
public static final int VERTICAL = 1;
@Retention(RetentionPolicy.SOURCE)
@IntDef({HORIZONTAL, VERTICAL})
@interface Orientation {
}
private int mPower = 100; //
private int orientation; //
private int mStrokeColor; //
private int mStrokeWidth; //
private int mLowBatteryColor; //
private int mHealthBatteryColor; //
private int mHappyBatteryColor; //
private boolean mCharging; //
private int mChargingColor; //
private boolean mShowPercent; //
private int mPercentColor; //
private float mPercentSize; //
private int width;
private int height;
private int headWidth; //
private int headHeight; //
private int mLowBattery = 20; //
private int mHealthBattery = 50; //
private Paint mPaint = new Paint();
public void setPower(int power) {
this.mPower = power;
if (mPower < 0) {
mPower = 0;
} else if (mPower > 100) {
mPower = 100;
}
invalidate();
}
public void setColor(@ColorRes int color) {
this.mStrokeColor = color;
}
public void setOrientation(@Orientation int orientation) {
this.orientation = orientation;
}
public void setStrokeColor(@ColorInt int strokeColor) {
mStrokeColor = strokeColor;
}
public void setStrokeWith(@Dimension int strokeWidth) {
mStrokeWidth = strokeWidth;
}
public void setLowBatteryColor(@ColorInt int lowBatteryColor) {
mLowBatteryColor = lowBatteryColor;
}
public void setHealthBatteryColor(@ColorInt int healthBatteryColor) {
mHealthBatteryColor = healthBatteryColor;
}
public void setHappyBatteryColor(@ColorInt int happyBatteryColor) {
mHappyBatteryColor = happyBatteryColor;
}
public void setCharging(boolean charging) {
mCharging = charging;
}
public void setChargingColor(@ColorInt int chargingColor) {
mChargingColor = chargingColor;
}
public void setLowBattery(int lowBattery) {
mLowBattery = lowBattery;
}
public void setHealthBattery(int healthBattery) {
mHealthBattery = healthBattery;
}
public void setShowPercent(boolean showPercent) {
mShowPercent = showPercent;
}
public void setPercentColor(@ColorInt int percentColor) {
mPercentColor = percentColor;
}
public void setPercentSize(@Dimension int percentSize) {
mPercentSize = percentSize;
}
public BatteryView(Context context) {
super(context);
}
public BatteryView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.Battery);
mStrokeColor = typedArray.getColor(R.styleable.Battery_batteryColor, Color.BLACK);
mStrokeWidth = typedArray.getDimensionPixelOffset(
R.styleable.Battery_batteryStrokeWidth, DisplayUtil.dip2px(context, 1));
mLowBatteryColor = typedArray.getColor(R.styleable.Battery_batteryLowBatteryColor, Color.RED);
mHealthBatteryColor = typedArray.getColor(R.styleable.Battery_batteryHealthBatteryColor, Color.parseColor("#76AE00"));
mHappyBatteryColor = typedArray.getColor(R.styleable.Battery_batteryHappyBatteryColor, Color.GREEN);
mChargingColor = typedArray.getColor(R.styleable.Battery_batteryColor, Color.YELLOW);
orientation = typedArray.getInt(R.styleable.Battery_batteryOrientation, 0);
mPower = typedArray.getInt(R.styleable.Battery_batteryPower, 100);
mShowPercent = typedArray.getBoolean(R.styleable.Battery_batteryShowPercent, false);
mPercentColor = typedArray.getColor(R.styleable.Battery_batteryPercentColor, Color.BLACK);
mPercentSize = typedArray.getDimensionPixelOffset(
R.styleable.Battery_batteryPercentSize, DisplayUtil.sp2px(context, 11));
typedArray.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getMeasuredWidth();
height = getMeasuredHeight();
if (orientation == HORIZONTAL) {
headWidth = (height - getPaddingTop() - getPaddingBottom() - mStrokeWidth * 2) / 2;
} else {
headWidth = (width - getPaddingStart() - getPaddingEnd() - mStrokeWidth * 2) / 2;
}
headHeight = headWidth / 2;
int max = DisplayUtil.dip2px(getContext(), 8);
if (headHeight > max) {
//
headHeight = max;
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (orientation == HORIZONTAL) {
drawHorizontalBattery(canvas);
} else {
drawVerticalBattery(canvas);
}
}
private void drawHorizontalBattery(Canvas canvas) {
float strokeWithHalf = mStrokeWidth / 2f;
// 1.
mPaint.setColor(mStrokeColor);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(mStrokeWidth);
RectF r1 = new RectF(getPaddingStart() + strokeWithHalf,
getPaddingTop() + strokeWithHalf,
width - getPaddingEnd() - headHeight,
height - getPaddingBottom() - strokeWithHalf);
canvas.drawRect(r1, mPaint);
// 2.
mPaint.setStyle(Paint.Style.FILL);
float offset = (width - getPaddingStart() - getPaddingEnd() - mStrokeWidth * 2 - headHeight) * mPower / 100.f;
RectF r2 = new RectF(getPaddingStart() + mStrokeWidth,
getPaddingTop() + mStrokeWidth,
getPaddingStart() + mStrokeWidth + offset + strokeWithHalf, // padding + + + ( )
height - getPaddingBottom() - mStrokeWidth);
if (mCharging) {
mPaint.setColor(mChargingColor);
} else if (mPower < mLowBattery) {
mPaint.setColor(mLowBatteryColor);
} else if (mPower < mHealthBattery) {
mPaint.setColor(mHealthBatteryColor);
} else {
mPaint.setColor(mHappyBatteryColor);
}
canvas.drawRect(r2, mPaint);
// 3.
RectF r3 = new RectF(width - getPaddingEnd() - headHeight,
height / 2f - headWidth / 2f,
width - getPaddingEnd(),
height / 2f + headWidth / 2f);
mPaint.setColor(mStrokeColor);
canvas.drawRect(r3, mPaint);
// 4.
if (mShowPercent) {
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setTextAlign(Paint.Align.CENTER);
mPaint.setTextSize(mPercentSize);
mPaint.setColor(mPercentColor);
mPaint.setStrokeWidth(1);
String text = String.valueOf(mPower);
canvas.drawText(text,
width / 2f - mPaint.measureText(text) / 2,
height / 2f + (mPaint.getFontMetrics().bottom - mPaint.getFontMetrics().top) / 2 - mPaint.getFontMetrics().bottom,
mPaint);
}
}
private void drawVerticalBattery(Canvas canvas) {
float strokeWithHalf = mStrokeWidth / 2f;
// 1.
mPaint.setColor(mStrokeColor);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(mStrokeWidth);
RectF r1 = new RectF(getPaddingStart() + strokeWithHalf,
getPaddingTop() + headHeight,
width - getPaddingEnd(),
height - getPaddingBottom() - strokeWithHalf);
canvas.drawRect(r1, mPaint);
// 2.
mPaint.setStyle(Paint.Style.FILL);
float offset = (height - getPaddingTop() - getPaddingBottom() - mStrokeWidth * 2 - headHeight) * mPower / 100.f;
RectF r2 = new RectF(getPaddingStart() + mStrokeWidth,
height - getPaddingTop() - mStrokeWidth - offset - strokeWithHalf ,
width - getPaddingEnd() - strokeWithHalf,
height - getPaddingBottom() - mStrokeWidth);
if (mCharging) {
mPaint.setColor(mChargingColor);
} else if (mPower < mLowBattery) {
mPaint.setColor(mLowBatteryColor);
} else if (mPower < mHealthBattery) {
mPaint.setColor(mHealthBatteryColor);
} else {
mPaint.setColor(mHappyBatteryColor);
}
canvas.drawRect(r2, mPaint);
// 3.
RectF r3 = new RectF(width / 2f - headWidth / 2f,
getPaddingTop(),
width / 2f + headWidth / 2f,
getPaddingTop() + headHeight);
mPaint.setColor(mStrokeColor);
canvas.drawRect(r3, mPaint);
// 4.
if (mShowPercent) {
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setTextAlign(Paint.Align.CENTER);
mPaint.setTextSize(mPercentSize);
mPaint.setColor(mPercentColor);
mPaint.setStrokeWidth(1);
String text = String.valueOf(mPower);
canvas.drawText(text,
width / 2f,
height / 2f + (mPaint.getFontMetrics().bottom - mPaint.getFontMetrics().top) / 2 - mPaint.getFontMetrics().bottom,
mPaint);
}
}
}
テスト
<com.bottle.app.widget.BatteryView
android:id="@+id/batteryView3"
android:layout_width="@dimen/dp_49"
android:layout_height="@dimen/dp_80"
android:padding="@dimen/dp_2"
app:batteryShowPercent="true"
app:batteryPower="100"
app:batteryColor="@android:color/black"
app:batteryOrientation="vertical" />
private Runnable mAction = new Runnable() {
@Override
public void run() {
int pow = power++ % 100;
mBatteryView.setPower(pow);
mBatteryView.postDelayed(mAction, 100);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBatteryView = findViewById(R.id.batteryView);
mBatteryView.post(mAction);
}
総括と思考
実装中に注意すべき点は次のとおりです.
不足:
リファレンス
AndroidカスタムバッテリーコントロールAndroidカスタムView全解