gpt4 book ai didi

android - 滚动时的 Imageview 视差

转载 作者:可可西里 更新时间:2023-11-01 18:49:41 28 4
gpt4 key购买 nike

我看到很多例子说明视差背景当你滚动或 ListView 视差但是我找不到一个清楚的例子如何在你滚动 Activity 时对图像实现视差效果。

可以在 Airbnb 应用程序中找到示例实现。向下滚动时,您可以看到更多图片底部,向上滚动时,您可以看到更多图片顶部。

关于如何创建这种效果有什么提示和技巧吗?

enter image description here enter image description here

最佳答案

有一些库可以产生视差效果,这取决于您的应用程序是否对您的特定情况有用,例如:

Google 是您的好 friend ;) 如果这些都不符合您的需求,那么您必须创建一个自定义的 ScrollView 但这是一个较长的故事,请先尝试一下并发布您的结果。

编辑

如果这些都不符合您的要求,那么您必须这样做:

首先,创建一个自定义的 ScrollView,这样您就可以监听滚动变化。

public class ObservableScrollView extends ScrollView {

public interface OnScrollChangedListener {
public void onScrollChanged(int deltaX, int deltaY);
}

private OnScrollChangedListener mOnScrollChangedListener;

public ObservableScrollView(Context context) {
super(context);
}

public ObservableScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}

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

@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if(mOnScrollChangedListener != null) {
mOnScrollChangedListener.onScrollChanged(l - oldl, t - oldt);
}
}

public void setOnScrollChangedListener(OnScrollChangedListener listener) {
mOnScrollChangedListener = listener;
}
}

显然,您需要在布局中使用它而不是默认的 ScrollView:

<your.app.package.ObservableScrollView
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent">

此外,您还需要将 ImageView 包装在一个容器中,以使视差起作用:

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

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

最后将您的 Activity 设置为您全新的 ObservableScrollView 的监听器并让视差开始:

public class MyActivity extends Activity implements ObservableScrollView.OnScrollChangedListener {
private ObservableScrollView mScrollView;
private View imgContainer;
@Override
public void onCreate(Bundle savedInstanceState) {
// Init your layout and set your listener
mScrollView = (ObservableScrollView)findViewById(R.id.scroll_view);
mScrollView.setOnScrollChangedListener(this);
// Store the reference of your image container
imgContainer = findViewById(R.id.img_container);
}

@Override
public void onScrollChanged(int deltaX, int deltaY) {
int scrollY = mScrollView.getScrollY();
// Add parallax effect
imgContainer.setTranslationY(scrollY * 0.5f);
}
}

您可以根据需要多少视差修改 0.5 值。

编辑

如果您的 ImageView 位于 Activity 的顶部,则上述答案可以正常工作。我在下面发布了一些代码来添加功能,使 ImageView 在我成功工作的 Activity 布局中的任何位置。这些是通用计算(可能有一些错误),稍作调整就可以让它适用于您自己的情况。

对于这个例子,我有一个固定高度的图像容器 200dp 和图像 240dp。主要目的是当图像容器位于屏幕中间时没有视差效果,并且当用户向上或向下滚动以应用效果时。因此,随着图像容器靠近屏幕顶部或屏幕底部,将应用更多的视差效果。以下计算通过阅读它们有点难以理解,因此尝试在纸上用实数做一个例子。

public class MyActivity extends Activity implements ObservableScrollView.OnScrollChangedListener {
private ObservableScrollView mScrollView;
private View imgContainer;
private ImageView mImageView;
@Override
public void onCreate(Bundle savedInstanceState) {
// Init your layout and set your listener
mScrollView = (ObservableScrollView)findViewById(R.id.scroll_view);
mScrollView.setOnScrollChangedListener(this);
// Store the reference of your image container
imgContainer = findViewById(R.id.img_container);
// Store the reference of your image
mImageView = findViewById(R.id.img);
}

@Override
public void onScrollChanged(int deltaX, int deltaY) {
// Get scroll view screen bound
Rect scrollBounds = new Rect();
mScrollView.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)) {
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics ();
display.getMetrics(outMetrics);
// Get screen density
float density = getResources().getDisplayMetrics().density;

// Get screen height in pixels
float dpHeight = outMetrics.heightPixels / density;
int screen_height_pixels = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpHeight, getResources().getDisplayMetrics());
int half_screen_height = screen_height_pixels/2;

// Get image container height in pixels
int container_height_pixels = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 200, getResources().getDisplayMetrics());

// Get the location that consider a vertical center for the image (where the translation should be zero)
int center = half_screen_height - (container_height_pixels/2);

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

// 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%
int final_loc = ((loc_screen[1]-center)*100)/half_screen_height;

// translate the inner image taking consideration also the density of the screen
mImageView.setTranslationY(-final_loc * 0.4f * density);
}
}
}

我希望它可以帮助正在寻找类似功能的人。

关于android - 滚动时的 Imageview 视差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26990195/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com