-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Draw divider for list header/footer views #268
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,12 @@ public class WrapperView extends ViewGroup { | |
super(c); | ||
} | ||
|
||
WrapperView(Context c, View item) { | ||
super(c); | ||
|
||
update(item, null, null, 0); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It can easily get confusing when a constructor does anything else than constructing an object, i think calling update() should be done outside of the constructor as before. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you've made a valid point. I'll revert this change. |
||
} | ||
|
||
public boolean hasHeader() { | ||
return mHeader != null; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ | |
import android.content.Context; | ||
import android.graphics.Canvas; | ||
import android.graphics.Rect; | ||
import android.graphics.drawable.Drawable; | ||
import android.os.Build; | ||
import android.view.View; | ||
import android.widget.AbsListView; | ||
|
@@ -19,11 +20,18 @@ interface LifeCycleListener { | |
} | ||
|
||
private LifeCycleListener mLifeCycleListener; | ||
private List<View> mFooterViews; | ||
private List<WrapperView> mHeaderWrapperViews; | ||
private List<WrapperView> mFooterWrapperViews; | ||
private int mTopClippingLength; | ||
private Rect mSelectorRect = new Rect();// for if reflection fails | ||
private Field mSelectorPositionField; | ||
private boolean mClippingToPadding = true; | ||
private Drawable mDivider; | ||
private int mDividerHeight; | ||
private Rect mDividerTempRect = new Rect(); | ||
private boolean mHeaderDividersEnabled = true; | ||
private boolean mFooterDividersEnabled = true; | ||
|
||
|
||
public WrapperViewList(Context context) { | ||
super(context); | ||
|
@@ -103,36 +111,132 @@ protected void dispatchDraw(Canvas canvas) { | |
} else { | ||
super.dispatchDraw(canvas); | ||
} | ||
|
||
// bottom divider | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not that fun code to put in this class. I don't have any other suggestion right now but i definitely think this should somehow be moved into the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well I don't like this code either in that this makes similar logic to be scattered, also have no idea how this could be done nice at this moment. |
||
if (mFooterDividersEnabled && mDivider != null && getChildCount() > 0) { | ||
int t = getChildAt(getChildCount() - 1).getBottom(); | ||
|
||
mDividerTempRect.set(mDivider.getBounds()); | ||
|
||
mDivider.setBounds(getPaddingLeft(), t, getRight() - getLeft() - getPaddingRight(), t + mDividerHeight); | ||
mDivider.draw(canvas); | ||
mDivider.setBounds(mDividerTempRect); // restore bounds | ||
} | ||
mLifeCycleListener.onDispatchDrawOccurred(canvas); | ||
} | ||
|
||
void setLifeCycleListener(LifeCycleListener lifeCycleListener) { | ||
mLifeCycleListener = lifeCycleListener; | ||
} | ||
|
||
void setListDivider(Drawable divider, int dividerHeight) { | ||
this.mDivider = divider; | ||
this.mDividerHeight = dividerHeight; | ||
} | ||
|
||
@Override | ||
public void setHeaderDividersEnabled(boolean headerDividersEnabled) { | ||
super.setHeaderDividersEnabled(headerDividersEnabled); | ||
this.mHeaderDividersEnabled = headerDividersEnabled; | ||
|
||
updateHeaderViews(); | ||
} | ||
|
||
@Override | ||
public void setFooterDividersEnabled(boolean footerDividersEnabled) { | ||
super.setFooterDividersEnabled(footerDividersEnabled); | ||
this.mFooterDividersEnabled = footerDividersEnabled; | ||
|
||
updateFooterViews(); | ||
} | ||
|
||
@Override | ||
public void addHeaderView(View v, Object data, boolean isSelectable) { | ||
if (mHeaderWrapperViews == null) { | ||
mHeaderWrapperViews = new ArrayList<WrapperView>(); | ||
} | ||
|
||
WrapperView wv = new WrapperView(getContext(), v); | ||
super.addHeaderView(wv, data, isSelectable); | ||
mHeaderWrapperViews.add(wv); | ||
|
||
updateHeaderViews(); | ||
} | ||
|
||
@Override | ||
public void addFooterView(View v) { | ||
super.addFooterView(v); | ||
if (mFooterViews == null) { | ||
mFooterViews = new ArrayList<View>(); | ||
public boolean removeHeaderView(View v) { | ||
WrapperView wv = getWrapperViewByItem(mHeaderWrapperViews, v); | ||
if (wv != null) { | ||
super.removeHeaderView(wv); | ||
mHeaderWrapperViews.remove(wv); | ||
updateHeaderViews(); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
private void updateHeaderViews() { | ||
for (int i = 0; i < getHeaderViewsCount(); i++) { | ||
WrapperView wv = mHeaderWrapperViews.get(i); | ||
if (i == 0 || !mHeaderDividersEnabled) { | ||
wv.update(wv.getItem(), null, null, 0); | ||
} else { | ||
wv.update(wv.getItem(), null, mDivider, mDividerHeight); | ||
} | ||
} | ||
mFooterViews.add(v); | ||
} | ||
|
||
@Override | ||
public void addFooterView(View v, Object data, boolean isSelectable) { | ||
if (mFooterWrapperViews == null) { | ||
mFooterWrapperViews = new ArrayList<WrapperView>(); | ||
} | ||
|
||
WrapperView wv = new WrapperView(getContext(), v); | ||
super.addFooterView(wv, data, isSelectable); | ||
mFooterWrapperViews.add(wv); | ||
|
||
updateFooterViews(); | ||
} | ||
|
||
@Override | ||
public boolean removeFooterView(View v) { | ||
if (super.removeFooterView(v)) { | ||
mFooterViews.remove(v); | ||
WrapperView wv = getWrapperViewByItem(mFooterWrapperViews, v); | ||
if (wv != null) { | ||
super.removeFooterView(wv); | ||
mFooterWrapperViews.remove(wv); | ||
// no need to update dividers | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
private void updateFooterViews() { | ||
for (int i = 0; i < getFooterViewsCount(); i++) { | ||
WrapperView wv = mFooterWrapperViews.get(i); | ||
if (!mFooterDividersEnabled) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. small detail but i would rather have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think he means
Invert the if-condition and switch the bodies. |
||
wv.update(wv.getItem(), null, null, 0); | ||
} else { | ||
wv.update(wv.getItem(), null, mDivider, mDividerHeight); | ||
} | ||
} | ||
} | ||
|
||
static WrapperView getWrapperViewByItem(List<WrapperView> wrapperViewList, View item) { | ||
for (WrapperView wrapperView : wrapperViewList) { | ||
if (wrapperView.getItem() == item) { | ||
return wrapperView; | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
boolean containsFooterView(View v) { | ||
if (mFooterViews == null) { | ||
if (mFooterWrapperViews == null) { | ||
return false; | ||
} | ||
return mFooterViews.contains(v); | ||
|
||
return getWrapperViewByItem(mFooterWrapperViews, v) != null; | ||
} | ||
|
||
void setTopClippingLength(int topClipping) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,14 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent" > | ||
|
||
<TextView android:text="@string/app_name" | ||
android:layout_width="match_parent" | ||
android:layout_height="700dip" | ||
android:gravity="center" | ||
android:layout_gravity="center"/> | ||
|
||
android:layout_height="match_parent"> | ||
|
||
<TextView | ||
android:text="@string/app_name" | ||
android:layout_width="match_parent" | ||
android:layout_height="350dip" | ||
android:gravity="center" | ||
android:layout_gravity="center" /> | ||
|
||
|
||
</FrameLayout> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,14 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent" > | ||
|
||
<TextView android:text="@string/app_name" | ||
android:layout_width="match_parent" | ||
android:layout_height="400dip" | ||
android:gravity="center" | ||
android:layout_gravity="center"/> | ||
|
||
android:layout_height="match_parent"> | ||
|
||
<TextView | ||
android:text="@string/app_name" | ||
android:layout_width="match_parent" | ||
android:layout_height="200dip" | ||
android:gravity="center" | ||
android:layout_gravity="center" /> | ||
|
||
|
||
</FrameLayout> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is very confusing as it looks like the two above line of code are useless even though they aren't
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because
mDivider
andmDividerHeight
must be passed tomList
, those threeset*Divider*()
s will be there anyway. I'd love to make it less confusing, yet nothing came up in my mind for now.