Android 原生设计中在锁屏界面会显示运营商名称,用户界面中,大概是基于 icon 数量长度显示考虑,对运营商名称不作显示。但是国内基本都加上运营商名称。对图标显示长度优化基本都是:缩小运营商字体、限制字数长度、信号图标压缩上下叠加等。
SIM卡的 icon 对应的文件是 StatusBarMobileView,默认包含信号格、漫游、网络制式、上下行等图标。只需要在默认基础上,添加运营商名称View。

在信号格后面增加运营商名称,System中对文字图标显示自定义 AutoMarqueeTextView 类(主要增加跑马灯和省略号的样式自动切换)处理,我们使用 AutoMarqueeTextView 显示名称即可。
- //frameworks/base/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml
-
- <FrameLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical">
- <com.android.systemui.statusbar.AnimatedImageView
- android:id="@+id/mobile_signal"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- systemui:hasOverlappingRendering="false"
- />
- <ImageView
- android:id="@+id/mobile_roaming"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/stat_sys_roaming"
- android:contentDescription="@string/data_connection_roaming"
- android:visibility="gone" />
- FrameLayout>
- <com.android.systemui.util.AutoMarqueeTextView
- android:id="@+id/qs_carrier_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:textAppearance="@style/TextAppearance.QS.Status"
- android:textDirection="locale"
- android:textSize="8dp"
- android:marqueeRepeatLimit="marquee_forever"
- android:singleLine="true"
- android:maxEms="4"/>
然后调整好文字大小和长度适配。
默认图标都是从左到右排序的,这样会导致整体icon太长,状态栏放不下,从而导致icon被收到省略号中无法显示。
- //frameworks/base/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml
-
- <com.android.keyguard.AlphaOptimizedLinearLayout
- android:id="@+id/mobile_group"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:gravity="center_vertical"
- android:orientation="horizontal" >
- <ImageView
- android:id="@+id/mobile_volte"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:visibility="gone"
- android:paddingEnd="2dp"/>
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:orientation="vertical">
- <FrameLayout
- android:layout_height="10dp"
- android:layout_width="10dp">
- <ImageView
- android:id="@+id/mobile_type"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_marginTop="1dp"
- android:visibility="gone" />
- FrameLayout>
- <FrameLayout
- android:id="@+id/inout_container"
- android:layout_height="10dp"
- android:layout_width="10dp"
- android:layout_gravity="center_horizontal">
- <ImageView
- android:id="@+id/mobile_in"
- android:layout_height="10dp"
- android:layout_width="10dp"
- android:src="@drawable/ic_activity_down"
- android:visibility="gone"
- />
- <ImageView
- android:id="@+id/mobile_out"
- android:layout_height="10dp"
- android:layout_width="10dp"
- android:src="@drawable/ic_activity_up"
- android:visibility="gone"
- />
- FrameLayout>
- LinearLayout>
- <Space
- android:id="@+id/mobile_roaming_space"
- android:layout_height="match_parent"
- android:layout_width="0dp"
- android:visibility="gone"
- />
把子view直接的space都设置为0,再把4g图标和上下行图标缩小放到一列中。
获取运营商名称接口常用有两种
SubscriptionInfo.getCarrierName()
SubscriptionInfo.getDisplayName()
区别在第一种显示的内容更多,类似:CHN-CT中国电信。这里一般只想显示中国电信,使用第二个方法就行。
- //frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
-
- private DualToneHandler mDualToneHandler;
-
- private ImageView mVolte;
- + private TextView mCarrierText;
- + private SubscriptionManager mSubscriptionManager;
-
- public static StatusBarMobileView fromContext(Context context, String slot) {
- LayoutInflater inflater = LayoutInflater.from(context);
- @@ -80,6 +85,7 @@
-
- public StatusBarMobileView(Context context, AttributeSet attrs) {
- super(context, attrs);
- + mSubscriptionManager = SubscriptionManager.from(context);
- }
-
- public StatusBarMobileView(Context context, AttributeSet attrs, int defStyleAttr) {
- @@ -113,6 +119,9 @@
- mOut = findViewById(R.id.mobile_out);
- mInoutContainer = findViewById(R.id.inout_container);
- mVolte = findViewById(R.id.mobile_volte);
- + mCarrierText = findViewById(R.id.qs_carrier_text);
- + mCarrierText.setText("");
-
- mMobileDrawable = new SignalDrawable(getContext());
- mMobile.setImageDrawable(mMobileDrawable);
- @@ -159,6 +168,11 @@
- setVisibility(View.INVISIBLE);
- requestLayout();
- }
- + SubscriptionInfo subscriptionInfo = mSubscriptionManager.getActiveSubscriptionInfo(mState.subId);
- + if (subscriptionInfo != null) {
- + CharSequence cName = subscriptionInfo.getDisplayName();
- + mCarrierText.setText(cName);
- + }
- }
-
- private void initViewState() {
- @@ -194,6 +208,11 @@
- }else {
- mVolte.setVisibility(View.GONE);
- }
- + SubscriptionInfo subscriptionInfo = mSubscriptionManager.getActiveSubscriptionInfo(mState.subId);
- + if (subscriptionInfo != null) {
- + CharSequence cName = subscriptionInfo.getDisplayName();
- + mCarrierText.setText(cName);
- + }
- }
StatusBarMobileView 中动态获取刷新运营商名称。针对状态栏中icon颜色,设计是有要求的,需要根据背景的变化进行适应。在浅色背景显示深色,深色背景显示浅色,有一定对比度才行。
- //frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
-
- private boolean updateState(MobileIconState state) {
- @@ -258,6 +277,8 @@
- mMobileRoaming.setImageTintList(color);
- mDotView.setDecorColor(tint);
- mDotView.setIconColor(tint, false);
- + int foreground = mDualToneHandler.getSingleColor(intensity);
- + mCarrierText.setTextColor(foreground);
- }
-
- @Override
- @@ -288,6 +309,7 @@
- @Override
- public void setDecorColor(int color) {
- mDotView.setDecorColor(color);
- + mCarrierText.setTextColor(color);
- }
原生设计会在锁屏界面只显示SIM卡运营商。状态栏增加自定义的显示后,锁屏界面可以删除。对应 View
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
中的 mCarrierLabel ,设置隐藏即可。