Android - Нажмите, чтобы стереть части переднего плана ImageView, чтобы выставить фоновый вид - PullRequest
0 голосов
/ 22 ноября 2011

Так что я боролся с этим большую часть дня.Предположим, у меня есть пользовательский ImageView, который я хочу наложить на фоновое представление (оба в пределах RelativeLayout), которое при касании стирает части исходного растрового изображения представления, подобно инструменту стирания в MS Paint, открывая представление под ним.Я проверил почти все потоки (например, этот ), и они предлагают использовать PorterDuff SRC Mode в объекте Paint, а также создать Canvas из теневой копии ARGB_8888 исходной растровой карты дляприменить маскировку.

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

Каждый раз, когда я переопределяю onDraw, когда я применяю стирание к растровому изображению IV, он отображает черный фон вместо вида под ним, даже если я установил прозрачный фон.Так что я в своей последней веревке относительно того, что нужно сделать, чтобы раскрыть фоновое представление.

Вот что у меня есть до сих пор:

конструктор представления:

    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));  
    paint.setColor(Color.TRANSPARENT);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeJoin(Paint.Join.ROUND);
    paint.setStrokeWidth(STROKE_WIDTH);
    paint.setAntiAlias(true);

переопределил setImageBitmap для установки моего холста из моего переконфигурированного исходного растрового изображения:

public void setImageBitmap(Bitmap bitmap){
    super.setImageBitmap(bitmap);
    Drawable bd = getDrawable();
    if(bd == null){
        return;
    }

    Bitmap fullSizeBitmap = ((BitmapDrawable) bd).getBitmap();
    overlay = fullSizeBitmap.copy(Config.ARGB_8888, true);
    c2 = new Canvas(overlay);
}

метод onDraw:

protected void onDraw(Canvas canvas) {
    /*
     * Override paint call by re-drawing the view's Bitmap first, then overlaying our path on top of it
     */
    Drawable bd = getDrawable();
    if(bd == null){
        return;
    }
    Bitmap fullSizeBitmap = ((BitmapDrawable) bd).getBitmap();
    if(fullSizeBitmap != null && c2 != null){
        canvas.drawColor(Color.TRANSPARENT);
        c2.drawBitmap(fullSizeBitmap, 0, 0, null);
        c2.drawPath(path, paint);
        canvas.drawBitmap(overlay, 0, 0, null);
    }
}

Ответы [ 2 ]

1 голос
/ 21 марта 2017

Можете ли вы попробовать это решение, оно поможет вам стереть изображения в Android на ощупь .. Или загрузить демонстрационный пример

public class MainActivity extends Activity {

    Bitmap bp;
    Canvas bitmapCanvas;
    DrawView drawImg;
    LinearLayout ln1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        ln1 = (LinearLayout) findViewById(R.id.ln1);
        drawImg = new DrawView(this);
        ln1.addView(drawImg);

    }



    public class DrawView extends View implements View.OnTouchListener {

        private int x = 0;
        private int y = 0;

        Bitmap bitmap;
        Path circlePath;
        Paint circlePaint;

        private final Paint paint = new Paint();
        private final Paint eraserPaint = new Paint();


        public DrawView(Context context){
            super(context);
            setFocusable(true);
            setFocusableInTouchMode(true);
            this.setOnTouchListener(this);

            // Set background
            this.setBackgroundColor(Color.CYAN);
            bp = BitmapFactory.decodeResource(getResources(), R.drawable.bg);

            // Set bitmap
            bitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);
            bitmapCanvas = new Canvas();
            bitmapCanvas.setBitmap(bitmap);
            bitmapCanvas.drawColor(Color.TRANSPARENT);
            bitmapCanvas.drawBitmap(bp, 0, 0, null);

            circlePath = new Path();
            circlePaint = new Paint();
            circlePaint.setAntiAlias(true);
            circlePaint.setColor(Color.BLUE);
            circlePaint.setStyle(Paint.Style.STROKE);
            circlePaint.setStrokeJoin(Paint.Join.MITER);
            circlePaint.setStrokeWidth(4f);

            // Set eraser paint properties
            eraserPaint.setAlpha(0);
            eraserPaint.setStrokeJoin(Paint.Join.ROUND);
            eraserPaint.setStrokeCap(Paint.Cap.ROUND);
            eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
            eraserPaint.setAntiAlias(true);

        }

        @Override
        public void onDraw(Canvas canvas) {

            canvas.drawBitmap(bitmap, 0, 0, paint);
            bitmapCanvas.drawCircle(x, y, 30, eraserPaint);

            canvas.drawPath(circlePath, circlePaint);
        }

        public boolean onTouch(View view, MotionEvent event) {
            x = (int) event.getX();
            y = (int) event.getY();

            bitmapCanvas.drawCircle(x, y, 30, eraserPaint);

            circlePath.reset();
            circlePath.addCircle(x, y, 30, Path.Direction.CW);

            int ac=event.getAction();
            switch(ac){
                case MotionEvent.ACTION_UP:
                    Toast.makeText(MainActivity.this, String.valueOf(x), Toast.LENGTH_SHORT).show();
                    circlePath.reset();
                    break;
            }
            invalidate();
            return true;
        }
    }
}
1 голос
/ 26 февраля 2013

Я знаю, что это действительно старый вопрос, но вот что я сделал, чтобы исправить подобную проблему, которая у меня была.Возможно, это поможет кому-то в будущем.

Начиная с уровня API 11 и выше, вы должны указать этот кусок кода для ImageView, чтобы раскрыть изображение сзади, а не черную область.

if (Build.VERSION.SDK_INT >= 11) {
    imageview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}

Это помогло мне успешно отобразить заднее изображение

...