Android:自定义视图'PointsView':错误“以下类无法实例化”

时间:2013-04-08 13:21:45

标签: android android-layout android-custom-view

我正在创建一款Android Yahtzee游戏应用。为了跟踪玩家得分,我尝试创建一个PointsView类来保存这些分数。但是,我得到一个“以下类无法实例化: - uk.ac.surrey.jb00359.yatzy.PointsView ...请参阅错误日志(窗口>显示视图)...”我在PointsView时出现错误尝试在我的游戏XML布局文件中创建它,如下所示。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:background="@color/background_colour" >

  <Button
    android:id="@+id/roll_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_marginBottom="@dimen/die_margin"
    android:layout_marginLeft="@dimen/die_margin"
    android:text="@string/roll_button_text" />

  <TextView
    android:id="@+id/player_turn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBottom="@id/roll_button"
    android:layout_alignParentRight="true"
    android:layout_marginRight="@dimen/die_margin"
    android:text="@string/player_1_turn_text"
    android:textSize="18sp" />

  <ImageView
    android:id="@+id/die_3"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_above="@id/roll_button"
    android:layout_marginBottom="@dimen/die_margin"
    android:layout_centerHorizontal="true"
    android:contentDescription="@string/die_3_description"
    android:src="@drawable/dice_1" />

  <ImageView
    android:id="@+id/die_2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBottom="@id/die_3"
    android:layout_toLeftOf="@id/die_3"
    android:layout_marginRight="@dimen/die_margin"
    android:contentDescription="@string/die_2_description"
    android:src="@drawable/dice_1" />

  <ImageView
    android:id="@+id/die_1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBottom="@id/die_2"
    android:layout_toLeftOf="@id/die_2"
    android:layout_marginRight="@dimen/die_margin"
    android:contentDescription="@string/die_1_description"
    android:src="@drawable/dice_1" /> 

  <ImageView
    android:id="@+id/die_4"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBottom="@id/die_3"
    android:layout_toRightOf="@id/die_3"
    android:layout_marginLeft="@dimen/die_margin"
    android:contentDescription="@string/die_4_description"
    android:src="@drawable/dice_1" />

  <ImageView
    android:id="@+id/die_5"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBottom="@id/die_4"
    android:layout_toRightOf="@id/die_4"
    android:layout_marginLeft="@dimen/die_margin"
    android:contentDescription="@string/die_5_description"
    android:src="@drawable/dice_1" />

  <uk.ac.surrey.jb00359.yatzy.PointsView
    android:id="@+id/points_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginLeft="@dimen/points_view_margin"
    android:layout_marginTop="@dimen/points_view_margin"
    android:layout_marginRight="@dimen/points_view_margin"
    android:layout_marginBottom="@dimen/die_margin"
    android:layout_above="@id/die_1" />

</RelativeLayout>

当我查找错误日志时,它会给我这个异常堆栈跟踪:

java.lang.NoSuchMethodException: uk.ac.surrey.jb00359.yatzy.PointsView.<init>(android.content.Context, android.util.AttributeSet)
    at java.lang.Class.getConstructor0(Class.java:2733)
    at java.lang.Class.getConstructor(Class.java:1676)
    at com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback.instantiateClass(ProjectCallback.java:347)
    at com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback.loadView(ProjectCallback.java:179)
    at android.view.BridgeInflater.loadCustomView(BridgeInflater.java:207)
    at android.view.BridgeInflater.createViewFromTag(BridgeInflater.java:135)
    at android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:746)
    at android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:64)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:718)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:372)
    at com.android.layoutlib.bridge.impl.RenderSessionImpl.inflate(RenderSessionImpl.java:385)
    at com.android.layoutlib.bridge.Bridge.createSession(Bridge.java:332)
    at com.android.ide.common.rendering.LayoutLibrary.createSession(LayoutLibrary.java:325)
    at com.android.ide.eclipse.adt.internal.editors.layout.gle2.RenderService.createRenderSession(RenderService.java:440)
    at com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart.renderWithBridge(GraphicalEditorPart.java:1545)
    at com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart.recomputeLayout(GraphicalEditorPart.java:1302)
    at com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart.activated(GraphicalEditorPart.java:1059)
    at com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate.delegatePageChange(LayoutEditorDelegate.java:686)
    at com.android.ide.eclipse.adt.internal.editors.common.CommonXmlEditor.pageChange(CommonXmlEditor.java:360)
    at org.eclipse.ui.part.MultiPageEditorPart$2.widgetSelected(MultiPageEditorPart.java:292)
    at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:248)
    at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1276)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1300)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1285)
    at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1079)
    at org.eclipse.swt.custom.CTabFolder.setSelection(CTabFolder.java:3023)
    at org.eclipse.swt.custom.CTabFolder.onMouse(CTabFolder.java:1730)
    at org.eclipse.swt.custom.CTabFolder$1.handleEvent(CTabFolder.java:270)
    at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1276)
    at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3554)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3179)
    at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1022)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
    at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:916)
    at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:86)
    at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:585)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
    at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:540)
    at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
    at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:124)
    at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:353)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:616)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:629)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1438)
    at org.eclipse.equinox.launcher.Main.main(Main.java:1414)

到目前为止,我已经尝试使用stackoverflow用户Devunwired在“onMeasure custom view explanation”提供的代码覆盖我的PointView的onMeasure()方法,但到目前为止还没有明显的成功。 (见下文)

package uk.ac.surrey.jb00359.yatzy;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.view.View;

/**
 * 
 * This class outputs the current scores obtained by the two Yatzy players
 */
public class PointsView extends View {

// Do not change these values!
private static final float noOfColumns = 3f;
private static final float noOfRows = 19f;

private GameActivity game;
private GameLogic gameLogic;
private Paint majorLinePaint = new Paint();
private Paint minorLinePaint = new Paint();
/** 
  * Colour of score cells, that can be selected to store
  * a player's new dice score after a round (1-3 dice throws)
  */
private Paint selectablePaint = new Paint();
private Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float top, left, bottom, right; // grid boundaries
private float cellWidth, cellHeight; // Cell sizes

public PointsView(Context context, AttributeSet attrs, GameLogic gameLogic) {
    super(context, attrs);
    // Allow the view to refer to the game activity and game logic (state) 
    this.game = (GameActivity) context;
    this.gameLogic = gameLogic;
    majorLinePaint.setColor(getResources().getColor(R.color.major_line_colour));
    minorLinePaint.setColor(getResources().getColor(R.color.minor_line_colour));
    selectablePaint.setColor(getResources().getColor(R.color.selectable_cell_colour));
    textPaint.setColor(getResources().getColor(R.color.text_colour));
    textPaint.setStyle(Style.FILL);
    textPaint.setTextScaleX(1f);
    textPaint.setTextAlign(Paint.Align.CENTER); 
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    top = 0;
    left = 0;
    bottom = h;
    right = w;
    cellWidth = w / noOfColumns; // 3 columns of cells
    cellHeight = h / noOfRows; // 19 rows of cells
    // Set text size to be 7/8 of the height of each cell
    textPaint.setTextSize(cellHeight * (7/8));
    super.onSizeChanged(w, h, oldw, oldh);
}

@Override
protected void onDraw(Canvas canvas) {
    // Draw the PointsView's grid lines
    for (int i = 0; i <= noOfColumns; i++) {
        // Draw column lines
        canvas.drawLine(left + i*cellWidth, top, left + i*cellWidth, bottom, majorLinePaint);
    }
    for (int j = 0; j <= noOfRows; j++) {
        // Draw row lines
        canvas.drawLine(left, top + j*cellHeight, right, top + j*cellHeight, majorLinePaint);
    }

    // More drawing later...

}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    /** 
     * Here starts Devunwired's code from 
     * https://stackoverflow.com/questions/12266899/onmeasure-custom-view-explanation */

    int desiredWidth = 100;
    int desiredHeight = 100;

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

    /** End of Devunwired's code */
}

}

有人知道我的代码中发生了什么导致此错误吗?

1 个答案:

答案 0 :(得分:3)

尝试添加2个构造函数:

public PointsView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    public PointsView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }