|
30 | 30 |
|
31 | 31 | public class IconMerger extends LinearLayout { |
32 | 32 | private static final String TAG = "IconMerger"; |
| 33 | + private static final boolean DEBUG = false; |
33 | 34 |
|
34 | 35 | private int mIconSize; |
35 | | - private StatusBarIconView mMoreView; |
36 | | - private StatusBarIcon mMoreIcon = new StatusBarIcon(null, R.drawable.stat_notify_more, 0, 0, |
37 | | - null); |
| 36 | + private View mMoreView; |
38 | 37 |
|
39 | 38 | public IconMerger(Context context, AttributeSet attrs) { |
40 | 39 | super(context, attrs); |
41 | 40 |
|
42 | 41 | mIconSize = context.getResources().getDimensionPixelSize( |
43 | | - com.android.internal.R.dimen.status_bar_icon_size); |
| 42 | + R.dimen.status_bar_icon_size); |
44 | 43 |
|
45 | | - mMoreView = new StatusBarIconView(context, "more", null); |
46 | | - mMoreView.set(mMoreIcon); |
47 | | - super.addView(mMoreView, 0, new LinearLayout.LayoutParams(mIconSize, mIconSize)); |
| 44 | + if (DEBUG) { |
| 45 | + setBackgroundColor(0x800099FF); |
| 46 | + } |
48 | 47 | } |
49 | 48 |
|
50 | | - public void addView(StatusBarIconView v, int index, LinearLayout.LayoutParams p) { |
51 | | - super.addView(v, index+1, p); |
| 49 | + public void setOverflowIndicator(View v) { |
| 50 | + mMoreView = v; |
52 | 51 | } |
53 | 52 |
|
54 | | - public void addView(StatusBarIconView v, int index) { |
55 | | - super.addView(v, index+1, new LinearLayout.LayoutParams(mIconSize, mIconSize)); |
| 53 | + @Override |
| 54 | + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { |
| 55 | + super.onMeasure(widthMeasureSpec, heightMeasureSpec); |
| 56 | + // we need to constrain this to an integral multiple of our children |
| 57 | + int width = getMeasuredWidth(); |
| 58 | + setMeasuredDimension(width - (width % mIconSize), getMeasuredHeight()); |
56 | 59 | } |
57 | 60 |
|
58 | 61 | @Override |
59 | 62 | protected void onLayout(boolean changed, int l, int t, int r, int b) { |
60 | 63 | super.onLayout(changed, l, t, r, b); |
| 64 | + checkOverflow(r - l); |
| 65 | + } |
61 | 66 |
|
62 | | - final int maxWidth = r - l; |
63 | | - final int N = getChildCount(); |
64 | | - int i; |
65 | | - |
66 | | - // get the rightmost one, and see if we even need to do anything |
67 | | - int fitRight = -1; |
68 | | - for (i=N-1; i>=0; i--) { |
69 | | - final View child = getChildAt(i); |
70 | | - if (child.getVisibility() != GONE) { |
71 | | - fitRight = child.getRight(); |
72 | | - break; |
73 | | - } |
74 | | - } |
75 | | - |
76 | | - // find the first visible one that isn't the more icon |
77 | | - final StatusBarIconView moreView = mMoreView; |
78 | | - int fitLeft = -1; |
79 | | - int startIndex = -1; |
80 | | - for (i=0; i<N; i++) { |
81 | | - final View child = getChildAt(i); |
82 | | - if (child == moreView) { |
83 | | - startIndex = i+1; |
84 | | - } |
85 | | - else if (child.getVisibility() != GONE) { |
86 | | - fitLeft = child.getLeft(); |
87 | | - break; |
88 | | - } |
89 | | - } |
| 67 | + private void checkOverflow(int width) { |
| 68 | + if (mMoreView == null) return; |
90 | 69 |
|
91 | | - if (moreView == null || startIndex < 0) { |
92 | | - return; |
93 | | - /* |
94 | | - throw new RuntimeException("Status Bar / IconMerger moreView == " + moreView |
95 | | - + " startIndex=" + startIndex); |
96 | | - */ |
97 | | - } |
98 | | - |
99 | | - // if it fits without the more icon, then hide the more icon and update fitLeft |
100 | | - // so everything gets pushed left |
101 | | - int adjust = 0; |
102 | | - if (fitRight - fitLeft <= maxWidth) { |
103 | | - adjust = fitLeft - moreView.getLeft(); |
104 | | - fitLeft -= adjust; |
105 | | - fitRight -= adjust; |
106 | | - moreView.layout(0, moreView.getTop(), 0, moreView.getBottom()); |
| 70 | + final int N = getChildCount(); |
| 71 | + int visibleChildren = 0; |
| 72 | + for (int i=0; i<N; i++) { |
| 73 | + if (getChildAt(i).getVisibility() != GONE) visibleChildren++; |
107 | 74 | } |
108 | | - int extra = fitRight - r; |
109 | | - int shift = -1; |
110 | | - |
111 | | - int breakingPoint = fitLeft + extra + adjust; |
112 | | - int number = 0; |
113 | | - for (i=startIndex; i<N; i++) { |
114 | | - final StatusBarIconView child = (StatusBarIconView)getChildAt(i); |
115 | | - if (child.getVisibility() != GONE) { |
116 | | - int childLeft = child.getLeft(); |
117 | | - int childRight = child.getRight(); |
118 | | - if (childLeft < breakingPoint) { |
119 | | - // hide this one |
120 | | - child.layout(0, child.getTop(), 0, child.getBottom()); |
121 | | - int n = child.getStatusBarIcon().number; |
122 | | - if (n == 0) { |
123 | | - number += 1; |
124 | | - } else if (n > 0) { |
125 | | - number += n; |
126 | | - } |
127 | | - } else { |
128 | | - // decide how much to shift by |
129 | | - if (shift < 0) { |
130 | | - shift = childLeft - fitLeft; |
131 | | - } |
132 | | - // shift this left by shift |
133 | | - child.layout(childLeft-shift, child.getTop(), |
134 | | - childRight-shift, child.getBottom()); |
| 75 | + final boolean overflowShown = (mMoreView.getVisibility() == View.VISIBLE); |
| 76 | + // let's assume we have one more slot if the more icon is already showing |
| 77 | + if (overflowShown) visibleChildren --; |
| 78 | + final boolean moreRequired = visibleChildren * mIconSize > width; |
| 79 | + if (moreRequired != overflowShown) { |
| 80 | + post(new Runnable() { |
| 81 | + @Override |
| 82 | + public void run() { |
| 83 | + mMoreView.setVisibility(moreRequired ? View.VISIBLE : View.GONE); |
135 | 84 | } |
136 | | - } |
| 85 | + }); |
137 | 86 | } |
138 | | - |
139 | | - mMoreIcon.number = number; |
140 | | - mMoreView.set(mMoreIcon); |
141 | 87 | } |
142 | 88 | } |
0 commit comments