summaryrefslogtreecommitdiff
path: root/library/main/src/com/android/setupwizardlib/view/StickyHeaderListView.java
diff options
context:
space:
mode:
Diffstat (limited to 'library/main/src/com/android/setupwizardlib/view/StickyHeaderListView.java')
-rw-r--r--library/main/src/com/android/setupwizardlib/view/StickyHeaderListView.java215
1 files changed, 109 insertions, 106 deletions
diff --git a/library/main/src/com/android/setupwizardlib/view/StickyHeaderListView.java b/library/main/src/com/android/setupwizardlib/view/StickyHeaderListView.java
index 58274f6..c226f29 100644
--- a/library/main/src/com/android/setupwizardlib/view/StickyHeaderListView.java
+++ b/library/main/src/com/android/setupwizardlib/view/StickyHeaderListView.java
@@ -29,7 +29,6 @@ import android.view.View;
import android.view.WindowInsets;
import android.view.accessibility.AccessibilityEvent;
import android.widget.ListView;
-
import com.android.setupwizardlib.R;
/**
@@ -39,125 +38,129 @@ import com.android.setupwizardlib.R;
* when the sticky element hits the top of the view.
*
* <p>There are a few things to note:
+ *
* <ol>
* <li>The two supported scenarios are StickyHeaderListView -> Header (stickyContainer) -> sticky,
- * and StickyHeaderListView -> Header (sticky). The arrow (->) represents parent/child
- * relationship and must be immediate child.
+ * and StickyHeaderListView -> Header (sticky). The arrow (->) represents parent/child
+ * relationship and must be immediate child.
* <li>The view does not work well with padding. b/16190933
* <li>If fitsSystemWindows is true, then this will offset the sticking position by the height of
- * the system decorations at the top of the screen.
+ * the system decorations at the top of the screen.
* </ol>
*
* @see StickyHeaderScrollView
*/
public class StickyHeaderListView extends ListView {
- private View mSticky;
- private View mStickyContainer;
- private int mStatusBarInset = 0;
- private RectF mStickyRect = new RectF();
-
- public StickyHeaderListView(Context context) {
- super(context);
- init(null, android.R.attr.listViewStyle);
+ private View sticky;
+ private View stickyContainer;
+ private int statusBarInset = 0;
+ private final RectF stickyRect = new RectF();
+
+ public StickyHeaderListView(Context context) {
+ super(context);
+ init(null, android.R.attr.listViewStyle);
+ }
+
+ public StickyHeaderListView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(attrs, android.R.attr.listViewStyle);
+ }
+
+ public StickyHeaderListView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init(attrs, defStyleAttr);
+ }
+
+ private void init(AttributeSet attrs, int defStyleAttr) {
+ final TypedArray a =
+ getContext()
+ .obtainStyledAttributes(attrs, R.styleable.SuwStickyHeaderListView, defStyleAttr, 0);
+ int headerResId = a.getResourceId(R.styleable.SuwStickyHeaderListView_suwHeader, 0);
+ if (headerResId != 0) {
+ LayoutInflater inflater = LayoutInflater.from(getContext());
+ View header = inflater.inflate(headerResId, this, false);
+ addHeaderView(header, null, false);
}
-
- public StickyHeaderListView(Context context, AttributeSet attrs) {
- super(context, attrs);
- init(attrs, android.R.attr.listViewStyle);
+ a.recycle();
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ super.onLayout(changed, l, t, r, b);
+ if (sticky == null) {
+ updateStickyView();
}
-
- public StickyHeaderListView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- init(attrs, defStyleAttr);
+ }
+
+ public void updateStickyView() {
+ sticky = findViewWithTag("sticky");
+ stickyContainer = findViewWithTag("stickyContainer");
+ }
+
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ if (stickyRect.contains(ev.getX(), ev.getY())) {
+ ev.offsetLocation(-stickyRect.left, -stickyRect.top);
+ return stickyContainer.dispatchTouchEvent(ev);
+ } else {
+ return super.dispatchTouchEvent(ev);
}
-
- private void init(AttributeSet attrs, int defStyleAttr) {
- final TypedArray a = getContext().obtainStyledAttributes(attrs,
- R.styleable.SuwStickyHeaderListView, defStyleAttr, 0);
- int headerResId = a.getResourceId(R.styleable.SuwStickyHeaderListView_suwHeader, 0);
- if (headerResId != 0) {
- LayoutInflater inflater = LayoutInflater.from(getContext());
- View header = inflater.inflate(headerResId, this, false);
- addHeaderView(header, null, false);
- }
- a.recycle();
- }
-
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- super.onLayout(changed, l, t, r, b);
- if (mSticky == null) {
- updateStickyView();
- }
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ super.draw(canvas);
+ if (sticky != null) {
+ final int saveCount = canvas.save();
+ // The view to draw when sticking to the top
+ final View drawTarget = stickyContainer != null ? stickyContainer : sticky;
+ // The offset to draw the view at when sticky
+ final int drawOffset = stickyContainer != null ? sticky.getTop() : 0;
+ // Position of the draw target, relative to the outside of the scrollView
+ final int drawTop = drawTarget.getTop();
+ if (drawTop + drawOffset < statusBarInset || !drawTarget.isShown()) {
+ // ListView does not translate the canvas, so we can simply draw at the top
+ stickyRect.set(
+ 0,
+ -drawOffset + statusBarInset,
+ drawTarget.getWidth(),
+ drawTarget.getHeight() - drawOffset + statusBarInset);
+ canvas.translate(0, stickyRect.top);
+ canvas.clipRect(0, 0, drawTarget.getWidth(), drawTarget.getHeight());
+ drawTarget.draw(canvas);
+ } else {
+ stickyRect.setEmpty();
+ }
+ canvas.restoreToCount(saveCount);
}
-
- public void updateStickyView() {
- mSticky = findViewWithTag("sticky");
- mStickyContainer = findViewWithTag("stickyContainer");
+ }
+
+ @Override
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+ if (getFitsSystemWindows()) {
+ statusBarInset = insets.getSystemWindowInsetTop();
+ insets.replaceSystemWindowInsets(
+ insets.getSystemWindowInsetLeft(),
+ 0, /* top */
+ insets.getSystemWindowInsetRight(),
+ insets.getSystemWindowInsetBottom());
}
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- if (mStickyRect.contains(ev.getX(), ev.getY())) {
- ev.offsetLocation(-mStickyRect.left, -mStickyRect.top);
- return mStickyContainer.dispatchTouchEvent(ev);
- } else {
- return super.dispatchTouchEvent(ev);
- }
- }
-
- @Override
- public void draw(Canvas canvas) {
- super.draw(canvas);
- if (mSticky != null) {
- final int saveCount = canvas.save();
- // The view to draw when sticking to the top
- final View drawTarget = mStickyContainer != null ? mStickyContainer : mSticky;
- // The offset to draw the view at when sticky
- final int drawOffset = mStickyContainer != null ? mSticky.getTop() : 0;
- // Position of the draw target, relative to the outside of the scrollView
- final int drawTop = drawTarget.getTop();
- if (drawTop + drawOffset < mStatusBarInset || !drawTarget.isShown()) {
- // ListView does not translate the canvas, so we can simply draw at the top
- mStickyRect.set(0, -drawOffset + mStatusBarInset, drawTarget.getWidth(),
- drawTarget.getHeight() - drawOffset + mStatusBarInset);
- canvas.translate(0, mStickyRect.top);
- canvas.clipRect(0, 0, drawTarget.getWidth(), drawTarget.getHeight());
- drawTarget.draw(canvas);
- } else {
- mStickyRect.setEmpty();
- }
- canvas.restoreToCount(saveCount);
- }
- }
-
- @Override
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- public WindowInsets onApplyWindowInsets(WindowInsets insets) {
- if (getFitsSystemWindows()) {
- mStatusBarInset = insets.getSystemWindowInsetTop();
- insets.replaceSystemWindowInsets(
- insets.getSystemWindowInsetLeft(),
- 0, /* top */
- insets.getSystemWindowInsetRight(),
- insets.getSystemWindowInsetBottom()
- );
- }
- return insets;
- }
-
- @Override
- public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
- super.onInitializeAccessibilityEvent(event);
-
- // Decoration-only headers should not count as an item for accessibility, adjust the
- // accessibility event to account for that.
- final int numberOfHeaders = mSticky != null ? 1 : 0;
- event.setItemCount(event.getItemCount() - numberOfHeaders);
- event.setFromIndex(Math.max(event.getFromIndex() - numberOfHeaders, 0));
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
- event.setToIndex(Math.max(event.getToIndex() - numberOfHeaders, 0));
- }
+ return insets;
+ }
+
+ @Override
+ public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+ super.onInitializeAccessibilityEvent(event);
+
+ // Decoration-only headers should not count as an item for accessibility, adjust the
+ // accessibility event to account for that.
+ final int numberOfHeaders = sticky != null ? 1 : 0;
+ event.setItemCount(event.getItemCount() - numberOfHeaders);
+ event.setFromIndex(Math.max(event.getFromIndex() - numberOfHeaders, 0));
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+ event.setToIndex(Math.max(event.getToIndex() - numberOfHeaders, 0));
}
+ }
}