我有一个ListView,对于每个列表项,我希望它在它下面显示一个阴影。我正在使用Android棒棒糖的新提升功能来设置一个Z视图上,我想投射一个阴影,并且已经有效地与动作栏(技术上的棒棒糖工具栏)。我使用的是棒棒糖的抬高,但出于某种原因,它在列表项下没有显示阴影。下面是每个列表项的布局设置:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
style="@style/block"
android:gravity="center"
android:layout_gravity="center"
android:background="@color/lightgray"
>
<RelativeLayout
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:elevation="30dp"
>
<ImageView
android:id="@+id/documentImageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/alphared"
android:layout_alignParentBottom="true" >
<appuccino.simplyscan.Extra.CustomTextView
android:id="@+id/documentName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/white"
app:typeface="light"
android:paddingLeft="16dp"
android:paddingTop="8dp"
android:paddingBottom="4dp"
android:singleLine="true"
android:text="New Document"
android:textSize="27sp"/>
<appuccino.simplyscan.Extra.CustomTextView
android:id="@+id/documentPageCount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/white"
app:typeface="italic"
android:paddingLeft="16dp"
android:layout_marginBottom="16dp"
android:text="1 page"
android:textSize="20sp"/>
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
然而,下面是它如何显示列表项,没有阴影:
我也尝试过以下方法,但都无济于事:
将提升设置为ImageView和TextViews本身,而不是父布局。
应用了ImageView的背景。
使用TranslationZ代替Elevation。
如果你想有透明的背景和android:outlineProvider="bounds"不适合你,你可以创建自定义ViewOutlineProvider:
class TransparentOutlineProvider extends ViewOutlineProvider {
@Override
public void getOutline(View view, Outline outline) {
ViewOutlineProvider.BACKGROUND.getOutline(view, outline);
Drawable background = view.getBackground();
float outlineAlpha = background == null ? 0f : background.getAlpha()/255f;
outline.setAlpha(outlineAlpha);
}
}
将这个提供者设置为你的透明视图:
transparentView.setOutlineProvider(new TransparentOutlineProvider());
来源:
https://code.google.com/p/android/issues/detail?id=78248#c13
(编辑)
Drawable. getalpha()的文档说它是特定于Drawable如何威胁alpha的。它可能总是返回255。
在这种情况下,你可以手动提供alpha:
class TransparentOutlineProvider extends ViewOutlineProvider {
private float mAlpha;
public TransparentOutlineProvider(float alpha) {
mAlpha = alpha;
}
@Override
public void getOutline(View view, Outline outline) {
ViewOutlineProvider.BACKGROUND.getOutline(view, outline);
outline.setAlpha(mAlpha);
}
}
如果你的视图背景是一个StateListDrawable,默认颜色为#DDFF0000,即alpha DDx0/FFx0 == 0.86
transparentView.setOutlineProvider(new TransparentOutlineProvider(0.86f));
我一直在棒棒糖上玩阴影,这是我发现的:
似乎父ViewGroup的边界由于某种原因切断了子ViewGroup的阴影;而且
使用android设置的阴影:elevation被视图的边界截断,而不是通过边缘延伸的边界;
让子视图显示阴影的正确方法是在父视图上设置padding,并在父视图上设置android:clipToPadding="false"。
根据我所知道的,以下是我对你的建议:
设置你的顶级RelativeLayout,让padding等于你在相对布局上设置的边缘,你想要显示阴影;
在相同的RelativeLayout上设置android:clipToPadding="false";
从同样设置了仰角的RelativeLayout中移除边缘;
[编辑]你可能还需要在需要提升的子布局上设置一个非透明的背景色。
在一天结束的时候,你的顶级相对布局应该是这样的:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
style="@style/block"
android:gravity="center"
android:layout_gravity="center"
android:background="@color/lightgray"
android:paddingLeft="40dp"
android:paddingRight="40dp"
android:paddingTop="20dp"
android:paddingBottom="20dp"
android:clipToPadding="false"
>
内部相对布局应该是这样的:
<RelativeLayout
android:layout_width="300dp"
android:layout_height="300dp"
android:background="[some non-transparent color]"
android:elevation="30dp"
>
我花了一个小时才想明白。在我的例子中,我有一个背景设置,但它被设置为一种颜色。这还不够,你需要将视图的背景设置为可绘制的。
如。
这不会有阴影:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="165dp"
android:background="@color/ight_grey"
android:elevation="20dp"
android:orientation="vertical"
/>
但是这个会
<LinearLayout
android:layout_width="match_parent"
android:layout_height="165dp"
android:background="@drawable/selector_grey"
android:elevation="20dp"
android:orientation="vertical"
/>
编辑:
还发现,如果你使用选择器作为背景,如果你没有设置角落,那么阴影不会显示在预览窗口中,但它会显示在设备上
例:在预览中没有阴影:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="@color/white" />
<stroke
android:width="1dp"
android:color="@color/grey"/>
</shape>
</item>
</selector>
但这确实是:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="@color/white" />
<corners android:radius="1dp" />
<stroke
android:width="1dp"
android:color="@color/grey"/>
</shape>
</item>
</selector>
如果你想有透明的背景和android:outlineProvider="bounds"不适合你,你可以创建自定义ViewOutlineProvider:
class TransparentOutlineProvider extends ViewOutlineProvider {
@Override
public void getOutline(View view, Outline outline) {
ViewOutlineProvider.BACKGROUND.getOutline(view, outline);
Drawable background = view.getBackground();
float outlineAlpha = background == null ? 0f : background.getAlpha()/255f;
outline.setAlpha(outlineAlpha);
}
}
将这个提供者设置为你的透明视图:
transparentView.setOutlineProvider(new TransparentOutlineProvider());
来源:
https://code.google.com/p/android/issues/detail?id=78248#c13
(编辑)
Drawable. getalpha()的文档说它是特定于Drawable如何威胁alpha的。它可能总是返回255。
在这种情况下,你可以手动提供alpha:
class TransparentOutlineProvider extends ViewOutlineProvider {
private float mAlpha;
public TransparentOutlineProvider(float alpha) {
mAlpha = alpha;
}
@Override
public void getOutline(View view, Outline outline) {
ViewOutlineProvider.BACKGROUND.getOutline(view, outline);
outline.setAlpha(mAlpha);
}
}
如果你的视图背景是一个StateListDrawable,默认颜色为#DDFF0000,即alpha DDx0/FFx0 == 0.86
transparentView.setOutlineProvider(new TransparentOutlineProvider(0.86f));