I'm creating an Android Yahtzee game app. To keep track of player scores, I've tried to create a PointsView class to hold these scores. However, I'm getting a "The following classes could not be instantiated: - uk.ac.surrey.jb00359.yatzy.PointsView... See Error Log (Window > Show View)..." error for PointsView when I try to create it within my game XML layout file, shown below.
<?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>
When I look up the error log, it gives me this exception stack trace:
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)
So far, I have tried overriding my PointView's onMeasure() method using code kindly provided by stackoverflow user Devunwired at "onMeasure custom view explanation", but so far with no noticeable success. (See below)
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 */
}
}
Would anyone know what's happening in my code to cause this error?
Try to add 2 constructors:
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
}