简体   繁体   English

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

[英]Android : How to embed a custom view into a constraint layout?

I have a custom view with animation and I need to somehow get it in the constraint layout. 我有一个带有动画的自定义视图,我需要以某种方式在约束布局中获取它。 Here is a little example of what I mean. 是我的意思的一个小例子。 I basically need a small area where I can use custom animations/bitmaps and all that stuff. 我基本上需要一个小区域,可以在其中使用自定义动画/位图以及所有其他内容。

So far I've only managed to apply the view on all the screen with: setContentView(customView). 到目前为止,我仅设法通过以下方法在所有屏幕上应用视图:setContentView(customView)。

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

Combined your code with the code for onMeasure from the answer I mentioned in comments: 我在评论中提到的答案将您的代码与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();
    }
}

The XMl is as simple as: 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>

Here is the layout with displaying bounds on: 这是显示边界的布局:

渲染布局,其中显示视图边界处于打开状态

Things to keep in mind: 注意事项:

  1. Magic numbers - you got quite a few of those here, you know best what are they for but it's better to keep them as named constants 幻数-这里有很多数字,您最清楚它们的用途,但最好将它们保留为命名常量
  2. View size depends on size of a screen. 视图大小取决于屏幕的大小。 This might not be a good idea. 这可能不是一个好主意。 It should depend on the size of the resource you are drawing. 它应取决于您正在绘制的资源的大小。
  3. I used relative layout but it should be no different with constraint layout. 我使用了相对布局,但约束布局应该没有什么不同。
  4. Extra constructors that appeared were needed for XML inflation XML膨胀需要出现的额外构造函数

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM