Android 12.0 电池图标客制化,横放,仿苹果。

您所在的位置:网站首页 安卓状态栏修改5g图标显示无法使用 Android 12.0 电池图标客制化,横放,仿苹果。

Android 12.0 电池图标客制化,横放,仿苹果。

2024-07-11 13:17| 来源: 网络整理| 查看: 265

目录

一、概述

二、电池图标显示所在源码分析

三、自定义电池图标 

四、总结

 

一、概述

原生的电池图标是竖向,并且很小,不太美观。现客户需求状态栏的电池图标变为横放的。众所周知,状态栏的修改在SystemUI里。

效果图:

二、电池图标显示所在源码分析

 状态栏布局文件是status_bar。路径:SystemUI\res\layout\status_bar.xml

..省略部分代码..

电池图标就在布局system_icons中,路径:SystemUI\res\layout\system_icons.xml

其中BatteryMeterView是自定义View,继承于LinearLayout,实现的接口有BatteryStateChangeCallback,Tunable,DarkReceiver,ConfigurationListener。主要是监听电池状态变化,白天黑夜模式,以及主题等变化。

public class BatteryMeterView extends LinearLayout implements BatteryStateChangeCallback, Tunable, DarkReceiver, ConfigurationListener {}

而锁屏界面的状态栏也是引用到这个BatteryMeterView,在路径SystemUI\src\com\android\systemui\statusbar\phone\KeyguardStatusBarView.java中

private BatteryMeterView mBatteryView;

OK,明白了大概的逻辑,就可以自己试着重构了。

三、自定义电池图标 

如果在原文件 BatteryMeterView中修改太过麻烦,所以我们可以模仿BatteryMeterView,直接自己写一个自定义View。

直接上主菜!

1.在system_icons.xml中替换布局。 

 bird_status_bar_battery.xml

可以看到,上面的布局是一个横向的LinearLayout。

1.其中有outside和inside的电量百分比,百分比的显示或隐藏可以在设置-电池中去控制,也可以直接写死一种方式。

2.outside的充电图标和inside的充电图标,就是开始充电后显示的闪电图标,可以选择在电池内也可以选择在外侧。充电图标和电量百分比是对立的,如果充电图标inside,则电量百分比outside,反之亦然。

3.border是电池的边界,就是最外的一圈。

4.charge_level用list来管理,一共有10来个等级。电量的多少就是从这里体现。

 

2.布局中的src都是矢量图,具体的矢量图代码在另一篇文章中。可以参考一下。

传送门:http://t.csdn.cn/BgwqF

 3.自定义view,BirdBatteryMeterView同样继承于LinearLayout

package com.bird.systemui; import android.app.ActivityManager; import android.content.Context; import android.database.ContentObserver; import android.graphics.Rect; import android.net.Uri; import android.os.Handler; import android.os.PowerManager; import android.provider.Settings; import android.text.TextUtils; import android.util.ArraySet; import android.util.AttributeSet; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.Nullable; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.settings.CurrentUserTracker; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback; import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener; import com.android.systemui.tuner.TunerService.Tunable; import java.io.FileDescriptor; import java.io.PrintWriter; import java.text.NumberFormat; import java.util.Optional; import static android.provider.Settings.System.SHOW_BATTERY_PERCENT; import static com.android.systemui.DejankUtils.whitelistIpcs; //[状态栏更换新的电池图标][huangjiawei][20230427] public class BirdBatteryMeterView extends LinearLayout implements BatteryStateChangeCallback, Tunable, DarkReceiver, ConfigurationListener { private ImageView mBorderView; private ImageView mInsideChargeIconView; private ImageView mOutsideChargeIconView; private ImageView mLevelView; private TextView mInsidePercentView; private TextView mOutsidePercentView; private BatteryController mBatteryController; private int mUser; private final SettingObserver mSettingObserver; private final boolean mShowPercentAvailable; private final CurrentUserTracker mUserTracker; private int mNonAdaptedColor; private final String mSlotBattery; private int mLevel; private boolean mShowPercent; private boolean mShowPercentIn; private boolean mIsPowerSave; private boolean mCharging; public BirdBatteryMeterView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public BirdBatteryMeterView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); BroadcastDispatcher broadcastDispatcher = Dependency.get(BroadcastDispatcher.class); mSettingObserver = new SettingObserver(new Handler(context.getMainLooper())); mShowPercentAvailable = context.getResources().getBoolean( com.android.internal.R.bool.config_battery_percentage_setting_available); mSlotBattery = context.getString( com.android.internal.R.string.status_bar_battery); mUserTracker = new CurrentUserTracker(broadcastDispatcher) { @Override public void onUserSwitched(int newUserId) { mUser = newUserId; getContext().getContentResolver().unregisterContentObserver(mSettingObserver); getContext().getContentResolver().registerContentObserver( Settings.System.getUriFor(SHOW_BATTERY_PERCENT), false, mSettingObserver, newUserId); updateShowPercent(); updatePercentLevel(); } }; } @Override protected void onFinishInflate() { super.onFinishInflate(); mBorderView = findViewById(R.id.battery_border); mLevelView = findViewById(R.id.battery_level); mInsidePercentView = findViewById(R.id.battery_inside_percent); mOutsidePercentView = findViewById(R.id.battery_outside_percent); mInsideChargeIconView = findViewById(R.id.battery_inside_charge_icon); mOutsideChargeIconView = findViewById(R.id.battery_outside_charge_icon); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); mBatteryController = Dependency.get(BatteryController.class); mBatteryController.addCallback(this); mUser = ActivityManager.getCurrentUser(); getContext().getContentResolver().registerContentObserver( Settings.System.getUriFor(SHOW_BATTERY_PERCENT), false, mSettingObserver, mUser); getContext().getContentResolver().registerContentObserver( Settings.Global.getUriFor(Settings.Global.BATTERY_ESTIMATES_LAST_UPDATE_TIME), false, mSettingObserver); mUserTracker.startTracking(); updateShowPercent(); updatePercentLevel(); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); mUserTracker.stopTracking(); mBatteryController.removeCallback(this); getContext().getContentResolver().unregisterContentObserver(mSettingObserver); } @Override public void onDarkChanged(Rect area, float darkIntensity, int tint) { mNonAdaptedColor = DarkIconDispatcher.getTint(area, this, tint); mOutsidePercentView.setTextColor(mNonAdaptedColor); mInsidePercentView.setTextColor(mNonAdaptedColor); mInsideChargeIconView.setColorFilter(mNonAdaptedColor); mOutsideChargeIconView.setColorFilter(mNonAdaptedColor); if (!mIsPowerSave) { mBorderView.setColorFilter(mNonAdaptedColor); } if (!isLowLevel() || mCharging) { mLevelView.setColorFilter(mNonAdaptedColor); } } @Override public void onTuningChanged(String key, String newValue) { if (StatusBarIconController.ICON_HIDE_LIST.equals(key)) { ArraySet icons = StatusBarIconController.getIconHideList( getContext(), newValue); setVisibility(icons.contains(mSlotBattery) ? View.GONE : View.VISIBLE); } } @Override public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) { mLevel = level; mCharging = charging; updatePercentLevel(); updatePercentText(); } @Override public void onPowerSaveChanged(boolean isPowerSave) { PowerManager powerManager = getContext().getSystemService(PowerManager.class); mIsPowerSave = powerManager.isPowerSaveMode(); if (mIsPowerSave) { mBorderView.setColorFilter(mContext.getColor(R.color.bird_battry_power_save_color)); } else { mBorderView.setColorFilter(mNonAdaptedColor); } } private final class SettingObserver extends ContentObserver { public SettingObserver(Handler handler) { super(handler); } @Override public void onChange(boolean selfChange, @Nullable Uri uri) { super.onChange(selfChange, uri); updateShowPercent(); updatePercentLevel(); if (TextUtils.equals(uri.getLastPathSegment(), Settings.Global.BATTERY_ESTIMATES_LAST_UPDATE_TIME)) { updatePercentText(); } } } private void updatePercentText() { if (mBatteryController == null) { return; } if (mOutsidePercentView != null || mInsidePercentView != null) { if (!mCharging) { mBatteryController.getEstimatedTimeRemainingString((String estimate) -> { if (estimate != null) { Optional.ofNullable(mOutsidePercentView).ifPresent(view -> view.setText(estimate)); Optional.ofNullable(mInsidePercentView).ifPresent(view -> view.setText(estimate)); setContentDescription(getContext().getString( R.string.accessibility_battery_level_with_estimate, mLevel, estimate)); } else { setPercentTextAtCurrentLevel(); } }); } else { setPercentTextAtCurrentLevel(); } } else { setContentDescription( getContext().getString(mCharging ? R.string.accessibility_battery_level_charging : R.string.accessibility_battery_level, mLevel)); } } private void setPercentTextAtCurrentLevel() { mOutsidePercentView.setText( NumberFormat.getPercentInstance().format(mLevel / 100f)); mInsidePercentView.setText(NumberFormat.getNumberInstance().format(mLevel)); setContentDescription( getContext().getString(mCharging ? R.string.accessibility_battery_level_charging : R.string.accessibility_battery_level, mLevel)); } private void updateShowPercent() { //读设置中是否显示电量百分比的值 mShowPercent = 0 != whitelistIpcs(() -> Settings.System .getIntForUser(getContext().getContentResolver(), SHOW_BATTERY_PERCENT, 0, mUser)); //这个值同样可以在设置-电池中加两项去让用户决定用哪种方式,也可以直接像这里的值一样,直接写死一种方式。 mShowPercentIn = true; if (mShowPercentAvailable && mShowPercent) { mOutsidePercentView.setVisibility(!mShowPercentIn ? View.VISIBLE : View.GONE); mInsidePercentView.setVisibility(mShowPercentIn ? View.VISIBLE : View.GONE); updatePercentText(); } else { mOutsidePercentView.setVisibility(View.GONE); mInsidePercentView.setVisibility(View.GONE); } } private void updatePercentLevel() { //电量百分比和充电图标出现的位置是对立的 boolean showInsidePercent = mShowPercent && mShowPercentIn; mInsideChargeIconView.setVisibility(mCharging && !showInsidePercent ? View.VISIBLE : View.GONE); mOutsideChargeIconView.setVisibility(mCharging && showInsidePercent ? View.VISIBLE : View.GONE); mLevelView.setImageLevel(mLevel); //设置透明度可以调整充电body的颜色 if (mCharging) { mLevelView.setColorFilter(mNonAdaptedColor); mLevelView.setAlpha(0.6f); } else { if (isLowLevel()) { mLevelView.clearColorFilter(); mLevelView.setAlpha(1.0f); } else { mLevelView.setColorFilter(mNonAdaptedColor); if (showInsidePercent) { mLevelView.setAlpha(0.3f); } else { mLevelView.setAlpha(1.0f); } } } } private boolean isLowLevel() { return mLevel


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3