2016-01-04 102 views
1

我试图构建一个自定义视图,但由于某种原因它根本不显示。如何正确添加自定义视图到活动

为了节省读取两个构造函数,我调用了不带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

我在这里看到了两个问题。你不应该在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)); 

有几个小问题,但它可能让你去

+0

当我补充一点,自定义查看出现了,我看着由我的onDraw方法提供的值,并且你是正确的,当我调用drawText方法时,我给出了一个x和y参数,它在我的屏幕的可见区域之外。这解决了我的问题,谢谢。 – CompSci2015

+0

如果您对您在答案中提到的小问题有其他意见,我会非常感谢您分享了他们为什么会遇到问题以及如何改进这些问题。 – CompSci2015

+0

只是不明白为什么他们在那里的一些事情,但可能是因为你正在测试的东西。像这样,单独的布局xml实际上并未在所示的代码中使用,并且camera_preview FrameLayout已经包含一个CameraOverlay(您正在以编程方式添加一个)。如果进一步深入,那么嵌套布局对性能不利,尤其是当它们位于RelativeLayout中时,它们会被测量两次,或者如果您使用layout_weight(可能您之前使用过LinearLayout)(但影响很小)。在当前情况下需要较少的视图嵌套:) – priitv

相关问题