滚动时 Recyclerview 高度逐渐变化
Recyclerview elevation progressively changes when scrolling
我有一个 recyclerview
,我已经添加了一个 elevation
。似乎高度会随着项目在屏幕上的垂直位置而变高,阴影会随着项目向下滚动而增加。我试过添加背景颜色,但没有用。我找到了另一个 post,其中包含显示该问题的视频。 https://youtu.be/nROYq8rpUMs
这是我添加海拔的相对布局。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#EDEDED"
android:focusable="?attr/selectableItemBackground"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:id="@+id/newsRowRelativeLayout"
android:elevation="4dp">
<ImageView
android:id="@+id/newsImage"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:maxHeight="300dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="15dp"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
android:background="@color/mainTextBGColor" />
<TextView
android:id="@+id/newsTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:layout_below="@id/newsType"
android:textStyle="bold"
android:textColor="@color/news_title"
android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin"
android:textSize="@dimen/news_title_main" />
<TextView
android:id="@+id/newsType"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:layout_below="@id/newsImage"
android:textStyle="bold"
android:textAllCaps="true"
android:layout_marginTop="5dp"
android:layout_marginBottom="10dp"
android:textColor="@color/mainBGColor"
android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin"
android:textSize="@dimen/news_tag_detailed" />
<TextView
android:id="@+id/newsText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/newsTitle"
android:background="@android:color/transparent"
android:ellipsize="end"
android:maxLines="3"
android:textColor="@color/news_text"
android:layout_marginTop="10dp"
android:layout_marginBottom="5dp"
android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin"
android:textSize="@dimen/news_text_main"/>
</RelativeLayout>
没什么问题。 Elevation 效果使用所谓的 Key-Light 和 Ambient-Light。一个位于屏幕正上方(环境光),另一个(主光)在屏幕上方呈 45° 角。这就是为什么滚动时阴影会移动的原因。
tl;博士
阴影不是静态的,而是动态计算的。另见下图解释概念:
我发布的不是最终解决方案,而是我正在处理的草稿。
我了解Android的海拔理论,但这对我来说没有任何意义,所以我的想法是听屏幕上内容的滚动并根据它调整海拔.
public class VerticalScrollListener extends RecyclerView.OnScrollListener {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int[] visible = new int[1];
mLayoutManager.findFirstVisibleItemPositions(visible);
int[] lastvisible = new int[1];
mLayoutManager.findLastVisibleItemPositions(lastvisible);
for (int i = visible[0]; i<lastvisible[0]; i++){
RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(i);
int[] location = new int[2];
((MessageViewHolder)viewHolder).contentView.getLocationOnScreen(location);
float y = location[1];
float ratio = y/scheight;
((MessageViewHolder)viewHolder).contentView.setElevation(16-14*ratio);
}
}
@Override
public void onScrollStateChanged(final RecyclerView recyclerView, final int newState) {
super.onScrollStateChanged(recyclerView, newState);
}}
我有一个 recyclerview
,我已经添加了一个 elevation
。似乎高度会随着项目在屏幕上的垂直位置而变高,阴影会随着项目向下滚动而增加。我试过添加背景颜色,但没有用。我找到了另一个 post,其中包含显示该问题的视频。 https://youtu.be/nROYq8rpUMs
这是我添加海拔的相对布局。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#EDEDED"
android:focusable="?attr/selectableItemBackground"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:id="@+id/newsRowRelativeLayout"
android:elevation="4dp">
<ImageView
android:id="@+id/newsImage"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:maxHeight="300dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="15dp"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
android:background="@color/mainTextBGColor" />
<TextView
android:id="@+id/newsTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:layout_below="@id/newsType"
android:textStyle="bold"
android:textColor="@color/news_title"
android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin"
android:textSize="@dimen/news_title_main" />
<TextView
android:id="@+id/newsType"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:layout_below="@id/newsImage"
android:textStyle="bold"
android:textAllCaps="true"
android:layout_marginTop="5dp"
android:layout_marginBottom="10dp"
android:textColor="@color/mainBGColor"
android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin"
android:textSize="@dimen/news_tag_detailed" />
<TextView
android:id="@+id/newsText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/newsTitle"
android:background="@android:color/transparent"
android:ellipsize="end"
android:maxLines="3"
android:textColor="@color/news_text"
android:layout_marginTop="10dp"
android:layout_marginBottom="5dp"
android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin"
android:textSize="@dimen/news_text_main"/>
</RelativeLayout>
没什么问题。 Elevation 效果使用所谓的 Key-Light 和 Ambient-Light。一个位于屏幕正上方(环境光),另一个(主光)在屏幕上方呈 45° 角。这就是为什么滚动时阴影会移动的原因。
tl;博士 阴影不是静态的,而是动态计算的。另见下图解释概念:
我发布的不是最终解决方案,而是我正在处理的草稿。
我了解Android的海拔理论,但这对我来说没有任何意义,所以我的想法是听屏幕上内容的滚动并根据它调整海拔.
public class VerticalScrollListener extends RecyclerView.OnScrollListener {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int[] visible = new int[1];
mLayoutManager.findFirstVisibleItemPositions(visible);
int[] lastvisible = new int[1];
mLayoutManager.findLastVisibleItemPositions(lastvisible);
for (int i = visible[0]; i<lastvisible[0]; i++){
RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(i);
int[] location = new int[2];
((MessageViewHolder)viewHolder).contentView.getLocationOnScreen(location);
float y = location[1];
float ratio = y/scheight;
((MessageViewHolder)viewHolder).contentView.setElevation(16-14*ratio);
}
}
@Override
public void onScrollStateChanged(final RecyclerView recyclerView, final int newState) {
super.onScrollStateChanged(recyclerView, newState);
}}