我正在玩一些简单的Android应用程序代码,但是代码中的所有布局都存在问题。
当我在eclipse中打开布局时,这是错误
The following classes could not be instantiated:
- com.android2.calculator3.view.ColorButton (Open Class, Show Error Log)
See the Error Log (Window > Show View) for more details.
Tip: Use View.isInEditMode() in your custom views to skip code when shown in Eclipse
java.lang.ClassCastException: com.android.layoutlib.bridge.android.BridgeContext cannot be cast to com.android2.calculator3.Calculator
at com.android2.calculator3.view.ColorButton.<init>(ColorButton.java:39)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0( at sun.reflect.NativeConstructorAccessorImpl.newInstance( at sun.reflect.DelegatingConstructorAccessorImpl.newInstance( at java.lang.reflect.Constructor.newInstance( at com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback.instantiateClass(ProjectCallback.java:442)
at com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback.loadView(ProjectCallback.java:194)
at android.view.BridgeInflater.loadCustomView(BridgeInflater.java:207)
at android.view.BridgeInflater.createViewFromTag(BridgeInflater.java:132)
at android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:806)
at android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:64)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:782)
at android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:809)
at android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:64)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:782)
at android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:809)
at android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:64)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:782)
at android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:809)
at android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:64)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:782)
at android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:809)
at android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:64)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:782)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at android.view.LayoutInflater.inflate(LayoutInflater.java:385)
这是我在Colorbutton.java中的代码
package com.android2.calculator3.view;
import java.util.regex.Pattern;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.Button;
import com.android2.calculator3.Calculator;
import com.android2.calculator3.EventListener;
import calculator.app.R;
/**
* Button with click-animation effect.
*/
class ColorButton extends Button {
int CLICK_FEEDBACK_COLOR;
static final int CLICK_FEEDBACK_INTERVAL = 10;
static final int CLICK_FEEDBACK_DURATION = 350;
float mTextX;
float mTextY;
long mAnimStart;
EventListener mListener;
Paint mFeedbackPaint;
Paint mHintPaint = new Paint();
Rect bounds = new Rect();
float mTextSize = 0f;
public ColorButton(Context context, AttributeSet attrs) {
super(context, attrs);
Calculator calc = (Calculator) context;
init(calc);
mListener = calc.mListener;
setOnClickListener(mListener);
setOnLongClickListener(mListener);
}
private void init(Calculator calc) {
Resources res = getResources();
CLICK_FEEDBACK_COLOR = res.getColor(R.color.magic_flame);
mFeedbackPaint = new Paint();
mFeedbackPaint.setStyle(Style.STROKE);
mFeedbackPaint.setStrokeWidth(2);
getPaint().setColor(res.getColor(R.color.button_text));
mHintPaint.setColor(res.getColor(R.color.button_hint_text));
mAnimStart = -1;
}
private void layoutText() {
Paint paint = getPaint();
if(mTextSize != 0f) paint.setTextSize(mTextSize);
float textWidth = paint.measureText(getText().toString());
float width = getWidth() - getPaddingLeft() - getPaddingRight();
float textSize = getTextSize();
if(textWidth > width) {
paint.setTextSize(textSize * width / textWidth);
mTextX = getPaddingLeft();
mTextSize = textSize;
}
else {
mTextX = (getWidth() - textWidth) / 2;
}
mTextY = (getHeight() - paint.ascent() - paint.descent()) / 2;
if(mHintPaint != null) mHintPaint.setTextSize(paint.getTextSize() * 0.8f);
}
@Override
protected void onTextChanged(CharSequence text, int start, int before, int after) {
layoutText();
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if(changed) layoutText();
}
private void drawMagicFlame(int duration, Canvas canvas) {
int alpha = 255 - 255 * duration / CLICK_FEEDBACK_DURATION;
int color = CLICK_FEEDBACK_COLOR | (alpha << 24);
mFeedbackPaint.setColor(color);
canvas.drawRect(1, 1, getWidth() - 1, getHeight() - 1, mFeedbackPaint);
}
@Override
public void onDraw(Canvas canvas) {
if(mAnimStart != -1) {
int animDuration = (int) (System.currentTimeMillis() - mAnimStart);
if(animDuration >= CLICK_FEEDBACK_DURATION) {
mAnimStart = -1;
}
else {
drawMagicFlame(animDuration, canvas);
postInvalidateDelayed(CLICK_FEEDBACK_INTERVAL);
}
}
else if(isPressed()) {
drawMagicFlame(0, canvas);
}
CharSequence hint = getHint();
if(hint != null) {
String[] exponents = hint.toString().split(Pattern.quote("^"));
int offsetX = getContext().getResources().getDimensionPixelSize(R.dimen.button_hint_offset_x);
int offsetY = (int) ((mTextY + getContext().getResources().getDimensionPixelSize(R.dimen.button_hint_offset_y) - getTextHeight(mHintPaint,
hint.toString())) / 2)
- getPaddingTop();
float textWidth = mHintPaint.measureText(hint.toString());
float width = getWidth() - getPaddingLeft() - getPaddingRight() - mTextX - offsetX;
float textSize = mHintPaint.getTextSize();
if(textWidth > width) {
mHintPaint.setTextSize(textSize * width / textWidth);
}
for(String str : exponents) {
if(str == exponents[0]) {
canvas.drawText(str, 0, str.length(), mTextX + offsetX, mTextY - offsetY, mHintPaint);
offsetY += getContext().getResources().getDimensionPixelSize(R.dimen.button_hint_exponent_jump);
offsetX += mHintPaint.measureText(str);
}
else {
canvas.drawText(str, 0, str.length(), mTextX + offsetX, mTextY - offsetY, mHintPaint);
offsetY += getContext().getResources().getDimensionPixelSize(R.dimen.button_hint_exponent_jump);
offsetX += mHintPaint.measureText(str);
}
}
}
CharSequence text = getText();
canvas.drawText(text, 0, text.length(), mTextX, mTextY, getPaint());
}
private int getTextHeight(Paint paint, String text) {
mHintPaint.getTextBounds(text, 0, text.length(), bounds);
int height = bounds.height();
String[] exponents = text.split(Pattern.quote("^"));
for(int i = 1; i < exponents.length; i++) {
height += getContext().getResources().getDimensionPixelSize(R.dimen.button_hint_exponent_jump);
}
return height;
}
public void animateClickFeedback() {
mAnimStart = System.currentTimeMillis();
invalidate();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean result = super.onTouchEvent(event);
switch(event.getAction()) {
case MotionEvent.ACTION_UP:
if(isPressed()) {
animateClickFeedback();
}
else {
invalidate();
}
break;
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_CANCEL:
mAnimStart = -1;
invalidate();
break;
}
return result;
}
}
我无法弄清楚这里出了什么问题?
答案 0 :(得分:1)
您的错误日志可以完成大部分工作:
java.lang.ClassCastException: com.android.layoutlib.bridge.android.BridgeContext cannot be cast to com.android2.calculator3.Calculator
at com.android2.calculator3.view.ColorButton.<init>(ColorButton.java:39)
基本上,您正在尝试将BridgeContext
转换为Calculator
,我假设您在构造函数中引用此行:
public ColorButton(Context context, AttributeSet attrs) {
super(context, attrs);
Calculator calc = (Calculator) context; //This Line
init(calc);
mListener = calc.mListener;
setOnClickListener(mListener);
setOnLongClickListener(mListener);
}
为此,您的context
参数需要从Calculator
继承。一个简单的测试是:
if (context instanceof Calculator) {
Calculator calc = (Calculator) context;
} else {
Log.e("Log Tag", context.toString() + " must inherit from Calculator class");
}
或使用try/catch
块:
try {
Calculator calc = (Calculator) context;
} catch (ClassCastException e) {
Log.e("Log Tag", context.toString() + " must inherit from Calculator class");
e.printStackTrace();
}
修改:
对于您的情况可能的修复可能是您的构造函数的以下修订:
public ColorButton(Context context, AttributeSet attrs, Caculator calculator) {
super(context, attrs);
Calculator calc = calculator;
init(calc);
mListener = calc.mListener;
setOnClickListener(mListener);
setOnLongClickListener(mListener);
}
当然,这是因为我对你的自定义Calculator
类一无所知(即,它是否甚至是Context
的次级)。此方法将完全绕过context
转换,因此只要它继承自Context
类(最常见的是Activity
),您就可以为第一个参数传递任何您喜欢的内容。 / p>