如何将粘性标题添加到视差ScrollView?

时间:2015-03-19 13:02:55

标签: android scrollview parallax

我已根据this answer创建了ParallaxScrollView,视差效果与ImageView的效果很好。

public class ParallaxScrollView extends ScrollView {

    private Activity activity;

    private View imgContainer;

    private ImageView imageView;

    private float parallaxValue;

    public ParallaxScrollView(final Context context) {
        this(context, null);
    }

    public ParallaxScrollView(final Context context, final AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ParallaxScrollView(final Context context, final AttributeSet attrs, final int defStyle) {
        super(context, attrs, defStyle);
    }

    public void setParallaxParams(final Activity activity, final View imgContainer, final ImageView imageView, final float parallaxValue) {
        this.activity = activity;
        this.imgContainer = imgContainer;
        this.imageView = imageView;
        this.parallaxValue = parallaxValue;
    }

    @Override
    protected void onScrollChanged(final int l, final int t, final int oldl, final int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (activity == null || imgContainer == null || imageView == null) {
            throw new IllegalStateException("Please set parallax parameters via setParallaxParams() method!");
        }

        if (imageView.getTop() == 0) {
            imageView.setTranslationY(getScrollY() * parallaxValue);
            return;
        }

        // Get scroll view screen bound
        final Rect scrollBounds = new Rect();
        getHitRect(scrollBounds);

        // Check if image container is visible in the screen
        // so to apply the translation only when the container is visible to the user
        if (imgContainer.getLocalVisibleRect(scrollBounds)) {
            final Display display = activity.getWindowManager().getDefaultDisplay();
            final DisplayMetrics outMetrics = new DisplayMetrics ();
            display.getMetrics(outMetrics);
            // Get screen density
            final float density  = getResources().getDisplayMetrics().density;

            // Get screen height in pixels
            final float dpHeight = outMetrics.heightPixels / density;
            final float screenHeightPixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpHeight, getResources().getDisplayMetrics());
            final float halfScreenHeight = screenHeightPixels / 2;

            // Get image container height in pixels
            final float containerHeightPixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, imgContainer.getHeight(), getResources().getDisplayMetrics());

            // Get the location that consider a vertical center for the image (where the translation should be zero)
            final float center = halfScreenHeight - (containerHeightPixels / 2);

            // get the location (x,y) of the image container in pixels
            final int[] locScreen = {0,0};
            imgContainer.getLocationOnScreen(locScreen);

            // trying to transform the current image container location into percentage
            // so when the image container is exaclty in the middle of the screen percentage should be zero
            // and as the image container getting closer to the edges of the screen should increase to 100%
            final float finalLoc = ((locScreen[1]-center) * 100)/ halfScreenHeight;

            // translate the inner image taking consideration also the density of the screen
            imageView.setTranslationY(-finalLoc * parallaxValue * density);
        }
    }
}

以下是我如何使用它:

parallaxScrollView.setParallaxParams(getActivity(), imageContainer, image, 0.5f);

现在,我想向Toolbar添加一个粘性标题,因此当用户向下滚动并且标题位于Toolbar下面的屏幕顶部时,它将会#34;棒"到Toolbar,当用户向上滚动并且标题下方的内容到达顶部时,它应该"解开"。很难解释,但我希望很清楚:)

以下是布局的样子:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <ParallaxScrollView
        android:id="@+id/scroll_view"
        android:fillViewport="true"
        android:overScrollMode="never"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <FrameLayout
                android:id="@+id/image_container"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" >

                <ImageView
                    android:id="@+id/image"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:adjustViewBounds="true"
                    android:scaleType="centerCrop" />
            </FrameLayout>

            <FrameLayout
                android:id="@+id/sticky_header"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" >

                <!-- Content -->
            </FrameLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:paddingTop="@dimen/padding_big"
                android:paddingBottom="@dimen/padding_big"
                android:paddingEnd="@dimen/padding_big"
                android:paddingStart="@dimen/padding_big"
                android:paddingLeft="@dimen/padding_big"
                android:paddingRight="@dimen/padding_big">

                <!-- Content -->

所以,基本上我想要&#34;坚持&#34;用户滚动时,FrameLayout {id @+id/stickyHeader位于顶部。

AirBnb在其Android应用程序(take a look at sticky tab bar at this link)中使用的方法非常类似。

任何想法如何做到这一点? 理想情况下,不使用第三方库。

0 个答案:

没有答案