ListView 滚动时覆盖另一个布局

ListView overlay another layout when scroll

实际上我不知道它是如何正确调用的——overlay、parallax 或 slideUP,无论如何,我有一个名为 "cafe details" 的 Activity,它显示了一个带有 [=40= 的 Container(LinearLayout) ] 信息(名称,最低价格,交货时间分钟 e.t.c)和其他容器(ViewPager),其中包含带有某些信息(菜单和菜肴)的 ExpandableListView,我想做的就是在将列表视图滚动到特定 Y 时向上滑动我的 Viewpager覆盖(或覆盖)header 信息的位置。

类似的效果(但我不需要使用视差)看起来像这样

我可以检测到用户何时向下或向上滚动列表视图,但是如何使用 ViewPager 移动容器以覆盖其他容器?请给我出主意,问好。

UPD 我已经尝试了很多方法来实现它,但不幸的是,所有方法都不适合。所以现在我来到下一个变体 - 向 ListView 添加滚动侦听器,计算视图的 scrollY 位置,然后基于此通过调用 setTranslationY() 在 y 轴上移动 viewpager; 这是一些代码

1) ViewPager 的片段

    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) 主要Activity

//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() ;
}

不幸的是,这个简单的解决方案有一个问题 - 它在缓慢滚动时闪烁和抽动(我不知道如何正确称呼它)。所以我使用了 objectAnimator:

而不是 setTranslationY()
public void resizePagerContainer(AbsListView absListView){
    .............

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

我不喜欢这个解决方案,因为 1) 无论如何它确实会延迟调整 viewpager 的大小,而不是立即调整 2) 我不认为每次滚动时创建许多 ObjectAnimator 的 objects 是个好主意我的列表视图。 需要您的帮助和新鲜的想法。问候。

我假设您正在滚动顶部 header(ImageView 是 header 的 child)基于 ListView/ScrollView 的 scrollY,如下图:

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

如果您想将 header/image 固定到某个维度并继续滚动而不移动它,那么您可以更改 mMinHeaderTranslation 的值来实现该效果。

//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;

上面的代码片段参考了我的演示,但我认为它对您来说仍然足够通用。

有兴趣的可以看看我的demo https://github.com/boxme/ParallaxHeaderViewPager

您尝试过这个新 android 设计支持库中的 CoordinatorLayout 吗?看起来这就是你所需要的。 Check this video from 3:40 or this blog post.