2017-07-13 76 views
1

我正在开发一个Android项目,作为一名初级开发人员,我仍然在学习,因为我有一点设计问题,并想知道是否有人能够启发我。设置项目Alpha相对于水平中心的位置RecyclerView

我必须在水平列表上显示项目,我使用RecyclerView来完成,我一次只能在屏幕上显示三个项目(一个居中,两个部分可见),并且我始终保持一个该中心感谢LinearSnapHelper。我遇到的问题是,侧面的物品需要比中间的物品低0.5(比较1)。理想情况下,我希望让他们渐渐淡出,并逐渐滚动,但我完全不知道该如何执行此操作。

Horrible mockup here

有没有干净的方式做到这一点?

非常感谢你:)

回答

1

如果您RecyclerView的背景是纯色,即默认的活动背景色或白色,一个非常简单的方法是用半透明渐变绘制衰落叠加回收站从侧面的〜50%不透明的明亮颜色到中间的完全透明的颜色。这会产生这样的错觉,即在移动物品时这些物品实际上正在消失。

但是创建复杂的渐变是不容易在绘制XML:你可以只创建一个水平三色渐变

<shape 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="rectangle"> 
    <gradient 
     android:startColor="#55FFFFFF" 
     android:centerColor="#00FFFFFF" 
     android:endColor="#55FFFFFF"/> 
</shape> 
<!-- replace FFFFFF with the actual background color 
    and adjust the first two hexadecimal digits for the 
    overlay transparency (00 is transparent -> FF is opaque) --> 

,但可能这个梯度将涵盖太多的中心元素,将是烦人。

中间部分的覆盖层必须完全透明,梯度应从中央视图占用的空间外部开始。这可以通过重叠两个渐变来实现:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item 
     android:gravity="left" 
     android:right="200dp"> 
     <shape android:shape="rectangle"> 
      <gradient 
       android:type="linear" 
       android:startColor="#55FFFFFF" 
       android:endColor="#00FFFFFF"/> 
     </shape> 
    </item> 
    <item 
     android:left="200dp" 
     android:gravity="right"> 
     <shape android:shape="rectangle"> 
      <gradient 
       android:type="linear" 
       android:startColor="#55FFFFFF" 
       android:endColor="#AAFFFFFF"/> 
     </shape> 
    </item> 
</layer-list> 

图层列表是在Android绘图中创建多个渐变的唯一方法。 android:right="200dp"android:left="200dp"是每个渐变结束与视图的相对边界之间的距离。简而言之,如果用一个侧面物品+中央物品占据的空间替换200dp,则中间的空间将保持透明,因为它上面没有渐变。
在XML中设置RecyclerViewandroid:foreground=""属性中的这两个渐变可绘制对象之一,并查看它是否可用。

的编程方法意味着设定RecyclerViewOnScrollListener或者创建自定义LinearLayoutManager它覆盖scrollHorizontallyBy(),这样的事情:

public void updateChildrenAlpha() { 
    for (int i = 0; i < getChildCount(); i++) { 
     View child = getChildAt(i); 
     float maxDist = /* distance where alpha is min */; 
     float right = getDecoratedRight(child); 
     float left = getDecoratedLeft(child); 
     float childCenter = left + (right - left)/2; // Get item center position 
     float center = getWidth()/2; // Get RecyclerView's center position 
     child.setAlpha((Math.abs(center - childCenter) - maxDist)/maxDist); 
     // Map between 0f and 1f the abs value of the distance 
     // between the center of item and center of the RecyclerView 
     // and set it as alpha 
    } 
} 

@Override 
public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) { 
    updateChildrenAlpha(); 
    return super.scrollHorizontallyBy(dx, recycler, state); 
} 

@Override 
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) { 
    super.onLayoutChildren(recycler, state); 
    updateChildrenAlpha(); 
} 
+0

非常感谢您!尽管我使用maxDist - Math.abs(center - childCenter)作为setAlpha,但我采用了编程方法。其余的完美工作,只有我遇到的问题是在初始加载,scrollHorizo​​ntallyBy仅在执行滚动时调用 –

+0

很高兴我能帮上忙!你是对的,我忘了初始加载,编辑了答案。 – Umbo

+0

完美!再次感谢^^ –

相关问题