• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Apps Subclassed view crashes

Larsp

Lurker
Hi developer forum!

Disclaimer: I'm completely new to Android development, and my java is rusty. So bear with me. I'm Using Eclipse 3.5 on a mac.

I'm struggling to get any kind of subclassed view to work in my Android layout. What I'm trying to do, is to have a few TextViews and a subclassed SurfaceView side by side, defined in layout.xml. But the application simply crashes in the emulator when I substitute a real SurfaceView with my subclassed one.

I'm confused, because I believe I have done the same as other examples demonstrating subclassed views do...

1. My subclassed surfaceview, LarspPreview.java:

Code:
package com.example.larsp.testing;

import android.content.Context;
import android.view.SurfaceView;


public class LarspPreview extends SurfaceView 
{
    LarspPreview(Context context) 
    {
        super(context);
    }
     
}
2. Excerpt from my main.xml layout:


Works:


Code:
        <SurfaceView
            android:layout_weight="1" 
            android:layout_width="fill_parent" 
            android:layout_height="fill_parent" />
Crashes: (android says in emulator: "... has stopped unexpectedly ...")


Code:
        <com.example.larsp.testing.LarspPreview
            android:layout_weight="1" 
            android:layout_width="fill_parent" 
            android:layout_height="fill_parent" />
What am I missing? Its making me frustrated that I can't get this simple concept working!!

Thanks!
 
I've never had any luck at all using the emulator or the layout preview with my sub-classed Views. Would be nice if there were a way to let the emulator become familiar with your unique sub-class. Either this or we're both missing something... But each of my sub-classed View objects functions as designed on my test device (actually my working phone) with no complaints. Have you installed and tested on device?
 
Very simple solution, your missing 1 constructor :)

try adding:

Code:
    LarspPreview( Context context, AttributeSet attrs ) 
    {
        super(context, attrs);
    }

This is because there are multiple ways to create views. The above code takes attributes (these are the values you set in the XML) and assigns them to corresponding attributes of that view. The below code is for direct instantiation of the view, this is where you set your attributes manually in the code.

Code:
    LarspPreview(Context context) 
    {
        super(context);
    }

There is also a third constructor, again for XML but for setting base styles :

Code:
    LarspPreview(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }

Hope this helped.

I'm actually currently writing a tutorial about GLSurfaceView and this is a topic is covered in that, lol.
 
Thanks for the tips :)

I tried running on the real device. Same problem.

I tried adding the extra constructors, still doesn't work! :confused:

So, something is still missing. Interestingly, I can use the subclassed view without crashing, if I load it directly from the activity onCreate function. This works:
Code:
        lpp = new LarspPreview(this);
        setContentView(lpp);
While it crashes when using the xml layout:
Code:
        setContentView(R.layout.main);
Also, in other app examples, the subclassed views work just fine... There must be a link somewhere I don't understand or haven't setup. For instance, how exactly are the views defined in the layout xml instantiated? Maybe com.example.larsp.testing.LarspPreview is somehow not visible?
 
My mistake, Surface view needs to implement SurfaceHolder.Callback

The following code should work:

Code:
package com.example.larsp.testing;

import android.app.Activity;
import android.os.Bundle;

public class Larsp extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

Code:
package com.example.larsp.testing;

import android.content.Context;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class LarspPreview extends SurfaceView implements SurfaceHolder.Callback {

	 private SurfaceHolder mHolder;

	 public LarspPreview(Context context) {
		 super( context );
		 onLoad();
	 }

	 public LarspPreview(Context context, AttributeSet attrs) {
		 super( context, attrs );
		 onLoad();
	 }

	 public LarspPreview(Context context, AttributeSet attrs, int defStyle) {
		 super( context, attrs, defStyle);
		 onLoad();
	 }
	 
	 public void onLoad()
	 {
		 mHolder = getHolder();
		 mHolder.addCallback(this);
	 }

	 public void surfaceCreated(SurfaceHolder holder) {}
	 public void surfaceDestroyed(SurfaceHolder holder) {}
	 public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {}
}

and layout :

Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
		xmlns:android="http://schemas.android.com/apk/res/android"
	    android:layout_width="fill_parent" 
	    android:layout_height="fill_parent">
	<com.example.larsp.testing.LarspPreview
	    android:layout_width="fill_parent" 
	    android:layout_height="fill_parent" />
</LinearLayout>
 
My mistake, Surface view needs to implement SurfaceHolder.Callback

The following code should work:

.
.
.

and layout :

Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
		xmlns:android="http://schemas.android.com/apk/res/android"
	    android:layout_width="fill_parent" 
	    android:layout_height="fill_parent">
	<com.example.larsp.testing.LarspPreview
	    android:layout_width="fill_parent" 
	    android:layout_height="fill_parent" />
</LinearLayout>

So what would I need to change in code for the below XML?

Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
		xmlns:android="http://schemas.android.com/apk/res/android"
	    android:layout_width="fill_parent" 
	    android:layout_height="fill_parent">

	<SurfaceView android:id="@+id/surfaceviewtest"
	    android:layout_width="fill_parent" 
	    android:layout_height="fill_parent" />
</LinearLayout>

And while I am at it, probably needs a new thread, how do I draw with code on this layout;

Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
		xmlns:android="http://schemas.android.com/apk/res/android"
	    android:layout_width="fill_parent" 
	    android:layout_height="fill_parent">
	<View android:id="@+id/viewtest"
	    android:layout_width="fill_parent" 
	    android:layout_height="fill_parent" />
</LinearLayout>
[/code]
 
Back
Top Bottom