安卓 : How to embed a custom view into a constraint layout?

标签 android graphics

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

到目前为止,我只能通过以下方式在所有屏幕上应用 View : setContentView(customView)。

自定义 View :

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();
}

最佳答案

将您的代码与我在评论中提到的答案中的 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. View 尺寸取决于屏幕尺寸。这可能不是一个好主意。它应该取决于您正在绘制的资源的大小。
  3. 我使用了相对布局,但它与约束布局应该没有什么不同。
  4. XML 膨胀需要额外的构造函数

关于安卓 : How to embed a custom view into a constraint layout?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43119679/

相关文章:

android - 出现键盘时滚动布局

android - 绘制垂直虚线

c++ - 如何将轴移动到 QCustomPlot 的中间

cocoa - 如何绘制模糊的形状?

.net - 如何在灰色位图图像上绘制彩色形状?

Android FragmentTransaction 何时提交?

php - 安卓+php mysql

java - Android 按钮循环

java - 将图像添加到 ArrayList 时出现 IndexOutofBounds 异常

image - 如何在YUV 420半平面图像中应用单应性/ react 性?