android xml,布局中自定义视图的崩溃

Posted

技术标签:

【中文标题】android xml,布局中自定义视图的崩溃【英文标题】:android xml, crash of the custom view in a layout 【发布时间】:2013-01-11 20:24:01 【问题描述】:

我设计了一个简单的指南针应用, 第一步,我用一个视图(指南针视图)编写了应用程序,它工作得很好。我创建了一个自定义指南针视图的新实例,并使用了 setcontent(mView)。

现在我正在尝试使用布局,但我无法让它工作!每次我尝试时,应用程序都会崩溃。

代码如下:

自定义视图:

public class CustomDrawableView extends View 
public float azimut;
Paint paint = new Paint();
public CustomDrawableView(Context context) 
    super(context);
    paint.setStyle(Style.STROKE);
    paint.setStrokeWidth(2);
    paint.setColor(Color.WHITE);
    paint.setAntiAlias(true);
    azimut=0;
  ;
public CustomDrawableView(Context context, float Azimut) 
  super(context);
  paint.setStyle(Style.STROKE);
  paint.setStrokeWidth(2);
  paint.setColor(Color.WHITE);
  paint.setAntiAlias(true);
  azimut=Azimut;
;
protected void onDraw(Canvas canvas) 
    Bitmap bMap = BitmapFactory.decodeResource(getResources(),R.drawable.compassarrowbitmap);
    int width = getWidth();
    int height = getHeight();
    int centerx = width/2;
    int centery = height/2;
    int imHeight=200;
    int imWidth=200;
    Bitmap arrow = Bitmap.createScaledBitmap(bMap,imHeight , imWidth, false);
    canvas.save(Canvas.MATRIX_SAVE_FLAG); //Saving the canvas and later restoring it so only this image will be rotated.
    canvas.rotate(-azimut*360/(2*3.14159f), centerx, centery);
    canvas.drawBitmap(arrow, centerx-imWidth/2, centery-imHeight/2, null);
    canvas.restore();           
  

xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_
android:layout_
>
<FrameLayout 
android:layout_
android:layout_>

<org.example.compassTest.CustomDrawableView
    android:id="@+id/compassview"
    android:layout_
    android:layout_ />
</FrameLayout>
</LinearLayout>

主要活动:

public class MainActivity extends Activity implements SensorEventListener 
Float azimut=(float) 0;  // View to draw a compass
CustomDrawableView mCompassView;    
private SensorManager mSensorManager;
Sensor accelerometer;
Sensor magnetometer;

protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    this.mCompassView = (CustomDrawableView) findViewById(R.id.compassview);
    mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
    accelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    magnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);

protected void onResume() 
    super.onResume();
    mSensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_UI);
    mSensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_UI);

protected void onPause() 
    super.onPause();
    mSensorManager.unregisterListener(this);


public void onAccuracyChanged(Sensor sensor, int accuracy)   

float[] mGravity;
float[] mGeomagnetic;
public void onSensorChanged(SensorEvent event) 
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
        mGravity = event.values;
    if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
            mGeomagnetic = event.values;
    if (mGravity != null && mGeomagnetic != null) 
        float R[] = new float[9];
        float I[] = new float[9];
        boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);
        if (success) 
            float orientation[] = new float[3];
            SensorManager.getOrientation(R, orientation);
            azimut = orientation[0]; // orientation contains: azimut, pitch and roll
        
    
    this.mCompassView.azimut=azimut;
    this.mCompassView.invalidate();


** 日志:

    01-07 04:40:54.957: W/dalvikvm(18101): threadid=1: thread exiting with uncaught exception (group=0x40c431f8)
01-07 04:40:54.957: E/AndroidRuntime(18101): FATAL EXCEPTION: main
**01-07 04:40:54.957: E/AndroidRuntime(18101): java.lang.RuntimeException: Unable to start activity ComponentInfoorg.example.compasstest/org.example.compasstest.MainActivity: android.view.InflateException: Binary XML file line #11: Error inflating class org.example.compassTest.CustomDrawableView****
01-07 04:40:54.957: E/AndroidRuntime(18101):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1968)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1993)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at android.app.ActivityThread.access$600(ActivityThread.java:127)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1159)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at android.os.Handler.dispatchMessage(Handler.java:99)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at android.os.Looper.loop(Looper.java:137)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at android.app.ActivityThread.main(ActivityThread.java:4507)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at java.lang.reflect.Method.invokeNative(Native Method)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at java.lang.reflect.Method.invoke(Method.java:511)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at dalvik.system.NativeStart.main(Native Method)
01-07 04:40:54.957: E/AndroidRuntime(18101): Caused by: android.view.InflateException: Binary XML file line #11: Error inflating class org.example.compassTest.CustomDrawableView
01-07 04:40:54.957: E/AndroidRuntime(18101):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:691)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:739)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:742)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:271)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at android.app.Activity.setContentView(Activity.java:1835)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at org.example.compasstest.MainActivity.onCreate(MainActivity.java:28)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at android.app.Activity.performCreate(Activity.java:4465)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1052)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1932)
01-07 04:40:54.957: E/AndroidRuntime(18101):    ... 11 more
01-07 04:40:54.957: E/AndroidRuntime(18101): Caused by: java.lang.ClassNotFoundException: org.example.compassTest.CustomDrawableView
01-07 04:40:54.957: E/AndroidRuntime(18101):    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at android.view.LayoutInflater.createView(LayoutInflater.java:552)
01-07 04:40:54.957: E/AndroidRuntime(18101):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:680)
01-07 04:40:54.957: E/AndroidRuntime(18101):    ... 22 more

【问题讨论】:

请提供错误日志。 在哪里可以找到日志?? Eclipse > DDMS 透视图 > 日志猫 当您的应用程序崩溃时,它应该为您显示错误。突出显示红色行,按 Ctrl+C,然后将它们粘贴到您的问题中。 似乎 Eclipse 不喜欢我尝试在 xml 文件中使用自定义视图的方式 【参考方案1】:

我认为你缺少这个构造函数:

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

您正在尝试从布局 xml 传递参数构建视图,但您没有任何可以接收它们的构造函数。

【讨论】:

我不明白.. 我认为 xml 将使用构造函数构建视图:CustomDrawableView(Context context),而不传递任何参数...这就是我初始化 azimut=0 并更改它的原因只能从 main 的 void onSensorChanged 方法中的类外部。布局xml怎么传参数? ==> 你都经过这里android标签:id,宽度和高度 哦...好吧,那么..我到底该如何处理呢?我是否需要在构造函数中指定 layout_height 和其他? 您已经从 layout xml 收到了这个参数。是的,请把我的帖子标记为答案。 你能帮我设计一下构造函数吗?我如何处理这些参数?或者可以给我举个例子?..谢谢

以上是关于android xml,布局中自定义视图的崩溃的主要内容,如果未能解决你的问题,请参考以下文章

Android中自定义视图的“instanceof”方法?

Android中自定义属性的使用

具有自定义行布局的 ListView - Android

在 Android Studio 中向列表视图添加自定义行

在android中自定义表格布局

Android Studio中自定义标题栏的添加问题