AdevintaSpain / Parallax-Layer-Layout

Layered parallax effect to any Android views
957 stars 84 forks source link

Extend Image Beyond Bounds? #16

Closed rayliverified closed 7 years ago

rayliverified commented 7 years ago

Wow, I've had my eye on this library for a long time and am finally getting the opportunity to implement it in my project. This library is AMAZING! There are so much mindblowing creations openned up by this library and I am super excited to use it. Thank you for sharing!

The problem at hand deals with images that are supposed to extend beyond the boundaries of the screen. Currently, if an image is set to match the width and height of the view, a blank space appears when the parallax effect is in action. This is because the parallax moves the view, showing the background. Is there a way to make images extend off the screen so that when they are moved, they are not cropped? Thanks for the help!

rayliverified commented 7 years ago

Found a way to solve this issue, not too difficult! Simply extend the ViewGroup layout bounds beyond the visible screen. Set a negative top and left margin and increase the layout size by double the amount to compensate. Place the following code in onActivityCreated and you are good to go!

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        DisplayMetrics displayMetrics = new DisplayMetrics();
        getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        int height = displayMetrics.heightPixels;
        int width = displayMetrics.widthPixels;

        mFrameLayout = (FrameLayout) getView().findViewById(R.id.intro_layout);
        FrameLayout.LayoutParams lp;
        lp = (FrameLayout.LayoutParams) mFrameLayout.getLayoutParams();
        lp.topMargin = -(int)getResources().getDimension(R.dimen.parallax_margin);
        lp.leftMargin = -(int)getResources().getDimension(R.dimen.parallax_margin);
        lp.width = width + (int)getResources().getDimension(R.dimen.parallax_margin)*3;
        lp.height = height + (int)getResources().getDimension(R.dimen.parallax_margin)*3;
        mFrameLayout.setLayoutParams(lp);
    }

I wonder if there is a better way. This way is simple enough but I will keep this issue open for a week to allow discussion!

Sloy commented 7 years ago

Hi @searchy2! I'm glad you find the library useful :)

That's an interesting use case we didn't thought about. We originally intended the parallax for simpler images like the one you see in the readme. But I get why you would want a full bleed background.

Does that sample code work as you expect? If so, we could consider adding it to the library, maybe with some flag to tell that the view acts as a background. Do you have any sample project where we can try it out?

rayliverified commented 7 years ago

The sample code works correctly. The code does not need to be placed in the library. Instead, it is placed in the onActivityCreated method of the fragment containing the parallax view. I am using it in my app intro with onboarding. Here's a link to the APK: http://www.mediafire.com/file/ag91cd63vo6git6/Secret_Intro_v1.0.0.apk

Preview: secret intro preview

As you can see, I have a match_parent background, stars, and mountains. I find setting the margins to -60dp and the parallax base to 10dp with 15dp offset is within bounds. Setting the offset to 20dp moves the items enough to display the background. The library and code works great!

Sloy commented 7 years ago

It looks awesome! Great work :)

I meant that the library itself could have a feature that makes this little hack for backgrounds. Like an extendBounds="#dp" attribute or something like that. What do you think? If you think it would be a helpful addition feel free to open a PR with it :)

In any case, I'm glad that you could make it work for you and that you like the result. It's always nice to see how other people use what you shared 😃

rayliverified commented 7 years ago

@Sloy Thanks, it's your library that really adds the final touch!

I understand what you mean about adding the feature to the library and it is more trouble than it is worth. You have to consider that extending the view bounds progamatically means that the bounds are changed for ALL items in the layout. To make everything appear correctly, the user will likely have to do a few more custom computations to set the position of the items in the layout.

Here is the full XML of my intro layout:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:app="http://schemas.android.com/apk/res-auto"
             xmlns:gradient="http://schemas.android.com/apk/res-auto"
             android:id="@+id/intro_layout"
             android:layout_width="match_parent"
             android:layout_height="match_parent">

    <com.schibsted.spain.parallaxlayerlayout.ParallaxLayerLayout
        android:id="@+id/parallax"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:parallaxOffsetBase="10dp"
        app:parallaxOffsetIncrement="15dp">

        <com.dynamitechetan.flowinggradient.FlowingGradient
            android:id="@+id/background_gradient"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            gradient:transition_drawable="@drawable/bg_gradient_transition"
            gradient:transition_duration="6000"
            app:layout_parallaxEnabled="false"/>

        <com.yasic.library.particletextview.View.ParticleTextView
            android:id="@+id/particleTextView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_parallaxEnabled="false"/>

        <ImageView
            android:id="@+id/background_moon"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:srcCompat="@drawable/bg_moon"/>

        <ImageView
            android:id="@+id/foreground_image"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginBottom="-40dp"
            android:scaleType="fitEnd"
            app:srcCompat="@drawable/mountains_geometric"/>

        <RelativeLayout
            android:id="@+id/intro_layout_relative"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:descendantFocusability="beforeDescendants"
            android:focusableInTouchMode="true">

            <ImageView
                android:layout_width="60dp"
                android:layout_height="60dp"
                android:layout_marginBottom="12dp"
                android:layout_centerHorizontal="true"
                android:layout_above="@+id/intro_title"
                android:src="@drawable/logo_outline_all"/>

            <TextView
                android:id="@+id/intro_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Secret Messenger"
                android:layout_centerHorizontal="true"
                android:layout_above="@+id/intro_textwidget"
                android:textSize="24dp"
                android:textColor="@color/white"/>

            <android.support.design.widget.TextInputLayout
                android:id="@+id/intro_textwidget"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="8dp"
                android:layout_above="@+id/btn_continue"
                android:layout_centerHorizontal="true"
                android:theme="@style/TextAppearence.App.TextInputLayout">

                <EditText
                    android:id="@+id/intro_edittext"
                    android:layout_width="200dp"
                    android:layout_height="wrap_content"
                    android:textSize="18sp"
                    android:textColor="@color/white"
                    android:hint="Enter email"
                    android:textColorHint="@color/white"/>
            </android.support.design.widget.TextInputLayout>

            <stream.secretintro.ui.CustomButton
                android:id="@+id/btn_continue"
                android:layout_width="190dp"
                android:layout_height="wrap_content"
                android:paddingTop="6dp"
                android:paddingBottom="6dp"
                android:paddingLeft="8dp"
                android:paddingRight="8dp"
                android:layout_centerHorizontal="true"
                android:layout_above="@+id/space_bottom"
                android:text="Continue"
                android:textSize="18sp"
                android:maxLines="1"
                android:singleLine="true"
                android:ellipsize="none"
                app:btn_cornerRadius="20dp"
                app:btn_strokeWidth="1dp"
                app:btn_strokeColor="@color/white"
                app:btn_unpressColor="@color/transparent"
                app:btn_pressColor="@color/transparent"
                app:btn_text_unpressColor="@color/white"
                app:btn_text_pressColor="@color/white"/>

            <android.support.v4.widget.Space
                android:id="@+id/space_bottom"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_alignParentBottom="true"/>
        </RelativeLayout>
    </com.schibsted.spain.parallaxlayerlayout.ParallaxLayerLayout>
</FrameLayout>

Most of the view items are centered horizontal and their width is set proportional to the screen width using the following code:

        int layoutWidth = (int) (width/2);
        mEditText.getLayoutParams().width = layoutWidth;
        mButton.getLayoutParams().width = layoutWidth - Units.dpToPx(mContext, 10);
        mSpace.getLayoutParams().height = height/2 - Units.dpToPx(mContext, 75);

Hopefully the code snippets above provide enough guidance for someone that would like to create something like this in the future! Libraries used:

https://github.com/dynamitechetan/Flowing-Gradient https://github.com/Yasic/ParticleTextView

Sloy commented 7 years ago

Thanks a lot for sharing that 😃