问题
I'm new to android development and really struggling with using a custom view. I've read a lot of stuff on SO and its been really helpful with everything else, I just cant seem to work this one out. You guys are very smart and know your stuff so well. I hope to one day give back on SO as opposed to always taking! Any help would be very much appreciated. Thanks.
activity_display_message.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/share"
/>
<view class="me.myfirstapp.DisplayMessageActivity$MyView"
android:layout_width="150dp"
android:layout_height="100dp"
/>
DisplayMessageActivity.java
package me.myfirstapp;
import android.os.Bundle;
import android.app.Activity;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ShareActionProvider;
import android.support.v4.app.NavUtils;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.os.Build;
@SuppressLint({ "NewApi", "DrawAllocation" }) public class DisplayMessageActivity extends Activity {
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_message);
// Make sure we're running on Honeycomb or higher to use ActionBar APIs
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
// Show the Up button in the action bar.
getActionBar().setDisplayHomeAsUpEnabled(true);
}
}
public class MyView extends View {
private int mWidth;
private int mHeight;
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attribs) {
super(context, attribs);
}
public MyView(Context context, AttributeSet attribs, int defStyle) {
super(context, attribs, defStyle);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
Bitmap b1=BitmapFactory.decodeResource(getResources(), R.drawable.logolong);
b1 = Bitmap.createScaledBitmap(b1, 100, 20, false);
canvas.drawBitmap(b1, 600, 880, paint);
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/regencielight.TTF");
paint.setTypeface(tf);
paint.setColor(Color.parseColor("#ffffff"));
paint.setTextSize(46);
canvas.drawText(message, x1, 880, paint);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mWidth = View.MeasureSpec.getSize(widthMeasureSpec);
mHeight = View.MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(mWidth, mHeight);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
}
logcat output
03-15 21:14:23.382: E/AndroidRuntime(25443): FATAL EXCEPTION: main
03-15 21:14:23.382: E/AndroidRuntime(25443): Process: me.myfirstapp, PID: 25443
03-15 21:14:23.382: E/AndroidRuntime(25443): java.lang.RuntimeException: Unable to start activity ComponentInfo{me.myfirstapp/me.myfirstapp.DisplayMessageActivity}: android.view.InflateException: Binary XML file line #12: Error inflating class me.myfirstapp.DisplayMessageActivity$MyView
03-15 21:14:23.382: E/AndroidRuntime(25443): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
03-15 21:14:23.382: E/AndroidRuntime(25443): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
03-15 21:14:23.382: E/AndroidRuntime(25443): at android.app.ActivityThread.access$800(ActivityThread.java:135)
03-15 21:14:23.382: E/AndroidRuntime(25443): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
03-15 21:14:23.382: E/AndroidRuntime(25443): at android.os.Handler.dispatchMessage(Handler.java:102)
03-15 21:14:23.382: E/AndroidRuntime(25443): at android.os.Looper.loop(Looper.java:136)
03-15 21:14:23.382: E/AndroidRuntime(25443): at android.app.ActivityThread.main(ActivityThread.java:5017)
03-15 21:14:23.382: E/AndroidRuntime(25443): at java.lang.reflect.Method.invokeNative(Native Method)
03-15 21:14:23.382: E/AndroidRuntime(25443): at java.lang.reflect.Method.invoke(Method.java:515)
03-15 21:14:23.382: E/AndroidRuntime(25443): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
03-15 21:14:23.382: E/AndroidRuntime(25443): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
03-15 21:14:23.382: E/AndroidRuntime(25443): at dalvik.system.NativeStart.main(Native Method)
03-15 21:14:23.382: E/AndroidRuntime(25443): Caused by: android.view.InflateException: Binary XML file line #12: Error inflating class me.myfirstapp.DisplayMessageActivity$MyView
03-15 21:14:23.382: E/AndroidRuntime(25443): at android.view.LayoutInflater.createView(LayoutInflater.java:603)
03-15 21:14:23.382: E/AndroidRuntime(25443): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:696)
03-15 21:14:23.382: E/AndroidRuntime(25443): at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
03-15 21:14:23.382: E/AndroidRuntime(25443): at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
03-15 21:14:23.382: E/AndroidRuntime(25443): at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
03-15 21:14:23.382: E/AndroidRuntime(25443): at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
03-15 21:14:23.382: E/AndroidRuntime(25443): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:290)
03-15 21:14:23.382: E/AndroidRuntime(25443): at android.app.Activity.setContentView(Activity.java:1929)
03-15 21:14:23.382: E/AndroidRuntime(25443): at me.myfirstapp.DisplayMessageActivity.onCreate(DisplayMessageActivity.java:44)
03-15 21:14:23.382: E/AndroidRuntime(25443): at android.app.Activity.performCreate(Activity.java:5231)
03-15 21:14:23.382: E/AndroidRuntime(25443): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
03-15 21:14:23.382: E/AndroidRuntime(25443): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
03-15 21:14:23.382: E/AndroidRuntime(25443): ... 11 more
03-15 21:14:23.382: E/AndroidRuntime(25443): Caused by: java.lang.NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet]
03-15 21:14:23.382: E/AndroidRuntime(25443): at java.lang.Class.getConstructorOrMethod(Class.java:472)
03-15 21:14:23.382: E/AndroidRuntime(25443): at java.lang.Class.getConstructor(Class.java:446)
03-15 21:14:23.382: E/AndroidRuntime(25443): at android.view.LayoutInflater.createView(LayoutInflater.java:568)
03-15 21:14:23.382: E/AndroidRuntime(25443): ... 22 more
回答1:
I am sure that you are missing one of the constructor whenever you are creating a customView you have to override these constuctor And after seeing you stacktrace.
Caused by: java.lang.NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet]
// this above consturctor is misssing
Note: And also override onMeasure while creating custom View . it is mandatory
It's not mandatory, and most times you don't even have to worry about it as long as you provide constructors from View that pass them along to super().but you have to override second constructor to get your work done...
public CustomView(Context context) // No Attributes in this one.
{
super(context);
// Your code here
}
public CustomView(Context context, AttributeSet attrs)
{
super(context, attrs);
// Your code here
}
public CustomView(Context context, AttributeSet attrs, int default_style)
{
super(context, attrs, default_style);
// Your code here
}
回答2:
If you're using an inner class as a custom view class, it must be static
. The inflater doesn't have a reference to the outer class to instantiate it.
It's better to have your custom view classes on their own and not as inner classes.
回答3:
The problem here is clearly that you are defining your View as an inner non static class of the activity. That means that the view to be instantiated needs an instance of the Activity. At least make it static. Btw the onDraw you are using is too heavy. You are creating a new typeface, decoding and scaling bitmaps for every draw. Try to refactor it a bit
来源:https://stackoverflow.com/questions/22432901/android-view-inflateexception-issues-creating-custom-view