Android:如何将自定义视图嵌入约束布局?

时间:2017-03-30 13:41:35

标签: android graphics

我有一个带动画的自定义视图,我需要以某种方式在约束布局中获取它。 Here是我的意思的一个小例子。我基本上需要一个小区域,我可以使用自定义动画/位图和所有这些东西。

到目前为止,我只是设法在所有屏幕上应用视图: 的setContentView(customView)。

customView:

public class CrashView extends View {

private int width, height,bheight, bwidth, boxwidth, boxheight;
private float x,y,vx,vy;

private Bitmap bullet;
private Paint AA = new Paint(Paint.ANTI_ALIAS_FLAG);

public CrashView (Context context){
    super(context);

    Display display = ((Activity) getContext()).getWindowManager().getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);

    bullet = BitmapFactory.decodeResource(getResources(), R.drawable.bullet);
    bullet = Bitmap.createScaledBitmap(bullet, bullet.getWidth()/5, bullet.getHeight()/5, true);

    width = size.x;
    height = size.y;

    bheight = bullet.getHeight();
    bwidth = bullet.getWidth();

    boxheight = height / 4;
    boxwidth = (width / 20) * 19;

    x = (width/20)/4;
    y = boxheight-bheight/4*3;
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    vy = -0.1f - (float) ((Math.pow(x / 600, 2)) / 1.25);

    x += vx;
    y += vy;

    canvas.drawBitmap(bullet, x, y, AA);
    invalidate();
}

1 个答案:

答案 0 :(得分:2)

从我在评论中提到的答案中将您的代码与onMeasure的代码结合起来:

public class CrashView extends View {

    private int width, height, bheight, bwidth, boxwidth, boxheight;
    private float x, y, vx, vy;

    private Bitmap bullet;
    private Paint AA = new Paint(Paint.ANTI_ALIAS_FLAG);

    public CrashView(Context context) {
        super(context);
        init(context);
    }

    public CrashView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public CrashView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public CrashView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context);
    }

    private void init(Context ctx) {

        Display display = ((Activity) ctx).getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        //REPLACE DRAWABLE HERE
        bullet = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
        bullet = Bitmap.createScaledBitmap(bullet, bullet.getWidth() / 5, bullet.getHeight() / 5, true);

        width = size.x;
        height = size.y;

        bheight = bullet.getHeight();
        bwidth = bullet.getWidth();

        boxheight = height / 4;
        boxwidth = (width / 20) * 19;

        x = (width / 20) / 4;
        y = boxheight - bheight / 4 * 3;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int desiredWidth = boxwidth;
        int desiredHeight = boxwidth;

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        int width;
        int height;

        //Measure Width
        if (widthMode == MeasureSpec.EXACTLY) {
            //Must be this size
            width = widthSize;
        } else if (widthMode == MeasureSpec.AT_MOST) {
            //Can't be bigger than...
            width = Math.min(desiredWidth, widthSize);
        } else {
            //Be whatever you want
            width = desiredWidth;
        }

        //Measure Height
        if (heightMode == MeasureSpec.EXACTLY) {
            //Must be this size
            height = heightSize;
        } else if (heightMode == MeasureSpec.AT_MOST) {
            //Can't be bigger than...
            height = Math.min(desiredHeight, heightSize);
        } else {
            //Be whatever you want
            height = desiredHeight;
        }

        //MUST CALL THIS
        setMeasuredDimension(width, height);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        vy = -0.1f - (float) ((Math.pow(x / 600, 2)) / 1.25);

        x += vx;
        y += vy;

        canvas.drawBitmap(bullet, x, y, AA);
        invalidate();
    }
}

XMl就像:

一样简单
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/root">

    <com.test.myapplication.CrashView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</RelativeLayout>

以下是显示边界的布局:

Rendered layout with displaying view bounds ON

要记住的事情:

  1. 魔术数字 - 你在这里有很多这样的数字,你最了解它们是什么,但最好将它们保持为命名常数
  2. 查看大小取决于屏幕的大小。这可能不是一个好主意。它应该取决于您正在绘制的资源的大小。
  3. 我使用了相对布局,但它与约束布局应该没有区别。
  4. XML通胀需要出现的额外构造函数