How can I snap an image to the center in Imageview in scrollview, in Android?

When I view my Android scroll profile, it scrolls as it should.

But I would like the image in the image to be centered. Thus, you always see the person’s face in the image when scrolling up.

So far, I have not been able to complete this

A similar effect is created in the image below:

enter image description here

Stockguy Image:

enter image description here

My code so far (which has not yet achieved this):

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:fillViewport="true" android:scrollbars="none" android:background="#FAFAFA" android:id="@+id/cScrollview" > <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="1100dp" tools:context=".MainActivity" android:id="@+id/CRLayout"> <ImageView android:layout_gravity="center" android:adjustViewBounds="true" android:layout_width="601dp" android:layout_height="250dp" android:paddingTop="0dp" android:paddingLeft="0dp" android:paddingRight="0dp" android:scaleType="centerCrop" android:id="@+id/contactPic" android:src="@drawable/stockguy"/> .... </RelativeLayout> </ScrollView> 
+6
source share
3 answers

To achieve the parallax effect, for example, on the image that you published, try the following code. This is a very easy way.

Markup:

 <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/scrollView" android:layout_width="match_parent" android:layout_height="match_parent"> <RelativeLayout android:id="@+id/rlWrapper" android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/ivContactPhoto" android:layout_width="match_parent" android:layout_height="@dimen/contact_photo_height" android:scaleType="centerCrop" android:src="@drawable/stockguy" /> <LinearLayout android:layout_width="match_parent" android:layout_height="@dimen/contact_photo_height" android:layout_marginTop="250dp"> <!-- Other Views --> </LinearLayout> </RelativeLayout> </ScrollView> 

LinearLayout top margin equal to the height of ImageViews .

Listening to the scroll position of the ScrollView and changing the position of the ImageView :

 @Override protected void onCreate(Bundle savedInstanceState) { <...> mScrollView = (ScrollView) findViewById(R.id.scrollView); mPhotoIV = (ImageView) findViewById(R.id.ivContactPhoto); mWrapperRL = (RelativeLayout) findViewById(R.id.rlWrapper); mScrollView.getViewTreeObserver().addOnScrollChangedListener(new ScrollPositionObserver()); <...> } private class ScrollPositionObserver implements ViewTreeObserver.OnScrollChangedListener { private int mImageViewHeight; public ScrollPositionObserver() { mImageViewHeight = getResources().getDimensionPixelSize(R.dimen.contact_photo_height); } @Override public void onScrollChanged() { int scrollY = Math.min(Math.max(mScrollView.getScrollY(), 0), mImageViewHeight); // changing position of ImageView mPhotoIV.setTranslationY(scrollY / 2); // alpha you can set to ActionBar background float alpha = scrollY / (float) mImageViewHeight; } } 

Hope this helps.

+2
source

I would choose a different approach.

Try creating your layout based on the following snippet:

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/image" android:layout_width="match_parent" android:background="#00FF00" android:scaleType="centerCrop" android:layout_height="200dp"/> <FrameLayout android:id="@+id/content" android:layout_below="@+id/image" android:background="#FF0000" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout> 

Using the GestureDetector.SimpleOnGestureListener , you can detect when the user scrolls the content layout and updates the image size and alpha to get the described effect.

+1
source

I would implement this using a scroll callback in a ScrollView, this does not exist by default, but it is easy to create it by extending the ScrollView:

 public class UpdatingScrollView extends ScrollView { private OnScrollChangedListener mScrollChangedListener; public interface OnScrollChangedListener { public void onScrollChanged(int x, int y, int oldx, int oldy); } public UpdatingScrollView(Context context) { super(context); } public UpdatingScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public UpdatingScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void setOnScrollChangedListener(OnScrollChangedListener listener) { mScrollChangedListener = listener; } @Override protected void onScrollChanged(int x, int y, int oldx, int oldy) { super.onScrollChanged(x, y, oldx, oldy); if (mScrollChangedListener != null) mScrollChangedListener.onScrollChanged(x, y, oldx, oldy); } } 

Therefore, replace ScrollView in your layout with com.your.package.UpdatingScrollView .

In your fragment / event where the UpdatingScrollView parameter is defined, you set the scroll listener and update the bottom edge of the image based on the scroll offset. For every 2 pixels of scroll scrolling, you want to update the bottom margin by -1 pixel, which will cause the image to move up the screen at half the speed of the rest of the content.

So something like this:

 scrollView.setOnScrollChangedListener(new OnScrollChangedListener() { @Override public void onScrollChanged(int x, int y, int oldx, int oldy) { // I think y will be negative when scrolled if(y >= -image.getHeight()) { RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) image.getLayoutParams(); lp.setMargins(0, 0, 0, y / 2); image.setLayoutParams(lp); } } }); 
+1
source

Source: https://habr.com/ru/post/981269/


All Articles