Android - 在更深层的现有视图之上精确绘制ImageView

时间:2016-07-16 07:14:34

标签: android view

这是一个难以描述的情况,所以请耐心等待。我被要求做一个教练标记'屏幕有点像这样:

enter image description here

然而,在我的情况下,我需要“拉”'前面的一些底层图像,并以不同的颜色显示它们,使它们脱颖而出。我无法确定'框架'这些图像将在运行时之前。我的方法是添加一个覆盖整个屏幕的黑色,半透明视图(我称之为“幕布”),然后添加我需要的图像作为不同颜色的幕布子视图。 EDIT 这部分很简单,我也不是在寻求帮助(这就是为什么这个建议问题的副本不正确的原因)。

我不相信我可以使用bringToFront()setTranslationZ(),因为这些方法不会将ImageView一直带到我的幕前。所以,我想要做的是获得确切的框架'相对于整个屏幕的图像视图(其x,y,宽度和高度),然后尝试使用相同的可绘制框架添加新的图像视图。

了解潜在的观点'同样重要。实际上是由多个视图(包括一个滑动抽屉)组成,这就是我需要获取相对于屏幕的坐标的原因。我希望这是有道理的。

我可以使用正确的颜色绘制新的ImageView作为窗帘的子视图,但图像的位置和大小是偏离的。如何在前一个ImageView之上绘制新的@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ... ViewTreeObserver vto = mRootview.getViewTreeObserver(); vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { mRootview.getViewTreeObserver().removeOnGlobalLayoutListener(this); mDrawerLayout.openDrawer(Gravity.LEFT); RelativeLayout curtain = addOpaqueCurtainToRootView(); int frame[] = getFrameOfExistingImageView(); addNewImageViewOnTopOfEverything(curtain, frame); } }); } private RelativeLayout addOpaqueCurtainToRootView() { RelativeLayout curtain = new RelativeLayout(context); RelativeLayout.LayoutParams curtainParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT); curtain.setLayoutParams(curtainParams); curtain.setBackgroundColor(Color.argb(179, 0, 0, 0)); //70% opaque mRootview.addView(curtain); return curtain; } private int[] getFrameOfExistingImageView() { // proving that I have a reference to the original image mCurrentImage.setColorFilter(Color.rgb(255, 0, 0)); int array[] = new int[2]; mCurrentImage.getLocationOnScreen(array); Log.d(TAG, "width: " + Integer.toString(array[0])); Log.d(TAG, "height: " + Integer.toString(array[1])); Log.d(TAG, "x: " + Float.toString(mCurrentImage.getX())); Log.d(TAG, "y: " + Float.toString(mCurrentImage.getY())); int frame[] = new int[4]; // x,y,width,height frame[0] = (int)mCurrentImage.getX(); frame[1] = (int)mCurrentImage.getY(); frame[2] = array[0]; frame[3] = array[1]; return frame; } private void addNewImageViewOnTopOfEverything(RelativeLayout curtain, int[] frame) { ImageView iv = new ImageView(context); iv.setImageResource(R.drawable.imgView); iv.setColorFilter(Color.rgb(255, 255, 255)); iv.setX(frame[0]); iv.setY(frame[1]); iv.setLayoutParams(new RelativeLayout.LayoutParams(frame[2], frame[3])); curtain.addView(iv); }

我也对其他策略持开放态度(因为这个策略似乎不起作用)。谢谢你的帮助。

Plugin::load('CakePdf', ['bootstrap' => true]);
Configure::write('CakePdf', [
'engine' => [
    'className' => 'CakePdf.WkHtmlToPdf',
    'binary' => __DIR__ . '/../plugins/wkhtmltox/bin/wkhtmltopdf',
    'options' => [
        'print-media-type' => false,
        'outline' => true,
        'dpi' => 96
    ],
],]);

1 个答案:

答案 0 :(得分:0)

我想出来了。我有两个基本问题。

首先,我得到了ImageView所有错误的框架。我需要在绘制后获得左侧和顶部坐标以及图像的高度和宽度。这就是我这样做的方式(我实际上转换为左,上,右,下,但其余的很容易):

private int[] getFrameOfImageView(ImageView imageView) {

    int array[] = new int[2];
    imageView.getLocationOnScreen(array);

    int frame[] = new int[4];

    frame[0] = array[0]; // left
    frame[1] = array[1]; // top
    frame[2] = array[0] + imageView.getWidth(); // right
    frame[3] = array[1] + imageView.getHeight(); // bottom

    return frame;
}

然后,我创建了一个新类来进行绘图。这是我OP的最大区别。最初,我认为我可以将其添加为新ImageView并将其设置为LayoutParams以将其放置在我想要的位置。相反,我最后使用PaintCanvas进行绘图,尺寸调整和放置:

public class CanvasPainter extends View {

    Context mContext;
    Drawable mDrawable;

    int mFrame[];
    int left;
    int top;
    int right;
    int bottom;
    int width;
    int height;

    private final int LEFT = 0;
    private final int TOP = 1;
    private final int RIGHT = 2;
    private final int BOTTOM = 3;

    public CanvasPainter(Context context, int frame[], Drawable drawable) {
        super(context);

        mContext = context;
        mFrame = frame;
        mDrawable = drawable;

        left = frame[LEFT];
        top = frame[TOP];
        right = frame[RIGHT];
        bottom = frame[BOTTOM];
        width = right - left;
        height = bottom - top;

    }

    public void onDraw(Canvas canvas) {
        Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL);


        Bitmap b = ((BitmapDrawable) mDrawable).getBitmap();
        Bitmap bitmapResized = Bitmap.createScaledBitmap(b, width, height, false);

        canvas.drawBitmap(bitmapResized, left, top, paint);
    }
}

所以,把它放在一起,这一切都是从onCreate()像这样组织起来的;

@Override 
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ... 

    mDrawerLayout.openDrawer(Gravity.LEFT);

    ViewTreeObserver vto = mRootview.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override 
        public void onGlobalLayout() { 

            mRootview.getViewTreeObserver().removeOnGlobalLayoutListener(this);

            RelativeLayout curtain = addOpaqueCurtainToRootView();
            int frame[] = getFrameOfExistingImageView();
            Drawable d = ContextCompat.getDrawable(context, R.drawable.imgView);
            CanvasPainter canvasPainter = new CanvasPainter(context, mCurrentImg, frame, d);
            curtain.addView(canvasPainter);
        } 
    }); 
} 

可能是一个不起眼的问题,但我希望这有助于某人。