// Intimately tied to the design of res/layout/signal_cluster_view.xml
public class SignalClusterView extends LinearLayout implements NetworkControllerImpl.SignalCallback,
SecurityController.SecurityControllerCallback, Tunable, DarkReceiver {
// Vpn wifi 飞行模式图标
private final NetworkController mNetworkController;
private final SecurityController mSecurityController;
//省略
private ArrayList<PhoneState> mPhoneStates = new ArrayList<PhoneState>();
//省略
ViewGroup mEthernetGroup, mWifiGroup;
ImageView mVpn, mEthernet, mWifi, mAirplane, mEthernetDark, mWifiDark;
ImageView mWifiActivityIn, mWifiActivityOut;
View mWifiAirplaneSpacer, mWifiSignalSpacer;
LinearLayout mMobileSignalGroup;
路径是 /frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
可以看出来是LineLayout的子类 ,里面重写了onLayout方法,onLayout调用了super.onLayout方法和applyIconTint()方法.
applyIconTint()方法里面就是对view的设置
private void applyIconTint() {
setTint(mVpn, DarkIconDispatcher.getTint(mTintArea, mVpn, mIconTint));
//省略
applyDarkIntensity(
DarkIconDispatcher.getDarkIntensity(mTintArea, mEthernet, mDarkIntensity),
mEthernet, mEthernetDark);
for (int i = 0; i < mPhoneStates.size(); i++) {
mPhoneStates.get(i).setIconTint(mIconTint, mDarkIntensity, mTintArea);
}
}
//设置透明度
private void applyDarkIntensity(float darkIntensity, View lightIcon, View darkIcon) {
lightIcon.setAlpha(1 - darkIntensity);
darkIcon.setAlpha(darkIntensity);
}
// 为图片设置渲染颜色.
private void setTint(ImageView v, int tint) {
v.setImageTintList(ColorStateList.valueOf(tint));
}
view的初始化:
@Override
protected void onFinishInflate() {
super.onFinishInflate();
//findview组件
mVpn = findViewById(R.id.vpn);
mEthernetGroup = findViewById(R.id.ethernet_combo);
mEthernet = findViewById(R.id.ethernet);
//省略
maybeScaleVpnAndNoSimsIcons();
}
/**
* Extracts the icon off of the VPN and no sims views and maybe scale them by
* {@link #mIconScaleFactor}. Note that the other icons are not scaled here because
* they are dynamic. As such, they need to be scaled each time the icon changes in {@link #apply()}.
*/
private void maybeScaleVpnAndNoSimsIcons() {
if (mIconScaleFactor == 1.f) {
return;
}
mVpn.setImageDrawable(new ScalingDrawableWrapper(mVpn.getDrawable(), mIconScaleFactor));
}
maybeScaleVpnAndNoSimsIcons()上面的注释是说: 从vpn中提取图标,不显示sims视图,并按比例缩放 {@link miconscalefactor}。请注意,其他图标在此不缩放,因为它们是动态的因此,每次在{@link apply()中更改图标时,都需要缩放它们。
apply() 是一个私有方法,上面有一个注释 // Run after each indicator change. 也就是 每次指标变化后运行,里面内容就是对一些View的设置,那么调用apply()的地方有
@Override
public void setIsAirplaneMode(IconState icon) {//飞行模式
mIsAirplaneMode = icon.visible && !mBlockAirplane;
mAirplaneIconId = icon.icon;
mAirplaneContentDescription = icon.contentDescription;
apply();
}
@Override
public void onRtlPropertiesChanged(int layoutDirection) {
//省略
}
@Override
protected void onAttachedToWindow() {//连接到window
super.onAttachedToWindow();
mVpnVisible = mSecurityController.isVpnEnabled();
mVpnIconId = currentVpnIconId(mSecurityController.isVpnBranded());
for (PhoneState state : mPhoneStates) {
if (state.mMobileGroup.getParent() == null) {
mMobileSignalGroup.addView(state.mMobileGroup);
}
}
int endPadding = mMobileSignalGroup.getChildCount() > 0 ? mMobileSignalGroupEndPadding : 0;
mMobileSignalGroup.setPaddingRelative(0, 0, endPadding, 0);
Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
apply();
applyIconTint();
mNetworkController.addCallback(this);
mSecurityController.addCallback(this);
}
@Override
public void setWifiIndicators(...) {//wifi
}
@Override
public void setMobileDataIndicators(...); //信号等等数据
}
@Override
public void setEthernetIndicators(IconState state) {//设置以太网指示器
}
回到applyIconTint()方法,mPhoneStates是PhoneState的集合,源码里面PhoneState是内部类,
public PhoneState(int subId, Context context) {
ViewGroup root = (ViewGroup) LayoutInflater.from(context)
.inflate(R.layout.mobile_signal_group, null);
setViews(root);
mSubId = subId;
}
public void setViews(ViewGroup root) {
mMobileGroup = root;
mMobile = root.findViewById(R.id.mobile_signal);
mMobileType = root.findViewById(R.id.mobile_type);
mMobileRoaming = root.findViewById(R.id.mobile_roaming);
mMobileRoamingSpace = root.findViewById(R.id.mobile_roaming_space);
mMobileActivityIn = root.findViewById(R.id.mobile_in);
mMobileActivityOut = root.findViewById(R.id.mobile_out);
mMobileSignalDrawable = new SignalDrawable(mMobile.getContext());
mMobile.setImageDrawable(mMobileSignalDrawable);
}