ListView overlay another layout when scroll
Asked Answered
M

2

8

Actually I don't know how it properly called - overlay, parallax or slideUP, whatever, I have an Activity called "cafe details" which presents a Container(LinearLayout) with header information (name, min price, delivery time min e.t.c) and other container (ViewPager) which contains a ExpandableListView with something information (menus&dishes) and all I want to do is slide up my Viewpager when scrolls listview to scpecific Y position to cover(or overlay) header information.

MyPic

A similar effect (but with parallax that I don't need to use) looks like this

Similar effect

I can detect when user scrolling listview down or up but how I can move container with ViewPager to overlay other container? Please give me ideas, regards.

UPD I have tried a huge number of ways how to implement it and all of them unfortunately are not suitable. So now I have come to next variant - add scroll listener to ListView, calculate scrollY position of view and then based on that move the viewpager on y axis by calling setTranslationY(); Here is some code

1) ViewPager's fragment

    mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView absListView, int i) {

        }

        @Override
        public void onScroll(AbsListView absListView, int i, int i1, int i2) {
            if (getActivity() != null) {
                ((MainActivity) getActivity()).resizePagerContainer(absListView);
            }
        }
    });

2) MainActivity

//object fields

int previousPos; 
private float minTranslation;
private float minHeight;

<--------somewhere in onCreate

minTranslation = - (llVendorDescHeaders.getMeasuredHeight()+llVendorDescNote.getMeasuredHeight());
//llVendorDescHeaders is linearLayout with headers that should be hidden
//lVendorDescNote is a textView on green background;

minHeight = llVendorDescriptionPagerContainer.getMeasuredHeight();
//llVendorDescriptionPagerContainer is a container which contains ViewPager
--------->

public void resizePagerContainer(AbsListView absListView){

    final int scrollY = getScrollY(absListView);
    if (scrollY != previousPos) {
        final float translationY = Math.max(-scrollY, minTranslation);

        llVendorDescriptionPagerContainer.setTranslationY(translationY);

        previousPos = scrollY;
    }
}

private int getScrollY(AbsListView view) {
    View child = view.getChildAt(0);
    if (child == null) {
        return 0;
    }

    int firstVisiblePosition = view.getFirstVisiblePosition();
    int top = child.getTop();

    return -top + firstVisiblePosition * child.getHeight() ;
}

This simple solution unfortunately has a problem - it is blinking and twitching (I don't know how to call it right) when scrolls slowly. So instead setTranslationY() I've used an objectAnimator:

public void resizePagerContainer(AbsListView absListView){
    .............

    ObjectAnimator moveAnim = ObjectAnimator.ofFloat(llVendorDescriptionPagerContainer, "translationY", translationY);
    moveAnim.start();
   ..............
}

I don't like this solution because 1) anyway it does resize viewpager with delay, not instantly 2) I don't think that is good idea to create many ObjectAnimator's objects every time when I scroll my listView. Need your help and fresh ideas. Regards.

Matrimony answered 22/5, 2015 at 12:42 Comment(0)
R
1

Have you tried CoordinatorLayout from this new android's design support library? It looks like it's what you need. Check this video from 3:40 or this blog post.

Ruffner answered 30/5, 2015 at 15:2 Comment(1)
thanks for your response, I didn't know that google recently released new tricks in android support libraryMatrimony
K
2

I'm assuming that you are scrolling the top header (the ImageView is a child of the header) based on the scrollY of the ListView/ScrollView, as shown below:

float translationY = Math.max(-scrollY, mMinHeaderTranslation);
mHeader.setTranslationY(translationY);
mTopImage.setTranslationY(-translationY / 3); // For parallax effect

If you want to stick the header/image to a certain dimension and continue the scrolling without moving it anymore, then you can change the value of mMinHeaderTranslation to achieve that effect.

//change this value to increase the dimension of header stuck on the top
int tabHeight = getResources().getDimensionPixelSize(R.dimen.tab_height); 

mHeaderHeight = getResources().getDimensionPixelSize(R.dimen.header_height);
mMinHeaderTranslation = -mHeaderHeight + tabHeight;

The code snippets above are in reference to my demo but I think it's still general enough for you.

If you're interested you can check out my demo https://github.com/boxme/ParallaxHeaderViewPager

Konstantin answered 24/5, 2015 at 8:21 Comment(0)
R
1

Have you tried CoordinatorLayout from this new android's design support library? It looks like it's what you need. Check this video from 3:40 or this blog post.

Ruffner answered 30/5, 2015 at 15:2 Comment(1)
thanks for your response, I didn't know that google recently released new tricks in android support libraryMatrimony

© 2022 - 2024 — McMap. All rights reserved.