Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Left floating header #419

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,24 @@ You can call `expand` or `collapse` method to hide or show subitems.
You can also define a AnimationExecutor which implements `ExpandableStickyListHeadersListView.IAnimationExecutor`,
and put it into the ExpandableStickyListHeadersListView by `setAnimExecutor` method,if you want more fancy animation when hiding or showing subitems.

###Floating left headers support
Just like Cyberplus tablet, StickyListHeadersListView supports now floating left header.

<img src="https://github.com/LivioGama/StickyListHeaders/raw/master/cyberplus.png" width="640" />

To use it, in Java code :
```java
stickyList.setShowHeaderOnLeft(true);
```

You can also define a width for the header using styleable `headerWidth` or in the style this way :
```xml
<resources>
<style name="Theme.MyApp" parent="android:Theme.NoTitleBar">
<item name="headerWidth">100</item>
</style>
</resources>
```

Upgrading from 1.x versions
---------------------------
Expand Down
Binary file added cyberplus.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions library/res/values/attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
<attr name="android:transcriptMode" />
<attr name="android:stackFromBottom" />

<!-- Header attributes -->
<attr name="headerWidth" format="dimension" />

<!-- StickyListHeaders attributes -->
<attr name="hasStickyHeaders" format="boolean" />
<attr name="isDrawingListUnderStickyHeader" format="boolean" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,17 @@
*/
class AdapterWrapper extends BaseAdapter implements StickyListHeadersAdapter {

interface OnHeaderClickListener {
private int mStickyHeaderWidth;

public void setStickyHeaderWidth(int stickyHeaderWidth) {
mStickyHeaderWidth = stickyHeaderWidth;
}

void setShowHeaderOnLeft(boolean showHeaderOnLeft) {
mShowHeaderOnLeft = showHeaderOnLeft;
}

interface OnHeaderClickListener {
void onHeaderClick(View header, int itemPosition, long headerId);
}

Expand All @@ -35,6 +45,7 @@ interface OnHeaderClickListener {
private Drawable mDivider;
private int mDividerHeight;
private OnHeaderClickListener mOnHeaderClickListener;
private boolean mShowHeaderOnLeft;
private DataSetObserver mDataSetObserver = new DataSetObserver() {

@Override
Expand Down Expand Up @@ -175,6 +186,8 @@ public WrapperView getView(int position, View convertView, ViewGroup parent) {
wv = new WrapperView(mContext);
}
wv.update(item, header, mDivider, mDividerHeight);
wv.setShowHeaderOnLeft(mShowHeaderOnLeft);
wv.setHeaderWidth(mStickyHeaderWidth);
return wv;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ void onStickyHeaderChanged(StickyListHeadersListView l, View header,

/* --- Settings --- */
private boolean mAreHeadersSticky = true;
private boolean mShowHeaderOnLeft = false;
private boolean mClippingToPadding = true;
private boolean mIsDrawingListUnderStickyHeader = true;
private int mStickyHeaderTopOffset = 0;
Expand All @@ -110,6 +111,8 @@ void onStickyHeaderChanged(StickyListHeadersListView l, View header,
private AdapterWrapperDataSetObserver mDataSetObserver;
private Drawable mDivider;
private int mDividerHeight;
private int mStickyHeaderWidth;
private int mStickyHeaderHeight;

public StickyListHeadersListView(Context context) {
this(context, null);
Expand All @@ -127,6 +130,7 @@ public StickyListHeadersListView(Context context, AttributeSet attrs, int defSty

// Initialize the wrapped list
mList = new WrapperViewList(context);
mList.setTag(this.getTag());

// null out divider, dividers are handled by adapter so they look good with headers
mDivider = mList.getDivider();
Expand Down Expand Up @@ -213,6 +217,9 @@ public StickyListHeadersListView(Context context, AttributeSet attrs, int defSty
mList.setTranscriptMode(a.getInt(R.styleable.StickyListHeadersListView_android_transcriptMode,
ListView.TRANSCRIPT_MODE_DISABLED));

// -- Header attributes --
mStickyHeaderWidth = a.getDimensionPixelSize(R.styleable.StickyListHeadersListView_headerWidth, 100);

// -- StickyListHeaders attributes --
mAreHeadersSticky = a.getBoolean(R.styleable.StickyListHeadersListView_hasStickyHeaders, true);
mIsDrawingListUnderStickyHeader = a.getBoolean(
Expand Down Expand Up @@ -266,8 +273,13 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
if (mHeader != null) {
MarginLayoutParams lp = (MarginLayoutParams) mHeader.getLayoutParams();
int headerTop = lp.topMargin;
mHeader.layout(mPaddingLeft, headerTop, mHeader.getMeasuredWidth()
+ mPaddingLeft, headerTop + mHeader.getMeasuredHeight());
if (mShowHeaderOnLeft) {
mHeader.layout(mPaddingLeft, headerTop, mPaddingLeft + mStickyHeaderWidth,
headerTop + mHeader.getMeasuredHeight());
} else {
mHeader.layout(mPaddingLeft, headerTop, mHeader.getMeasuredWidth()
+ mPaddingLeft, headerTop + mHeader.getMeasuredHeight());
}
}
}

Expand Down Expand Up @@ -581,6 +593,10 @@ private int stickyHeaderTop() {

/* ---------- StickyListHeaders specific API ---------- */

public void setShowHeaderOnLeft(boolean showHeaderOnLeft) {
mShowHeaderOnLeft = showHeaderOnLeft;
}

public void setAreHeadersSticky(boolean areHeadersSticky) {
mAreHeadersSticky = areHeadersSticky;
if (!areHeadersSticky) {
Expand Down Expand Up @@ -719,6 +735,8 @@ public void setAdapter(StickyListHeadersAdapter adapter) {

mAdapter.setDivider(mDivider, mDividerHeight);

mAdapter.setShowHeaderOnLeft(mShowHeaderOnLeft);
mAdapter.setStickyHeaderWidth(mStickyHeaderWidth);
mList.setAdapter(mAdapter);
clearHeader();
}
Expand Down Expand Up @@ -908,6 +926,10 @@ public void smoothScrollToPositionFromTop(int position, int offset,
}
}

public void performItemClick(View view, int position, long id) {
mList.performItemClick(view, position, id);
}

public void setSelection(int position) {
setSelectionFromTop(position, 0);
}
Expand Down
70 changes: 54 additions & 16 deletions library/src/se/emilsjolander/stickylistheaders/WrapperView.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,21 @@ public class WrapperView extends ViewGroup {
int mDividerHeight;
View mHeader;
int mItemTop;
boolean mShowHeaderOnLeft;
private int mHeaderWidth;

WrapperView(Context c) {
super(c);
}

public void setShowHeaderOnLeft(boolean showHeaderOnLeft) {
mShowHeaderOnLeft = showHeaderOnLeft;
}

public void setHeaderWidth(int headerWidth) {
mHeaderWidth = headerWidth;
}

public boolean hasHeader() {
return mHeader != null;
}
Expand Down Expand Up @@ -65,7 +75,13 @@ void update(View item, View header, Drawable divider, int dividerHeight) {
}
this.mHeader = header;
if (header != null) {
addView(header);
if (mShowHeaderOnLeft) {
ViewGroup.LayoutParams params = header.getLayoutParams();
params.width = mHeaderWidth;
addView(header, params);
} else {
addView(header);
}
}
}

Expand All @@ -90,14 +106,20 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mHeader.measure(childWidthMeasureSpec,
MeasureSpec.makeMeasureSpec(params.height, MeasureSpec.EXACTLY));
} else {
mHeader.measure(childWidthMeasureSpec,
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
if (mShowHeaderOnLeft) {
mHeader.measure(MeasureSpec.makeMeasureSpec(mHeaderWidth, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
} else {
mHeader.measure(childWidthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
}
}
if (!mShowHeaderOnLeft) {
measuredHeight += mHeader.getMeasuredHeight();
}
measuredHeight += mHeader.getMeasuredHeight();
} else if (mDivider != null&&mItem.getVisibility()!=View.GONE) {
measuredHeight += mDividerHeight;
}

//measure item
ViewGroup.LayoutParams params = mItem.getLayoutParams();
//enable hiding listview item,ex. toggle off items in group
Expand All @@ -109,6 +131,9 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
MeasureSpec.makeMeasureSpec(params.height, MeasureSpec.EXACTLY));
measuredHeight += mItem.getMeasuredHeight();
} else {
if (mShowHeaderOnLeft) {
childWidthMeasureSpec = childWidthMeasureSpec - mHeaderWidth;
}
mItem.measure(childWidthMeasureSpec,
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
measuredHeight += mItem.getMeasuredHeight();
Expand All @@ -126,18 +151,31 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) {
r = getWidth();
b = getHeight();

if (mHeader != null) {
int headerHeight = mHeader.getMeasuredHeight();
mHeader.layout(l, t, r, headerHeight);
mItemTop = headerHeight;
mItem.layout(l, headerHeight, r, b);
} else if (mDivider != null) {
mDivider.setBounds(l, t, r, mDividerHeight);
mItemTop = mDividerHeight;
mItem.layout(l, mDividerHeight, r, b);
if (mShowHeaderOnLeft) {
if (mDivider != null) {
mDivider.setBounds(mHeaderWidth, t, r, mDividerHeight);
t += mDividerHeight;
}
if (mHeader != null) {
int headerHeight = mHeader.getMeasuredHeight();
mHeader.layout(l, t, mHeaderWidth, headerHeight);
}
mItem.layout(mHeaderWidth, t, r, b);
mItemTop = t;
} else {
mItemTop = t;
mItem.layout(l, t, r, b);
if (mHeader != null) {
int headerHeight = mHeader.getMeasuredHeight();
mHeader.layout(l, t, r, headerHeight);
mItemTop = headerHeight;
mItem.layout(l, headerHeight, r, b);
} else if (mDivider != null) {
mDivider.setBounds(l, t, r, mDividerHeight);
mItemTop = mDividerHeight;
mItem.layout(l, mDividerHeight, r, b);
} else {
mItemTop = t;
mItem.layout(l, t, r, b);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public void run() {
stickyList.setEmptyView(findViewById(R.id.empty));
stickyList.setDrawingListUnderStickyHeader(true);
stickyList.setAreHeadersSticky(true);
stickyList.setShowHeaderOnLeft(true);
stickyList.setAdapter(mAdapter);

mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
Expand Down Expand Up @@ -111,7 +112,6 @@ public void run() {
fastScrollCheckBox = (CheckBox) findViewById(R.id.fast_scroll_checkBox);
fastScrollCheckBox.setOnCheckedChangeListener(checkBoxListener);

stickyList.setStickyHeaderTopOffset(-20);
}

@Override
Expand Down