+			}
153
+			mDivider.draw(canvas);
154
+		}
155
+	}
156
+}

+ 196 - 0
views/src/main/java/com/android/views/stickylistheaders/WrapperViewList.java

@@ -0,0 +1,196 @@
1
+package com.android.views.stickylistheaders;
2
+
3
+import android.content.Context;
4
+import android.graphics.Canvas;
5
+import android.graphics.Rect;
6
+import android.os.Build;
7
+import android.view.View;
8
+import android.widget.AbsListView;
9
+import android.widget.ListView;
10
+
11
+import java.lang.reflect.Field;
12
+import java.util.ArrayList;
13
+import java.util.List;
14
+
15
+class WrapperViewList extends ListView {
16
+
17
+	interface LifeCycleListener {
18
+		void onDispatchDrawOccurred(Canvas canvas);
19
+	}
20
+
21
+	private LifeCycleListener mLifeCycleListener;
22
+	private List<View> mFooterViews;
23
+	private int mTopClippingLength;
24
+	private Rect mSelectorRect = new Rect();// for if reflection fails
25
+	private Field mSelectorPositionField;
26
+	private boolean mClippingToPadding = true;
27
+    private boolean mBlockLayoutChildren = false;
28
+
29
+	public WrapperViewList(Context context) {
30
+		super(context);
31
+
32
+		// Use reflection to be able to change the size/position of the list
33
+		// selector so it does not come under/over the header
34
+		try {
35
+			Field selectorRectField = AbsListView.class.getDeclaredField("mSelectorRect");
36
+			selectorRectField.setAccessible(true);
37
+			mSelectorRect = (Rect) selectorRectField.get(this);
38
+
39
+			if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
40
+				mSelectorPositionField = AbsListView.class.getDeclaredField("mSelectorPosition");
41
+				mSelectorPositionField.setAccessible(true);
42
+			}
43
+		} catch (NoSuchFieldException e) {
44
+			e.printStackTrace();
45
+		} catch (IllegalArgumentException e) {
46
+			e.printStackTrace();
47
+		} catch (IllegalAccessException e) {
48
+			e.printStackTrace();
49
+		}
50
+	}
51
+
52
+	@Override
53
+	public boolean performItemClick(View view, int position, long id) {
54
+		if (view instanceof WrapperView) {
55
+			view = ((WrapperView) view).mItem;
56
+		}
57
+		return super.performItemClick(view, position, id);
58
+	}
59
+
60
+	private void positionSelectorRect() {
61
+		if (!mSelectorRect.isEmpty()) {
62
+			int selectorPosition = getSelectorPosition();
63
+			if (selectorPosition >= 0) {
64
+				int firstVisibleItem = getFixedFirstVisibleItem();
65
+				View v = getChildAt(selectorPosition - firstVisibleItem);
66
+				if (v instanceof WrapperView) {
67
+					WrapperView wrapper = ((WrapperView) v);
68
+					mSelectorRect.top = wrapper.getTop() + wrapper.mItemTop;
69
+				}
70
+			}
71
+		}
72
+	}
73
+
74
+	private int getSelectorPosition() {
75
+		if (mSelectorPositionField == null) { // not all supported andorid
76
+			// version have this variable
77
+			for (int i = 0; i < getChildCount(); i++) {
78
+				if (getChildAt(i).getBottom() == mSelectorRect.bottom) {
79
+					return i + getFixedFirstVisibleItem();
80
+				}
81
+			}
82
+		} else {
83
+			try {
84
+				return mSelectorPositionField.getInt(this);
85
+			} catch (IllegalArgumentException e) {
86
+				e.printStackTrace();
87
+			} catch (IllegalAccessException e) {
88
+				e.printStackTrace();
89
+			}
90
+		}
91
+		return -1;
92
+	}
93
+
94
+	@Override
95
+	protected void dispatchDraw(Canvas canvas) {
96
+		positionSelectorRect();
97
+		if (mTopClippingLength != 0) {
98
+			canvas.save();
99
+			Rect clipping = canvas.getClipBounds();
100
+			clipping.top = mTopClippingLength;
101
+			canvas.clipRect(clipping);
102
+			super.dispatchDraw(canvas);
103
+			canvas.restore();
104
+		} else {
105
+			super.dispatchDraw(canvas);
106
+		}
107
+		mLifeCycleListener.onDispatchDrawOccurred(canvas);
108
+	}
109
+
110
+	void setLifeCycleListener(LifeCycleListener lifeCycleListener) {
111
+		mLifeCycleListener = lifeCycleListener;
112
+	}
113
+
114
+	@Override
115
+	public void addFooterView(View v) {
116
+		super.addFooterView(v);
117
+		addInternalFooterView(v);
118
+	}
119
+
120
+	@Override
121
+	public void addFooterView(View v, Object data, boolean isSelectable) {
122
+		super.addFooterView(v, data, isSelectable);
123
+		addInternalFooterView(v);
124
+	}
125
+
126
+	private void addInternalFooterView(View v) {
127
+		if (mFooterViews == null) {
128
+			mFooterViews = new ArrayList<View>();
129
+		}
130
+		mFooterViews.add(v);
131
+	}
132
+
133
+	@Override
134
+	public boolean removeFooterView(View v) {
135
+		if (super.removeFooterView(v)) {
136
+			mFooterViews.remove(v);
137
+			return true;
138
+		}
139
+		return false;
140
+	}
141
+
142
+	boolean containsFooterView(View v) {
143
+		if (mFooterViews == null) {
144
+			return false;
145
+		}
146
+		return mFooterViews.contains(v);
147
+	}
148
+
149
+	void setTopClippingLength(int topClipping) {
150
+		mTopClippingLength = topClipping;
151
+	}
152
+
153
+	int getFixedFirstVisibleItem() {
154
+		int firstVisibleItem = getFirstVisiblePosition();
155
+		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
156
+			return firstVisibleItem;
157
+		}
158
+
159
+		// first getFirstVisiblePosition() reports items
160
+		// outside the view sometimes on old versions of android
161
+		for (int i = 0; i < getChildCount(); i++) {
162
+			if (getChildAt(i).getBottom() >= 0) {
163
+				firstVisibleItem += i;
164
+				break;
165
+			}
166
+		}
167
+
168
+		// work around to fix bug with firstVisibleItem being to high
169
+		// because list view does not take clipToPadding=false into account
170
+		// on old versions of android
171
+		if (!mClippingToPadding && getPaddingTop() > 0 && firstVisibleItem > 0) {
172
+			if (getChildAt(0).getTop() > 0) {
173
+				firstVisibleItem -= 1;
174
+			}
175
+		}
176
+
177
+		return firstVisibleItem;
178
+	}
179
+
180
+	@Override
181
+	public void setClipToPadding(boolean clipToPadding) {
182
+		mClippingToPadding = clipToPadding;
183
+		super.setClipToPadding(clipToPadding);
184
+	}
185
+
186
+    public void setBlockLayoutChildren(boolean block) {
187
+        mBlockLayoutChildren = block;
188
+    }
189
+
190
+    @Override
191
+    protected void layoutChildren() {
192
+        if (!mBlockLayoutChildren) {
193
+            super.layoutChildren();
194
+        }
195
+    }
196
+}

+ 34 - 0
views/src/main/res/values/attrs.xml

@@ -87,4 +87,38 @@
87 87
     </declare-styleable>
88 88
 
89 89
     <attr name="SwipeBackLayoutStyle" format="reference"/>
90
+
91
+    <declare-styleable name="StickyListHeadersListView">
92
+        <attr name="stickyListHeadersListViewStyle" format="reference"/>
93
+
94
+        <!-- View attributes -->
95
+        <attr name="android:clipToPadding" />
96
+        <attr name="android:scrollbars" />
97
+        <attr name="android:overScrollMode" />
98
+        <attr name="android:padding" />
99
+        <attr name="android:paddingLeft" />
100
+        <attr name="android:paddingTop" />
101
+        <attr name="android:paddingRight" />
102
+        <attr name="android:paddingBottom" />
103
+
104
+        <!-- ListView attributes -->
105
+        <attr name="android:fadingEdgeLength" />
106
+        <attr name="android:requiresFadingEdge" />
107
+        <attr name="android:cacheColorHint" />
108
+        <attr name="android:choiceMode" />
109
+        <attr name="android:drawSelectorOnTop" />
110
+        <attr name="android:fastScrollEnabled" />
111
+        <attr name="android:fastScrollAlwaysVisible" />
112
+        <attr name="android:listSelector" />
113
+        <attr name="android:scrollingCache" />
114
+        <attr name="android:scrollbarStyle" />
115
+        <attr name="android:divider" />
116
+        <attr name="android:dividerHeight" />
117
+        <attr name="android:transcriptMode" />
118
+        <attr name="android:stackFromBottom" />
119
+
120
+        <!-- StickyListHeaders attributes -->
121
+        <attr name="hasStickyHeaders" format="boolean" />
122
+        <attr name="isDrawingListUnderStickyHeader" format="boolean" />
123
+    </declare-styleable>
90 124
 </resources>

kodo - Gogs: Go Git Service

Nav apraksta

Brightcells: 55b9749bbe Admin Site Register 7 gadi atpakaļ
..
migrations 6e7c94e744 MchInfoDecryptLogInfo 7 gadi atpakaļ
__init__.py 5fdb5b42fd Logfile Upload 8 gadi atpakaļ
admin.py 55b9749bbe Admin Site Register 7 gadi atpakaļ
apps.py 5fdb5b42fd Logfile Upload 8 gadi atpakaļ
models.py 6e7c94e744 MchInfoDecryptLogInfo 7 gadi atpakaļ
tests.py 5fdb5b42fd Logfile Upload 8 gadi atpakaļ
views.py 5fdb5b42fd Logfile Upload 8 gadi atpakaļ