ParallaxScroll
ParallaxScroll copied to clipboard
Dividers
Hello, I have a problem with ParallaxListView when i use it with a single header. In my header, i have a dark background. I have also dividers enabled in my listview. When i scroll, i see the header's background hover the dividers..
do you know this problem ? (tested on Kitkat/ICS/gingerbread)
thank you
I guess its make sense since the dividers are draw separately from the views - that get offset to make the parallax effect. I think that the best thing will be to override the way the dividers work in the ParrallaxListView but for now you can use your dividers as part of your views and it will work fine - you can make a vertical linear layout that contains your list view item with addition of a separator view.
Yes, that's exactly what I did. I just was pointing the problem for your knowledge :)
Hi @mypplication , Could you provide an example of the fix? I'd like to remove the dividers showing the background
edit: adding android:divider="@null" to the ParallaxListView fixed it
<com.nirhart.parallaxscroll.views.ParallaxListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:parallax_factor="1.9"
tools:context=".MainActivity"
android:divider="@null"
/>
No it did't work. Whenever parallax background is drawing with the list, they just mix up.
If you want definitively remove divider in your listview, set android:divider="@null" and android:dividerHeight="0dp"
thank you
@nirhart I've found a pretty horrendous solution since it requires API 18, but at least it might be helpful for yourself to figure out a better way. So the problem is with the headerview drawing over the divider/adapter views. Ideally the headerview can be clipped by the offset so that it doesn't draw over the adapter views (this happens if you add any transparency to the adapter views, you can see an odd effect with the parallax). API 18 added a way to clip views but only clips itself and not its children.
I tried a quick solution below just to prove it could work:
view.setTranslationY(offset);
if (android.os.Build.VERSION.SDK_INT >= 18) { //obv this could be optimised
Rect clipRect = new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom() + (int) offset);
view.setClipBounds(clipRect);
if(view instanceof ViewGroup) { //here we would have to act recursively to get all children views and set the clipping on every child and child's child (ughh)
((ViewGroup) view).getChildAt(0).setClipBounds(clipRect);
}
}
The actual code to clip the view isn't big (when thinking of compatibility). see: http://stackoverflow.com/questions/18724976/can-setclipbounds-be-called-on-a-view-before-it-has-been-drawn#answer-19927060
But it would be very inconvenient if every view within the headerview had to extend a custom view
@nirhart I had another attempt tonight to find an easier solution and here it is.
public class ClippingRelativeLayout extends RelativeLayout {
private int offset;
public ClippingRelativeLayout(Context context) {
super(context);
}
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.clipRect(new Rect(getLeft(), getTop(), getRight(), getBottom() + offset));
super.dispatchDraw(canvas);
}
public void setClipY(int offset) {
this.offset = offset;
invalidate();
}
}
by doing the clipRect() in dispatchDraw all the children are clipped and therefore don't need the recursive approach above. It is also fully compatible (although I haven't tested on older versions of android). Then in ParallaxView:
@SuppressLint("NewApi")
public void setOffset(float offset) {
ClippingRelativeLayout view = this.view.get();
if (view != null) {
if (isAPI11) {
view.setTranslationY(offset);
} else {
translatePreICS(view, offset);
}
view.setClipY((int) offset);
}
}
And then
public void addParallaxedHeaderView(View v) {
ClippingRelativeLayout clippingLayout = new ClippingRelativeLayout(v.getContext());
clippingLayout.addView(v);
super.addHeaderView(clippingLayout);
helper.addParallaxedHeaderView(clippingLayout);
}
Note - It would need testing/tweaking for adding multiple HeaderViews.
Edit: It also needs sorting for parallax factors other than 1.9
@LukeDeighton Thank you very much for your contribution, I'll take a look at it once I'll have some spare time
@nirhart Any update regarding the issue? Thanks.
@LukeDeighton awesome!