Применить пользовательскую маску к ImageView - PullRequest
0 голосов
/ 03 июля 2019

Я хочу настроить свой ImageView так: enter image description here

Я пробовал разные подходы, такие как использование форм через xml или OutlineProvider. Ни один из них не сработал в этом случае.

На данный момент я написал CustomImageView, который рисует круг следующим образом:

enter image description here

class HeaderImageView : AppCompatImageView {

    @SuppressLint("CanvasSize")
    override fun onDraw(canvas: Canvas) {
        val halfWidth = (canvas.width / 2).toFloat()
        val radius = height.toFloat()
        val path = Path().apply {
            addCircle(halfWidth, 0f, radius, Path.Direction.CCW)
        }

        canvas.clipPath(path)

        super.onDraw(canvas)
    }
}

Как мне манипулировать путем, чтобы получить желаемый результат?

Спасибо!

редактирование:

Для ясности, у меня есть изображение, которым я хочу "манипулировать", а не цвет.

Добавлен xml:

    <.HeaderImageView
        android:layout_width="match_parent"
        android:layout_height="230dp"
        android:fitsSystemWindows="false"
        android:scaleType="centerCrop"
        android:src="@drawable/bg"
        app:layout_collapseMode="parallax" />

Ответы [ 3 ]

0 голосов
/ 03 июля 2019

Я рисую круглую форму, используя Path. И использовать какой-то механизм для подгонки изображения в круглой части.

Я сделал с помощью Path. Проверьте это.

public class RoundedView extends AppCompatImageView {
private Bitmap mBitmap;
Path mPath;
float width, height, offset;
float percent = 0.37f;
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);


public RoundedView(Context context) {
    super(context);
}

public RoundedView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    init(context, attrs);
}

public RoundedView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init(context, attrs);
}

private void init(Context context, AttributeSet attrs) {
    TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.RoundedView);
    percent = arr.getFloat(R.styleable.RoundedView_roundPercent, 0.37f);
    arr.recycle();
}

@Override
protected void onDraw(Canvas canvas) {
    if (mPath != null) {
        canvas.drawPath(mPath, mPaint);
    }
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    width = w;
    height = h;

    offset = w / 2f;

    change();

}

private void change() {
    float roundness = percent * height;


    Drawable d = getDrawable();
    if (d != null) {

        mBitmap = drawableToBitmap(d);
        mBitmap = Bitmap.createScaledBitmap(mBitmap, (int) width, (int) height, false);

        final Shader shader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        mPaint.setShader(shader);

        mPath = new Path();
        mPath.moveTo(0, 0);
        mPath.lineTo(width, 0);
        mPath.lineTo(width, height - roundness);
        mPath.quadTo(offset, height + roundness, 0, height - roundness);
        mPath.close();
    }
}

@Override
public void setImageDrawable(@Nullable Drawable drawable) {
    super.setImageDrawable(drawable);

    change();

}

public Bitmap drawableToBitmap(Drawable drawable) {
    Bitmap bitmap = null;

    if (drawable instanceof BitmapDrawable) {
        BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
        if (bitmapDrawable.getBitmap() != null) {
            return bitmapDrawable.getBitmap();
        }
    }

    if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
        bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
    } else {
        bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
    }

    Canvas canvas = new Canvas(bitmap);
    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    drawable.draw(canvas);
    return bitmap;
}
}
0 голосов
/ 04 июля 2019

Спасибо за ответы, которые наверняка пригодятся другим пользователям.К сожалению, мне пришлось помочь себе получить желаемые результаты.

Это мое окончательное решение, которое применяет четырехугольник Безье к ImageView.

class HeaderImageView : AppCompatImageView {
    constructor(context: Context?) : super(context) {
        init()
    }

    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
        init()
    }

    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
        init()
    }

    lateinit var paint: Paint

    private fun init() {
        paint = Paint()
        paint.color = Color.WHITE
        paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP)
        paint.style = Paint.Style.FILL
    }

    @SuppressLint("CanvasSize")
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        val fHeight = canvas.height.toFloat()
        val startEndHeight = canvas.height / 1.18f
        val fWidth = canvas.width.toFloat()
        val halfWidth = (fWidth / 2)

        val path = Path()
        //X = Left side, Y = close to bottom
        val ptStart = PointF(0f, startEndHeight)
        //X = Middle, Y = Bottom
        val ptMiddle = PointF(halfWidth, fHeight + 95)
        // X = Right Side, Y = close to bottom
        val ptEnd = PointF(fWidth, startEndHeight)

        path.moveTo(ptStart.x, ptStart.y)
        path.quadTo(ptMiddle.x, ptMiddle.y, ptEnd.x, ptEnd.y)
        path.lineTo(fWidth, fHeight)
        path.lineTo(0f, fHeight)

        path.close()

        canvas.drawPath(path, paint)
    }
}

enter image description here

0 голосов
/ 03 июля 2019

Вы можете сделать рисование вот так -

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:left="-20dp"
        android:right="-20dp">
        <shape xmlns:android="http://schemas.android.com/apk/res/android"
            android:shape="oval"
            android:useLevel="false">
            <solid android:color="#25454F" />
            <size
                android:width="200dp"
                android:height="60dp" />
        </shape>
    </item>
</layer-list>

И реализовать макет, как это -

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:background="#25454F"
        android:layout_marginBottom="55dp">
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:background="@drawable/semi_oval_image"
        android:layout_marginTop="55dp">
    </LinearLayout>

</RelativeLayout>
...