问题
I would like to achieve a layout that looks like the "desired" image as part of the initial app state that informs the user of some basic actions. Right now I'm getting the "actual" image.
I need to have a background image of any drawable/image that has an overlay that is slanted from lower-left to upper-right and of any color. This also has to be scalable in terms of the same shape over any number of devices, phones or tablets and support back to SDK 16.
So far I've been going off the idea of using a vector image to create the slant drawable and then overlay that on top of the background image using a FrameLayout
for the layering effect. I'm not sure if this is the best way to accomplish this but I'd like the overlay drawable to be a vector drawable or a nine-patch so it doesn't pixelate on wider layouts.
layout/view_layout.xml
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/background_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/bg_image"/>
<View
android:layout_width="match_parent"
android:layout_height="52dp"
android:layout_gravity="bottom"
android:background="@drawable/overlay"/>
</FrameLayout>
drawable/overlay.xml
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp" android:height="36dp"
android:viewportWidth="48" android:viewportHeight="36">
<path
android:fillColor="#fff"
android:pathData="M48,0 L48,36 L0,36 L0,32 Z"/>
</vector>
If anyone knows how to add a drop shadow to a vector drawable (I haven't been able to find a way) or if there is a better approach to this, any help or suggestion would be much appreciated. Thanks!
回答1:
What I ended up doing to solve this was extending the ImageView
class and adding custom draw logic to overlay the Image. It's not using a Vector Drawable like I had hoped but it does present the exact effect that I was hoping for. Here's a basic outline of my class:
public class CoveredImageView extends ImageView {
static float DENSITY = 1f;
static final float SHADOW_DISTANCE = 10f;
static final int SHADOW_COLOR = 0xAA000000;
Path path;
Paint paint;
Point p1, p2, p3;
public CoveredImageView(Context context) {
this(context, null);
}
public CoveredImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CoveredImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
void init(@NonNull Context context) {
DENSITY = context.getResources().getDisplayMetrics().density;
path = new Path();
paint = new Paint();
p1 = new Point();
p2 = new Point();
p3 = new Point();
// Required to make the ShadowLayer work properly
setLayerType(LAYER_TYPE_SOFTWARE, null);
}
void updateDrawVariables() {
int shadowSize = (int)(SHADOW_DISTANCE * DENSITY);
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
paint.setShadowLayer(shadowSize, 0, -1, SHADOW_COLOR);
// Offset the actual position by the shadow size so
int left = 0 - shadowSize;
int right = getMeasuredWidth() + shadowSize;
int bottom = getMeasuredHeight();
p1.set(left, bottom);
p2.set(right, bottom - (int)(52 * DENSITY));
p3.set(right, bottom);
path.setFillType(Path.FillType.EVEN_ODD);
path.moveTo(p1.x, p1.y);
path.lineTo(p2.x, p2.y);
path.lineTo(p3.x, p3.y);
// Move the path shape down so that the shadow doesn't "fade" at the left and right edges
path.lineTo(p3.x, p3.y + shadowSize);
path.lineTo(p1.x, p1.y + shadowSize);
path.close();
}
@Override
public void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
// Update all the drawing variables if the layout values have changed
if(changed) {
updateDrawVariables();
}
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Paint the current path values that were set after onLayout()
canvas.drawPath(path, paint);
}
}
来源:https://stackoverflow.com/questions/42165130/create-vector-drawable-with-drop-shadow-to-overlay-an-image