如何在android中创建电池电量指示器?
我想创建一个电池电量指示器,如图所示(我在图中圈出)。绿色部分应根据设备中的可用电池填充 像这样从设备获取电池百分比如何在android中创建电池电量指示器?,android,android-layout,user-interface,batterylevel,Android,Android Layout,User Interface,Batterylevel,我想创建一个电池电量指示器,如图所示(我在图中圈出)。绿色部分应根据设备中的可用电池填充 像这样从设备获取电池百分比 registerReceiver(mBatInfoReceiver, new IntentFilter( Intent.ACTION_BATTERY_CHANGED)); 因此,在布局中,我能够显示电池百分比 public class BatteryIndicatorActivity extends Activity { //Create
registerReceiver(mBatInfoReceiver, new IntentFilter(
Intent.ACTION_BATTERY_CHANGED));
因此,在布局中,我能够显示电池百分比
public class BatteryIndicatorActivity extends Activity {
//Create Broadcast Receiver Object along with class definition
private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver() {
@Override
//When Event is published, onReceive method is called
public void onReceive(Context c, Intent i) {
//Get Battery %
int level = i.getIntExtra("level", 0);
TextView tv = (TextView) findViewById(R.id.textfield);
//Set TextView with text
tv.setText("Battery Level: " + Integer.toString(level) + "%");
}
};
但是如何为这种类型的电池指示器创建UI。他们是否有api来实现这一点?如果没有,如何创建这种类型的UI
我们将感谢您的帮助。有很多方法可以做到这一点。以下是其中的几个:
进度条
,使其垂直,使其以电池形状绘制视图
,在其中覆盖onDraw()
,并在画布上绘制电池形状
有很多方法可以做到这一点。以下是其中的几个:
进度条
,使其垂直,使其以电池形状绘制视图
,在其中覆盖onDraw()
,并在画布上绘制电池形状
这是显示电池电量的自定义视图
class BatteryView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
View(context, attrs, defStyleAttr) {
private var radius: Float = 0f
private var isCharging: Boolean = false
// Top
private var topPaint =
PaintDrawable(Color.WHITE) // I only want to corner top-left and top-right so I use PaintDrawable instead of Paint
private var topRect = Rect()
private var topPaintWidthPercent = 50
private var topPaintHeightPercent = 8
// Border
private var borderPaint = Paint().apply {
color = Color.BLUE
style = Paint.Style.STROKE
}
private var borderRect = RectF()
private var borderStrokeWidthPercent = 8
private var borderStroke: Float = 0f
// Percent
private var percentPaint = Paint()
private var percentRect = RectF()
private var percentRectTopMin = 0f
private var percent: Int = 0
// Charging
private var chargingRect = RectF()
private var chargingBitmap: Bitmap? = null
init {
init(attrs)
chargingBitmap = getBitmap(R.drawable.ic_charging)
}
private fun init(attrs: AttributeSet?) {
val ta = context.obtainStyledAttributes(attrs, R.styleable.BatteryView)
try {
percent = ta.getInt(R.styleable.BatteryView_bv_percent, 0)
isCharging = ta.getBoolean(R.styleable.BatteryView_bv_charging, false)
} finally {
ta.recycle()
}
}
@SuppressLint("DrawAllocation")
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val measureWidth = View.getDefaultSize(suggestedMinimumWidth, widthMeasureSpec)
val measureHeight = (measureWidth * 1.8f).toInt()
setMeasuredDimension(measureWidth, measureHeight)
radius = borderStroke / 2
borderStroke = (borderStrokeWidthPercent * measureWidth).toFloat() / 100
// Top
val topLeft = measureWidth * ((100 - topPaintWidthPercent) / 2) / 100
val topRight = measureWidth - topLeft
val topBottom = topPaintHeightPercent * measureHeight / 100
topRect = Rect(topLeft, 0, topRight, topBottom)
// Border
val borderLeft = borderStroke / 2
val borderTop = topBottom.toFloat() + borderStroke / 2
val borderRight = measureWidth - borderStroke / 2
val borderBottom = measureHeight - borderStroke / 2
borderRect = RectF(borderLeft, borderTop, borderRight, borderBottom)
// Progress
val progressLeft = borderStroke
percentRectTopMin = topBottom + borderStroke
val progressRight = measureWidth - borderStroke
val progressBottom = measureHeight - borderStroke
percentRect = RectF(progressLeft, percentRectTopMin, progressRight, progressBottom)
// Charging Image
val chargingLeft = borderStroke
var chargingTop = topBottom + borderStroke
val chargingRight = measureWidth - borderStroke
var chargingBottom = measureHeight - borderStroke
val diff = ((chargingBottom - chargingTop) - (chargingRight - chargingLeft))
chargingTop += diff / 2
chargingBottom -= diff / 2
chargingRect = RectF(chargingLeft, chargingTop, chargingRight, chargingBottom)
}
override fun onDraw(canvas: Canvas) {
drawTop(canvas)
drawBody(canvas)
if (!isCharging) {
drawProgress(canvas, percent)
} else {
drawCharging(canvas)
}
}
private fun drawTop(canvas: Canvas) {
topPaint.bounds = topRect
topPaint.setCornerRadii(floatArrayOf(radius, radius, radius, radius, 0f, 0f, 0f, 0f))
topPaint.draw(canvas)
}
private fun drawBody(canvas: Canvas) {
borderPaint.strokeWidth = borderStroke
canvas.drawRoundRect(borderRect, radius, radius, borderPaint)
}
private fun drawProgress(canvas: Canvas, percent: Int) {
percentPaint.color = getPercentColor(percent)
percentRect.top = percentRectTopMin + (percentRect.bottom - percentRectTopMin) * (100 - percent) / 100
canvas.drawRect(percentRect, percentPaint)
}
// todo change color
private fun getPercentColor(percent: Int): Int {
if (percent > 50) {
return Color.WHITE
}
if (percent > 30) {
return Color.YELLOW
}
return Color.RED
}
private fun drawCharging(canvas: Canvas) {
chargingBitmap?.let {
canvas.drawBitmap(it, null, chargingRect, null)
}
}
private fun getBitmap(drawableId: Int, desireWidth: Int? = null, desireHeight: Int? = null): Bitmap? {
val drawable = AppCompatResources.getDrawable(context, drawableId) ?: return null
val bitmap = Bitmap.createBitmap(
desireWidth ?: drawable.intrinsicWidth,
desireHeight ?: drawable.intrinsicHeight,
Bitmap.Config.ARGB_8888
)
val canvas = Canvas(bitmap)
drawable.setBounds(0, 0, canvas.width, canvas.height)
drawable.draw(canvas)
return bitmap
}
fun charge() {
isCharging = true
invalidate() // can improve by invalidate(Rect)
}
fun unCharge() {
isCharging = false
invalidate()
}
fun setPercent(percent: Int) {
if (percent > 100 || percent < 0) {
return
}
this.percent = percent
invalidate()
}
fun getPercent(): Int {
return percent
}
}
class BatteryView@JVM重载构造函数(上下文:context,attrs:AttributeSet?=null,defStyleAttr:Int=0):
视图(上下文、属性、defStyleAttr){
专用变量半径:浮点=0f
专用var放电:布尔值=false
//顶
私人油漆=
PaintDrawable(Color.WHITE)//我只想左上角和右上角,所以我使用PaintDrawable而不是Paint
私有变量topRect=Rect()
私有风险值百分比=50
私有变量topPaintHeightPercent=8
//边界
私有变量borderPaint=Paint()。应用{
颜色=color.BLUE
style=Paint.style.STROKE
}
私有变量borderRect=RectF()
私有变量borderStrokeWidthPercent=8
私有变量borderStroke:Float=0f
//百分比
私有变量percentPaint=Paint()
私有变量percentRect=RectF()
私有变量percentRectTopMin=0f
私有变量百分比:Int=0
//充电
私有变量chargingRect=RectF()
私有变量chargingBitmap:位图?=null
初始化{
初始化(属性)
chargingBitmap=getBitmap(R.drawable.ic_充电)
}
私人娱乐初始(属性集?){
val ta=context.actainstyledattributes(attrs,R.styleable.battyview)
试一试{
percent=ta.getInt(R.styleable.BatteryView\u bv\u percent,0)
放电=ta.getBoolean(R.styleable.BatteryView\u bv\u充电,false)
}最后{
ta.回收()
}
}
@SuppressLint(“DrawAllocation”)
覆盖测量时的乐趣(widthMeasureSpec:Int,heightMeasureSpec:Int){
val measureWidth=View.getDefaultSize(建议的最小宽度、宽度度量等级)
val measurewhight=(measureWidth*1.8f).toInt()
设置测量尺寸(测量宽度、测量高度)
半径=边界笔划/2
borderStroke=(borderStrokeWidthPercent*measureWidth).toFloat()/100
//顶
val topLeft=测量宽度*((100-topPaintWidthPercent)/2)/100
val topRight=测量宽度-topLeft
val topBottom=顶部高度百分比*测量高度/100
topRect=Rect(上左、0、上右、上下)
//边界
val borderLeft=borderStroke/2
val borderTop=topBottom.toFloat()+borderStroke/2
val borderRight=测量宽度-边界笔划/2
val borderBottom=测量高度-borderStroke/2
borderRect=RectF(borderLeft、borderTop、borderRight、borderBottom)
//进展
val progressLeft=边界笔划
percentRectTopMin=上下+边界笔划
val progressRight=测量宽度-边界行程
val progressBottom=测量高度-边界行程
percentRect=RectF(progressLeft、percentRectTopMin、progressRight、progressBottom)
//充电图像
val chargingLeft=边界笔划
var chargingTop=上下+边界笔划
val chargingRight=测量宽度-边界行程
var chargingBottom=测量高度-边界冲程
val diff=((chargingBottom-chargingTop)-(chargingRight-chargingLeft))
chargingTop+=diff/2
chargingBottom-=diff/2
chargingRect=RectF(chargingLeft、chargingTop、chargingRight、chargingBottom)
}
覆盖onDraw(画布:画布){
拉手(帆布)
抽体(帆布)
如果(!放电){
绘图进度(画布,百分比)
}否则{
抽纱(帆布)
}
}
私人趣味吸顶(帆布:帆布){
topaint.bounds=topRect
topPaint.setCornerRadii(浮动阵列OF(半径、半径、半径、半径、0f、0f、0f、0f))
顶部绘制(画布)
}
私人趣味抽体(帆布:帆布){
borderPaint.strokeWidth=borderStroke
canvas.drawRoundRect(borderRect,radius,radius,borderPaint)
}
私人趣味drawProgress(画布:画布,百分比:整数){
percentPaint.color=getPercentColor(百分比)
percentRect.top=percentRectTopMin+(percentRect.bottom-percentRectTopMin)*(100%)/100
canvas.drawRect(percentRect,percentPaint)
}
//todo变色
私人娱乐getPercentColor(百分比:Int):Int{
如果(百分比>50){
返回颜色。白色
}
如果(百分比>30){
返回颜色。黄色
}
返回颜色:红色
}
私人娱乐抽奖收费(画布:画布){
Charging?让我来{
可以
<declare-styleable name="BatteryView">
<attr name="bv_charging" format="boolean" />
<attr name="bv_percent" format="integer" />
</declare-styleable>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="368.492"
android:viewportHeight="368.492">
<path
android:fillColor="#FFFFFF"
android:pathData="M297.51,150.349c-1.411,-2.146 -3.987,-3.197 -6.497,-2.633l-73.288,16.498L240.039,7.012c0.39,-2.792 -1.159,-5.498 -3.766,-6.554c-2.611,-1.069 -5.62,-0.216 -7.283,2.054L71.166,217.723c-1.489,2.035 -1.588,4.773 -0.246,6.911c1.339,2.132 3.825,3.237 6.332,2.774l79.594,-14.813l-23.257,148.799c-0.436,2.798 1.096,5.536 3.714,6.629c0.769,0.312 1.562,0.469 2.357,0.469c1.918,0 3.78,-0.901 4.966,-2.517l152.692,-208.621C298.843,155.279 298.916,152.496 297.51,150.349z" />
</vector>
<package.BatteryView
android:id="@+id/battery_view"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:src="@drawable/ic_charging"
app:bv_charging="false"
app:bv_percent="20" />