如果我将findViewById调用移动到Activity,此代码可以正常工作。有关为什么它不能在LearningView类内部工作的任何提示?我已经尝试在com.example.LearningView标记内移动TextView但没有快乐。我更喜欢从SurfaceView子类中获取TextView,因为我认为将电视视为SV的“孩子”更合乎逻辑。
这是我写的一个人为的例子,用来在更大的应用程序中找出问题,但它的要点是相同的,堆栈跟踪基本相同。
对于它的价值,findViewById调用返回null,这显然在一些尝试中修复了NullPointerExceptions。
正如你可能从我的尝试中收集到的那样,我对这一次失明了。
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>
堆栈追踪:
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]
答案 0 :(得分:2)
您正在崩溃,因为TextView
后findViewById()
为空。 TextView
不是SurfaceView
的孩子,因此以findViewById()
为起点调用SurfaceView
将无法找到它。
答案 1 :(得分:2)
您可以将上下文强制转换为活动,并按如下方式查找视图:
(TextView)((Activity)context).findViewById(R.id.contents);
现在它不会为空。
答案 2 :(得分:1)
我遇到了同样的问题,Loke提供的答案解决了我的问题。我不知道铸造是否是一个很好的干净方式来为Android sdk编程。这是我的代码最终结果:
我的活动有:
setContentView(R.layout.game);
我的game.xml:
<TextView
android:text="@string/text_foul_counter_1"
android:layout_height="wrap_content"
android:background="#fff"
android:gravity="center"
android:textColor="#000"
android:id="@+id/TextViewFoulCounter1"
android:layout_width="wrap_content"
android:layout_below="@+id/TextViewFoul1"
android:padding="2dp"></TextView>
从我的班级中调用finViewById: public class PlayerView extends Activity实现OnClickListener,OnLongClickListener {...}
没有强制转换我曾经得到一个空指针异常。下面是现在有效的代码行。
foulsTextViewTeam1 = (TextView) ((Activity) context).findViewById(R.id.TextViewFoulCounter1);