1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.qs; 18 19 import android.animation.ValueAnimator; 20 import android.content.Context; 21 import android.view.View; 22 import android.widget.FrameLayout; 23 import android.widget.ImageView; 24 25 import com.android.systemui.R; 26 import com.android.systemui.plugins.qs.QSTile.SignalState; 27 import com.android.systemui.plugins.qs.QSTile.State; 28 import com.android.systemui.qs.tileimpl.QSIconViewImpl; 29 import com.android.systemui.qs.tileimpl.SlashImageView; 30 31 /** View that represents a custom quick settings tile for displaying signal info (wifi/cell). **/ 32 public class SignalTileView extends QSIconViewImpl { 33 private static final long DEFAULT_DURATION = new ValueAnimator().getDuration(); 34 private static final long SHORT_DURATION = DEFAULT_DURATION / 3; 35 36 protected FrameLayout mIconFrame; 37 protected ImageView mSignal; 38 private ImageView mOverlay; 39 private ImageView mIn; 40 private ImageView mOut; 41 42 private int mWideOverlayIconStartPadding; 43 private int mSignalIndicatorToIconFrameSpacing; 44 45 public SignalTileView(Context context) { 46 super(context); 47 48 mIn = addTrafficView(R.drawable.ic_qs_signal_in); 49 mOut = addTrafficView(R.drawable.ic_qs_signal_out); 50 51 setClipChildren(false); 52 setClipToPadding(false); 53 54 mWideOverlayIconStartPadding = context.getResources().getDimensionPixelSize( 55 R.dimen.wide_type_icon_start_padding_qs); 56 mSignalIndicatorToIconFrameSpacing = context.getResources().getDimensionPixelSize( 57 R.dimen.signal_indicator_to_icon_frame_spacing); 58 } 59 60 private ImageView addTrafficView(int icon) { 61 final ImageView traffic = new ImageView(mContext); 62 traffic.setImageResource(icon); 63 traffic.setAlpha(0f); 64 addView(traffic); 65 return traffic; 66 } 67 68 @Override 69 protected View createIcon() { 70 mIconFrame = new FrameLayout(mContext); 71 mSignal = createSlashImageView(mContext); 72 mIconFrame.addView(mSignal); 73 mOverlay = new ImageView(mContext); 74 mIconFrame.addView(mOverlay, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 75 return mIconFrame; 76 } 77 78 protected SlashImageView createSlashImageView(Context context) { 79 return new SlashImageView(context); 80 } 81 82 @Override 83 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 84 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 85 int hs = MeasureSpec.makeMeasureSpec(mIconFrame.getMeasuredHeight(), MeasureSpec.EXACTLY); 86 int ws = MeasureSpec.makeMeasureSpec(mIconFrame.getMeasuredHeight(), MeasureSpec.AT_MOST); 87 mIn.measure(ws, hs); 88 mOut.measure(ws, hs); 89 } 90 91 @Override 92 protected void onLayout(boolean changed, int l, int t, int r, int b) { 93 super.onLayout(changed, l, t, r, b); 94 layoutIndicator(mIn); 95 layoutIndicator(mOut); 96 } 97 98 @Override 99 protected int getIconMeasureMode() { 100 return MeasureSpec.AT_MOST; 101 } 102 103 private void layoutIndicator(View indicator) { 104 boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; 105 int left, right; 106 if (isRtl) { 107 right = getLeft() - mSignalIndicatorToIconFrameSpacing; 108 left = right - indicator.getMeasuredWidth(); 109 } else { 110 left = getRight() + mSignalIndicatorToIconFrameSpacing; 111 right = left + indicator.getMeasuredWidth(); 112 } 113 indicator.layout( 114 left, 115 mIconFrame.getBottom() - indicator.getMeasuredHeight(), 116 right, 117 mIconFrame.getBottom()); 118 } 119 120 @Override 121 public void setIcon(State state, boolean allowAnimations) { 122 final SignalState s = (SignalState) state; 123 setIcon(mSignal, s, allowAnimations); 124 125 if (s.overlayIconId > 0) { 126 mOverlay.setVisibility(VISIBLE); 127 mOverlay.setImageResource(s.overlayIconId); 128 } else { 129 mOverlay.setVisibility(GONE); 130 } 131 if (s.overlayIconId > 0 && s.isOverlayIconWide) { 132 mSignal.setPaddingRelative(mWideOverlayIconStartPadding, 0, 0, 0); 133 } else { 134 mSignal.setPaddingRelative(0, 0, 0, 0); 135 } 136 final boolean shouldAnimate = allowAnimations && isShown(); 137 setVisibility(mIn, shouldAnimate, s.activityIn); 138 setVisibility(mOut, shouldAnimate, s.activityOut); 139 } 140 141 private void setVisibility(View view, boolean shown, boolean visible) { 142 final float newAlpha = shown && visible ? 1 : 0; 143 if (view.getAlpha() == newAlpha) return; 144 if (shown) { 145 view.animate() 146 .setDuration(visible ? SHORT_DURATION : DEFAULT_DURATION) 147 .alpha(newAlpha) 148 .start(); 149 } else { 150 view.setAlpha(newAlpha); 151 } 152 } 153 } 154