Создайте вектор для рисования с тенью, чтобы наложить изображение
Я хотел бы получить макет, который выглядит как "желаемое" изображение, как часть начального состояния приложения, которое информирует пользователя о некоторых основных действиях. Прямо сейчас я получаю "фактическое" изображение.
Мне нужно иметь фоновое изображение любого рисованного / изображения, которое имеет оверлей, который наклонен от нижнего левого до верхнего правого и любого цвета. Это также должно быть масштабируемым с точки зрения одинаковой формы для любого количества устройств, телефонов или планшетов и поддерживать обратно в SDK 16.
До сих пор я отказывался от идеи использовать векторное изображение для создания наклонной прорисовки, а затем наложить ее поверх фонового изображения, используя FrameLayout
для эффекта наслоения. Я не уверен, что это лучший способ для достижения этой цели, но я бы хотел, чтобы оверлей, который можно нарисовать, был векторным или с девятью патчами, чтобы он не пикселировал при более широких макетах.
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>
Если кто-то знает, как добавить тень на векторную графику (я не смог найти способ) или если есть лучший подход к этому, любая помощь или предложение будут высоко оценены. Спасибо!
1 ответ
То, что я в конечном итоге сделал, чтобы решить это, было расширение ImageView
класс и добавление пользовательской логики рисования для наложения изображения. Он не использует Vector Drawable, как я надеялся, но он дает именно тот эффект, на который я надеялся. Вот основная схема моего класса:
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);
}
}