简体   繁体   English

如何在Android中的滚动视图中将图像锚定到Imageview中的中心?

[英]How can I anchor an image to the center within an Imageview in a scrollview, in Android?

When I scroll within my Android scrollview, it scrolls down as it should. 当我在Android滚动视图中滚动时,它会向下滚动。

But I'd like the image within the imageview to anchor to the centre. 但我希望imageview中的图像能够锚定到中心。 So you always see the face of the person in the image as you scrolling up. 因此,当您向上滚动时,您总会看到图像中人物的脸部。

So far I have not been able to accomplish this 到目前为止,我还没有完成这个任务

A similar effect is created in the image below: 在下图中创建了类似的效果:

在此输入图像描述

Stockguy image: Stockguy图片:

在此输入图像描述

My code so far (which so far doesn't accomplish 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>

To achieve parallax effect like on image you posted try following code. 为了实现像你发布的图像上的视差效果,请尝试以下代码。 It is a very simple way. 这是一种非常简单的方式。

Layout: 布局:

<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 's top margin is equal to the ImageViews 's height. LinearLayout的上边距等于ImageViews的高度。

Listening scroll position of the ScrollView and changing position of ImageView : 侦听ScrollView滚动位置和更改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 it will help. 希望它会有所帮助。

I'd take a different approach with that. 我会采用不同的方法。

Try building 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 on the content layout and update the image size and alpha accordingly to get the effect you describe. 使用GestureDetector.SimpleOnGestureListener您可以检测用户何时滚动内容布局并相应地更新图像大小和alpha以获得您描述的效果。

I would implement this using a scroll callback on the ScrollView, this doesn't exist by default but is easy to create yourself by extending ScrollView: 我将使用ScrollView上的滚动回调来实现它,默认情况下这不存在,但通过扩展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);
    }
}

So replace ScrollView in your layout with com.your.package.UpdatingScrollView . 因此,使用com.your.package.UpdatingScrollView替换布局中的ScrollView。

In your Fragment/Activity where the UpdatingScrollView is defined you set the scroll listener and update the bottom margin of the image based on the scroll offset. 在Fragment / Activity中,其中定义了UpdatingScrollView,您可以设置滚动侦听器并根据滚动偏移更新图像的下边距。 For every 2 pixels the ScrollView has scrolled you'll want to update the bottom margin by -1 pixel which will make the image move up the screen at half the rate of the rest of the content. 对于ScrollView已滚动的每2个像素,您需要将底部边距更新为-1像素,这将使图像以其他内容的一半速率向上移动到屏幕上。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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