tags:

views:

75

answers:

1

This code works fine if I move the findViewById call in to the Activity. Any hints as to why it doesn't work from inside the LearningView class? I've tried moving the TextView inside the com.example.LearningView tag but no joy. I'd prefer to get the TextView from within the SurfaceView subclass as I feel it's more logical to treat the TV as a "child" of the SV.

This is a contrived example I wrote to figure out the problem in a larger application, but the gist of it is the same, and the stack trace is basically the same.

For what it is worth, the findViewById call is returning null, which obviously threw NullPointerExceptions in some attempts to fix this.

As you can probably gather from my attempts I'm flying blind on this one.

Learning.java:

package com.example.Learning;

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

public class Learning extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

LearningView.java:

package com.example.Learning;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.TextView;

public class LearningView extends SurfaceView implements SurfaceHolder.Callback {
    public LearningView(Context context, AttributeSet atts) {
        super(context, atts);
        getHolder().addCallback(this);      
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        TextView t = (TextView) findViewById(R.id.contents);
        t.setText("testing");
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
    }
}

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <com.example.Learning.LearningView
        android:id="@+id/learningview" android:layout_width="fill_parent"
        android:layout_height="fill_parent" />
    <TextView android:id="@+id/contents" android:layout_gravity="bottom|left"
        android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:textColor="#ffffffff" />
</FrameLayout>

Stack trace:

Thread [<3> main] (Suspended (exception RuntimeException))  
    ActivityThread.performLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2454  
    ActivityThread.handleLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2470   
    ActivityThread.access$2200(ActivityThread, ActivityThread$ActivityRecord, Intent) line: 119 
    ActivityThread$H.handleMessage(Message) line: 1821  
    ActivityThread$H(Handler).dispatchMessage(Message) line: 99 
    Looper.loop() line: 123 
    ActivityThread.main(String[]) line: 4310    
    Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]  
    Method.invoke(Object, Object...) line: 521  
    ZygoteInit$MethodAndArgsCaller.run() line: 860  
    ZygoteInit.main(String[]) line: 618 
    NativeStart.main(String[]) line: not available [native method]  
+2  A: 

You are crashing because your TextView is null after findViewById(). The TextView is not a child of the SurfaceView, therefore calling findViewById() with the SurfaceView as the starting point will not find it.

Romain Guy
Right. Is there a way I can rearrange things so that the TextView is a child of the SurfaceView? I've tried moving the TextView inside the <com.example.Learning.LearningView> node but that didn't do it. Basically, I am looking for a way to move view-oriented logic (text strings) from the Activity code layer to the View layer where it makes more sense (to me).
dpk
No, SurfaceView cannot have children. Why don't you just call findViewById() on SurfaceView's parent instead. Also, the logic really belongs in the Actity, not in the views.
Romain Guy
What is SurfaceView.findViewById() or View.findViewById() for if not for child views? I'm going to have to respectfully disagree on the logic belonging in Activity -- I'm going to have a lot of TextViews, and it doesn't make sense to me to have to set up references to those Views in Activity and then pass all of those references along to the main View, when all of the other display logic is contained within the Layout or View subclass.
dpk