在不开启开发者选项的情况下 直接在屏幕显示当前布局,内外边距,大小,方便产品,测试查看布局大小
基本思路:
为activty添加蒙层((ViewGroup) activity.getWindow().getDecorView()).addView(layoutView);
获取activity布局,递归遍历控件,获取每个控件决定位置,宽高,内外边距,然后画在layoutView上
关键代码如下:
import android.app.Activity;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
/*
* Created by wanjian on 2016/10/22.
*
* setContentView后调用,外边距浅红色,内边距浅绿色
*/
public class Layout {
public static void showLayout(Activity activity) {
if (activity == null) {
return;
}
ViewGroup vg = (ViewGroup) activity.getWindow().getDecorView();
LayoutView layoutView = new LayoutView(vg);
((ViewGroup) activity.getWindow().getDecorView()).addView(layoutView);
}
static class LayoutView extends View {
private String TAG = "LayoutView";
private ViewGroup vg;
private int[] mLocation = new int[2];
private Paint mPaint;
private int txtH;
private int cornerW;
private int strokeW;
public LayoutView(ViewGroup vg) {
super(vg.getContext());
this.vg = vg;
cornerW = dp2px(6);
strokeW = dp2px(1);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(Color.BLUE);
// mPaint.setShader(new LinearGradient(0, 0, 10, 10, new int[]{
// Color.RED, Color.BLUE,}, null,
// Shader.TileMode.REPEAT));
mPaint.setTextSize(dp2px(12));
Rect rect = new Rect();
mPaint.getTextBounds("1", 0, 1, rect);
txtH = rect.height();
vg.addOnLayoutChangeListener(new OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
invalidate();
}
});
}
@Override
protected void onDraw(final Canvas canvas) {
super.onDraw(canvas);
if (vg.getWidth() == 0 && vg.getHeight() == 0) {
vg.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
drawLayot(vg, canvas);
vg.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
} else {
drawLayot(vg, canvas);
}
}
private void drawLayot(ViewGroup vg, Canvas canvas) {
for (int i = 0; i < vg.getChildCount(); i++) {
View v = vg.getChildAt(i);
if (v instanceof LayoutView) {
continue;
}
v.getLocationOnScreen(mLocation);
drawMargin(canvas, v);
drawPadding(canvas, v);
drawBorder(canvas, v);
drawCorner(canvas, v);
drawWH(canvas, v);
if (v instanceof ViewGroup) {
drawLayot((ViewGroup) v, canvas);
}
}
}
private void drawPadding(Canvas canvas, View v) {
int l = v.getPaddingLeft();
int t = v.getPaddingTop();
int r = v.getPaddingRight();
int b = v.getPaddingBottom();
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(0x1500ff00);
canvas.drawRect(mLocation[0], mLocation[1], mLocation[0] + l, mLocation[1] + v.getHeight(), mPaint);
canvas.drawRect(mLocation[0], mLocation[1], mLocation[0] + v.getWidth(), mLocation[1] + t, mPaint);
canvas.drawRect(mLocation[0] + v.getWidth() - r, mLocation[1], mLocation[0] + v.getWidth(), mLocation[1] + v.getHeight(), mPaint);
canvas.drawRect(mLocation[0], mLocation[1] + v.getHeight() - b, mLocation[0] + v.getWidth(), mLocation[1] + v.getHeight(), mPaint);
mPaint.setStyle(Paint.Style.STROKE);
}
private void drawMargin(Canvas canvas, View v) {
ViewGroup.LayoutParams params = v.getLayoutParams();
if (params instanceof ViewGroup.MarginLayoutParams) {//画 外边距
ViewGroup.MarginLayoutParams marginLayoutParams = ((ViewGroup.MarginLayoutParams) params);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(0x11ff0000);
int l = mLocation[0] - marginLayoutParams.leftMargin;
int t = mLocation[1] - marginLayoutParams.topMargin;
int r = mLocation[0] + v.getWidth() + marginLayoutParams.rightMargin;
int b = mLocation[1] + v.getHeight() + marginLayoutParams.bottomMargin;
canvas.drawRect(l, mLocation[1], mLocation[0], mLocation[1] + v.getHeight(), mPaint);//left
canvas.drawRect(mLocation[0] + v.getWidth(), mLocation[1], r, mLocation[1] + v.getHeight(), mPaint);//right
canvas.drawRect(mLocation[0], t, mLocation[0] + v.getWidth(), mLocation[1], mPaint);
canvas.drawRect(mLocation[0], mLocation[1] + v.getHeight(), mLocation[0] + v.getWidth(), b, mPaint);
mPaint.setStyle(Paint.Style.STROKE);
}
}
private void drawWH(Canvas canvas, View v) {
//随机颜色,以免宽高覆盖后看不清
mPaint.setColor((int) (Math.random() * 0xffffff + 0xff000000));
mPaint.setStyle(Paint.Style.FILL);
canvas.drawText("w:" + v.getWidth() + " h:" + v.getHeight(), mLocation[0], mLocation[1] + txtH, mPaint);
mPaint.setStyle(Paint.Style.STROKE);
}
private void drawBorder(Canvas canvas, View v) {
mPaint.setColor(Color.MAGENTA);
canvas.drawRect(mLocation[0], mLocation[1], mLocation[0] + v.getWidth(), mLocation[1] + v.getHeight(), mPaint);
}
private void drawCorner(Canvas canvas, View v) {
mPaint.setColor(Color.BLUE);
mPaint.setStrokeWidth(strokeW);
canvas.drawLine(mLocation[0], mLocation[1], mLocation[0] + cornerW, mLocation[1], mPaint);
canvas.drawLine(mLocation[0], mLocation[1], mLocation[0], mLocation[1] + cornerW, mPaint);
canvas.drawLine(mLocation[0] + v.getWidth() - cornerW, mLocation[1], mLocation[0] + v.getWidth(), mLocation[1], mPaint);
canvas.drawLine(mLocation[0] + v.getWidth(), mLocation[1], mLocation[0] + v.getWidth(), mLocation[1] + cornerW, mPaint);
canvas.drawLine(mLocation[0], mLocation[1] + v.getHeight(), mLocation[0], mLocation[1] + v.getHeight() - cornerW, mPaint);
canvas.drawLine(mLocation[0], mLocation[1] + v.getHeight(), mLocation[0] + cornerW, mLocation[1] + v.getHeight(), mPaint);
canvas.drawLine(mLocation[0] + v.getWidth() - cornerW, mLocation[1] + v.getHeight(), mLocation[0] + v.getWidth(), mLocation[1] + v.getHeight(), mPaint);
canvas.drawLine(mLocation[0] + v.getWidth(), mLocation[1] + v.getHeight() - cornerW, mLocation[0] + v.getWidth(), mLocation[1] + v.getHeight(), mPaint);
mPaint.setStrokeWidth(1);
}
/**
* 滚动后可能不绘制,轻触一下屏幕即可再次绘制
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
invalidate();
return super.onTouchEvent(event);
}
private int dp2px(int dip) {
float density = getContext().getResources().getDisplayMetrics().density;
return (int) (dip * density + 0.5);
}
}
}
</pre><pre code_snippet_id="1943375" snippet_file_name="blog_20161022_4_2364372" name="code" class="java">
用法很简单,一句话搞定,直接在setContent后调用Layout.showLayout(this);即可
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.vs);
Layout.showLayout(this);
}
}
效果图,宽高信息可能会被覆盖,还没想到更好的解决方案,暂时采用随机颜色设置宽高信息