如何正确地向活动添加自定义视图

时间:2016-01-04 15:22:07

标签: android view android-custom-view

我正在尝试构建自定义视图但由于某种原因它根本没有显示。

为了节省您读取两个构造函数,我在没有attr参数的情况下调用View构造函数,因为这些应该从Layout文件中获取。此处未提取的任何值都在视图类本身中设置。

我的观点类:

package mrl233.campustour.AugmentedReality;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.hardware.SensorManager;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;

import org.w3c.dom.Text;

import java.util.ArrayList;
import java.util.List;

import mrl233.campustour.R;

/**
 * TODO: document your custom view class.
 */
public class CameraOverlay extends View {

    private float mAzimuth;
    private float mPitch;
    private float mRoll;
    private String mTextString;
    private int mTextColor = Color.RED;
    private float mTextDimension = 80;
    private Drawable mTextDrawable;
    private float mTextSize = 29;
    private TextPaint mTextPaint;
    private float mTextHeight = 0;
    private float mTextWidth;


    public CameraOverlay(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.CameraOverlay,
                0, 0);

        try {
            mTextString = a.getString(R.styleable.CameraOverlay_exampleString);
            mAzimuth = a.getFloat(R.styleable.CameraOverlay_exampleFloat_X, 0);
            mPitch = a.getFloat(R.styleable.CameraOverlay_exampleFloat_Y, 0);
            mRoll = a.getFloat(R.styleable.CameraOverlay_exampleFloat_Z, 0);
        } finally {
            a.recycle();
        }
        init();
    }
    public CameraOverlay(Context con, float azimuth, float pitch, float roll) {
        this(con,null);
        this.mAzimuth = azimuth;
        this.mPitch = pitch;
        this.mRoll = roll;
        TypedArray a = con.getTheme().obtainStyledAttributes(
                null,
                R.styleable.CameraOverlay,
                0, 0);

        try {
            mTextString = a.getString(R.styleable.CameraOverlay_exampleString);
            mAzimuth = a.getFloat(R.styleable.CameraOverlay_exampleFloat_X, 0);
            mPitch = a.getFloat(R.styleable.CameraOverlay_exampleFloat_Y, 0);
            mRoll = a.getFloat(R.styleable.CameraOverlay_exampleFloat_Z, 0);

        } finally {
            a.recycle();
        }
        init();

    }
        @Override
    public void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            invalidate();
            int paddingLeft = getPaddingLeft();
            int paddingTop = getPaddingTop();
            int paddingRight = getPaddingRight();
            int paddingBottom = getPaddingBottom();

            int contentWidth = getWidth() - paddingLeft - paddingRight;
            int contentHeight = getHeight() - paddingTop - paddingBottom;

            canvas.drawText("wsfsefseefsfsef",
                    paddingLeft + (contentWidth - mTextWidth),
                    paddingTop + (contentHeight + mTextHeight)
                    ,mTextPaint);


    }

}

这是我的视图布局:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    android:id="@+id/overlay"  >

    <mrl233.campustour.AugmentedReality.CameraOverlay
        android:background="#ccc"
        android:layout_width="300dp" android:layout_height="300dp" android:paddingLeft="20dp"
        android:paddingBottom="40dp" custom:exampleDimension="24sp" custom:exampleColor="#33b5e5"
        custom:exampleString="Hello, CameraOverlay"
        custom:exampleFloat_X="0.1"
        custom:exampleFloat_Y="0.5"
        custom:exampleFloat_Z="1"/>

</FrameLayout>

我将此视图添加到具有其自己视图的活动中。这是Activity类的onCreate方法,我尝试添加视图。

 @Override
    @SuppressWarnings("deprecation")
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.content_augment);

        preview = (FrameLayout) findViewById(R.id.camera_preview);
        mPreview = new CameraPreview(this, camera);
        mCameraOverlay = new CameraOverlay(this, 0, 0, 0);

        preview.addView(mPreview);
        preview.addView(mCameraOverlay);
        preview.bringChildToFront(mCameraOverlay);

    }

此活动类的布局:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout      xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:showIn="@layout/augment"
        tools:context="mrl233.campustour.Activities.Augment">

        <FrameLayout
            android:id="@+id/camera_preview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1">

        <!--<SurfaceView-->
            <!--android:layout_width="match_parent"-->
            <!--android:layout_height="match_parent"-->
            <!--android:id="@+id/surfaceView"/>-->

            <mrl233.campustour.AugmentedReality.CameraOverlay
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                />
        </FrameLayout>

    </RelativeLayout>

1 个答案:

答案 0 :(得分:2)

我在这里看到两个问题。你不应该在onDraw方法中调用invalidate(),因为它会导致视图重绘(无限循环)。其次getWidth()可能为0。您可能希望从onSizeChanged方法获取画布宽度

private int width;
private int height;

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    width = w;
    height = h;
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    ...
    int contentWidth = width - paddingLeft - paddingRight;
    ...
}

尝试使用硬编码尺寸导致当前您可能会在屏幕外绘制该文本或给它太少的空间(这可能会帮助您找到问题)。 我能想到的最小的customView将是:

public class CustomView extends View {
    private TextPaint paint;

    public CustomView(Context context) {
        super(context);
        paint = new TextPaint(Paint.LINEAR_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.RED);
        paint.setTextSize(20);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawText("Hello", 20, 20, paint);
    }
}

并初始化:

preview.addView(new CustomView(this));

还有一些小问题,但它可能会让你去