【发布时间】:2016-11-19 09:53:42
【问题描述】:
这是一个难以描述的情况,所以请多多包涵。我被要求制作一个像这样的“教练标记”屏幕:
但是,就我而言,我需要将一些底层图像“拉”到前面,并以不同的颜色显示它们以使它们脱颖而出。在运行时间之前,我无法确定这些图像的“框架”是什么。我的方法是添加一个覆盖整个屏幕的黑色半透明视图(我称之为“窗帘”),然后添加我需要的图像作为具有不同颜色的窗帘的子视图。 编辑这部分很简单,我不是在寻求帮助(这就是为什么认为这是建议问题的重复的建议是不正确的)。
我不相信我可以使用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);
}
【问题讨论】:
-
试试this
-
@user5599807 - 不是重复的。那篇文章只是问了一个非常简单的问题,即如何绘制具有半透明背景的视图。我已经这样做了(很容易)。我的问题是关于如何将子视图放置在新视图上的精确位置和精确大小。
-
@pskink - 谢谢。当我阅读这段代码时,它似乎只是建议解决方案是 a)获取对图像视图的引用,b)将其从其初始父视图中删除,然后 c)将其添加到新的半透明视图中。但这并不能解决如何在新父级中定位和调整图像视图大小的问题,对吧?我可能不明白如何正确实施这个建议。有比我看到的更多吗?非常感谢您提供任何进一步的建议。我很感激!
-
不需要
ImageView:在dispatchDraw方法中绘制你想要的任何东西,你可以调用例如canvas.drawBitmap,MyDecorView占据所有屏幕,包括操作栏,所以你不需要定位它无论如何,只需在调用setContentView之后再调用addMeToTheViewTree