【问题标题】:Set a drawable drawn programmatically on top of the ImageView设置在 ImageView 顶部以编程方式绘制的可绘制对象
【发布时间】:2016-01-08 00:21:26
【问题描述】:

我有一个可绘制对象,我希望将它绘制在 ImageView 上方。现在不是:

我是这样在 FrameLayout 上设置的:

BubbleDrawable bubbleDrawable = new BubbleDrawable(true);
bubbleLayout.setBackgroundDrawable(bubbleDrawable);

但这无济于事。两者都没有帮助:

bubbleLayout.bringToFront();
bubbleLayout.invalidate();
bubbleLayout.requestLayout();

我也尝试从这里回答但没有用 - ImageView 什么也没显示https://stackoverflow.com/a/16370226/3937738

可绘制对象:

package com.example.chat.view;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.Log;

public class BubbleDrawable extends Drawable {

  private Paint mPaint;

  private float mBoxWidth;
  private float mBoxHeight;
  private Rect mBoxPadding = new Rect();

  private float mPointerWidth;
  private float mPointerHeight;
  private boolean my;
  private float strokeWidth;
  private int strokeColor;
  private int fillColor;
  private static final String TAG = "BubbleDrawable";

  public BubbleDrawable(boolean my) {
    this.my = my;
    initBubble();
  }

  private void initBubble() {
    setPointerSizes(25);
  }

  @Override
  public void draw(Canvas canvas) {
    Log.d(TAG, "draw");
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    fillBubble(canvas);
    drawBubbleStroke(canvas);
    //drawTriangle(canvas, my);
  }

  private void drawBubbleStroke(Canvas canvas) {
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeWidth(strokeWidth);
    //mPaint.setColor(strokeColor);
    mPaint.setColor(Color.RED);
    drawPath(canvas);
  }

  private void fillBubble(Canvas canvas) {
    mPaint.setStyle(Paint.Style.FILL);
    mPaint.setColor(fillColor);
    drawPath(canvas);
  }

  private void drawPath(Canvas canvas) {
    Rect bounds = getBounds();
    Path path = new Path();

    //right arrow
    path.moveTo(mBoxWidth, mBoxHeight / 2 - mPointerWidth / 2);
    path.lineTo(mBoxWidth + mPointerHeight, mBoxHeight / 2);
    path.lineTo(mBoxWidth, mBoxHeight / 2 + mPointerWidth / 2);

    //right vertical lower line.
    path.lineTo(mBoxWidth, mBoxHeight - mPointerWidth / 2);

    //bottom right arc.
    path.arcTo(new RectF(mBoxWidth - mPointerWidth, bounds.bottom - mPointerWidth, mBoxWidth, bounds.bottom), 0, 90);

    //bottom horizontal line.
    path.lineTo(mPointerWidth / 2, mBoxHeight);

    //bottom left arc.
    path.arcTo(new RectF(0, mBoxHeight - mPointerWidth, mPointerWidth, mBoxHeight), 90, 90);

    //left vertical line.
    path.lineTo(0, mPointerWidth);

    //top left arc.
    path.arcTo(new RectF(0, 0, mPointerWidth, mPointerWidth), 180, 90);

    //top horizontal line
    path.lineTo(mBoxWidth - mPointerWidth / 2, 0);

    //top right arc
    path.arcTo(new RectF(mBoxWidth - mPointerWidth, 0, mBoxWidth, mPointerWidth), 270, 90);

    //right vertical upper line.
    path.lineTo(mBoxWidth, mPointerWidth / 2);

    path.close();
    path.setFillType(Path.FillType.EVEN_ODD);
    if(!my)
      rotatePath(path);
    canvas.drawPath(path, mPaint);
  }

  private void rotatePath(Path path) {
    Matrix mMatrix = new Matrix();
    RectF bounds = new RectF();
    path.computeBounds(bounds, true);
    mMatrix.postRotate(180, bounds.centerX(), bounds.centerY());
    path.transform(mMatrix);
  }

  @Override
  public int getOpacity() {
    return PixelFormat.OPAQUE;
  }

  @Override
  public void setAlpha(int alpha) {
    // TODO Auto-generated method stub
  }

  @Override
  public void setColorFilter(ColorFilter cf) {
    // TODO Auto-generated method stub
  }

  @Override
  public boolean getPadding(Rect padding) {
    Log.d(TAG, "getPadding " + padding.bottom + ", " + padding.top);
    padding.set(mBoxPadding);

    return true;
  }

  @Override
  protected void onBoundsChange(Rect bounds) {
    mBoxWidth = bounds.width() - mPointerHeight;
    mBoxHeight = getBounds().height();
    super.onBoundsChange(bounds);
  }

  public void setPointerSizes(int pointerWidth) {
    mPointerWidth = pointerWidth;
    mPointerHeight = (float) Math.sqrt((double) (pointerWidth * pointerWidth / 2)); //  base of equilateral triangle
    Log.d(TAG, "mPointerHeight " + mPointerHeight);
  }

  public void setPadding(int left, int top, int right, int bottom) {
    Log.d(TAG, "setPadding");
    mBoxPadding.left = left;
    mBoxPadding.top = top;
    mBoxPadding.right = right;
    mBoxPadding.bottom = bottom;
  }

  public void setPointerSizes(int pointerWidth, int pointerHeight) {
    mPointerWidth = pointerWidth;
    mPointerHeight = pointerHeight;
  }

  public void setFillColor(int fillColor) {
    //Log.d(TAG, "setFillColor");
    this.fillColor = fillColor;
  }

  public void setStrokeColor(int strokeColor) {
    this.strokeColor = strokeColor;
  }

  public void setStrokeWidth(float strokeWidth) {
    this.strokeWidth = strokeWidth;
  }
}

部分布局:

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingRight="5dp"
        android:adjustViewBounds="true"
        android:scaleType="centerCrop"/>

</FrameLayout>

【问题讨论】:

  • 将另一个 ImageView 放在第一个之上并在其中绘制?或者只是在 ImageView 中添加一些上边距并在容器上绘制。

标签: java android drawable


【解决方案1】:

也许只需在 RelativeLayout 内的 xml 文件中创建 2 个 ImageView 并将一个放在另一个之上。

【讨论】:

    猜你喜欢
    • 2011-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多