2016-01-04 51 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

相關問題