简体   繁体   中英

Keeping an image “pinned” when scrolling

I am trying to create the effect seen on this webpage for example

http://www.soyuzcoffee.com/ru/home

the part where as you scroll it appears as the main content is scrolling over the big images (images that act as dividers between sections)

I am very close but if the image is smaller that the height of the view (image does not fill the entire screen) the image scrolls up like it normally would until it hits the top. I am trying to make it look like the image is stationary and the frame is moving over it.

here is my layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.example.pinnedscrollview.CustomScrollView
        android:id="@+id/scroller"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

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

            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent" >

                <com.example.pinnedscrollview.PinnedImageView
                    android:id="@+id/image"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"/>
            </FrameLayout>

            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent" >

                <com.example.pinnedscrollview.PinnedImageView
                    android:id="@+id/image2"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"/>
            </FrameLayout>

            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent" >

                <com.example.pinnedscrollview.PinnedImageView
                    android:id="@+id/image3"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"/>
            </FrameLayout>

            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent" >

                <com.example.pinnedscrollview.PinnedImageView
                    android:id="@+id/image4"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"/>
            </FrameLayout>
        </LinearLayout>
    </com.example.pinnedscrollview.CustomScrollView>

</RelativeLayout>

Then I have an onScrollChangedListener that runs this method everytime the scroll position changes

private void handleScroll(ViewGroup source, int top) {
    ViewGroup container = (ViewGroup) source.findViewById(R.id.container);
    final int count = container.getChildCount();
    for (int i = 0; i < count; i++) {
        View item = container.getChildAt(i);
        View v = null;
        if(i == 0){
            v = item.findViewById(R.id.image);
        }else if(i == 1){
            v = item.findViewById(R.id.image2);
        }else if(i == 2){
            v = item.findViewById(R.id.image3);
        }else if(i == 3){
            v = item.findViewById(R.id.image4);
        }
        source.getHitRect(mTempRect);
        if (v != null && v.getLocalVisibleRect(mTempRect)) {
            ((PinnedImageView) v).reveal(source, item.getBottom(),item.getTop());
        }
    }
}

Then this is the reveal method that just sets the Translation in the Y direction

public void reveal(View scroller,int parentBottom,int parentTop) {
        float previousOffset = mOffsetY;

        if(parentTop - scroller.getScrollY() < 0){
            mOffsetY= Math.abs(parentTop - scroller.getScrollY());
        }else{
            mOffsetY = Math.min(0, scroller.getHeight() - (parentBottom - scroller.getScrollY()));
        }

        if (previousOffset != mOffsetY) {
            setTranslationY(mOffsetY);
        }
    }

I am not sure if I need to do something with the Matrix of the image in the onDraw and redraw the bitmap or not.

Any ideas or other ways that I can accomplish something similar to that website?

I would set the desired image as a background image of a containing layout. Then set appropriate transparencies and place the scrollable view as a child of the parent layout that contains the image. You may even be able to set the background of the scrollable view itself.

You then may be able to use conditionals etc to adjust the frame of the background image and swap images based on the scroll position.

<LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        android:layout_marginTop="48dp"
        android:background="@drawable/tmf_background"
     >
        <ImageView
            android:src="@drawable/the_lineup_header"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:paddingTop="16.5dp"
            android:contentDescription="@string/noDescription" />
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:background="@drawable/tmf_sub_header" >
            <TextView... />
            <Button ... />
            <Button... />
            <Button ... />
            <TextView ... />
        </LinearLayout>
        <ListView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:divider="@drawable/tmf_divider"
            android:background="@android:color/transparent" >       
        </ListView>
     </LinearLayout>

Here is a chunk of the xml for the free app I did for True Music Festival for it's first year. https://play.google.com/store/apps/details?id=com.fyresite.truemusicapp There we have a single background image that stays static while the content scrolls over it. Combining that with your scroll position listener you should be able to, at the very least, change the background image as you scroll. You could then try transforming the background image to get that scrolling effect on the site.

You may find this question to be useful Android: Moving background image while navigating through Views

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM