我有一个名为GLView的自定义视图,它扩展了GLSurfaceView类。在这个GLView内部,我想访问父线性布局中包含的另一个TextView。当我调用this.getParent时它返回NULL,所以我看了,eclipse确实说mparent为null。有谁知道为什么?
调用视图的活动类
package org.kizik.WLTBO;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class WholettheballoutActivity extends Activity {
GLView view;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.score);
view = (GLView) findViewById(R.id.mySurfaceView);
// You can use a FrameLayout to hold the surface view
/*FrameLayout frameLayout = new FrameLayout(this);
frameLayout.addView(view);
// Then create a layout to hold everything, for example a RelativeLayout
RelativeLayout relativeLayout= new RelativeLayout(this);
relativeLayout.addView(frameLayout);
relativeLayout.addView(score);
setContentView(relativeLayout);*/
}
@Override
protected void onPause() {
super.onPause();
view.onPause();
}
@Override
protected void onResume() {
super.onResume();
view.onResume();
}
}
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"
android:id="@+id/parent" >
<TextView android:id="@+id/textView2"
android:text = "Points 12345 Time:"
android:gravity="center_horizontal"
android:textSize="22sp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<org.kizik.WLTBO.GLView
android:id="@+id/mySurfaceView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>
可能不需要,但这里是GLView类中的构造函数
public GLView(Context context) {
super(context);
// Uncomment this to turn on error-checking and logging
//setDebugFlags(DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS);
renderer = new GLRenderer(context, view);
setRenderer(renderer);
}
public GLView(Context context, AttributeSet attrs){
super(context,attrs);
view = this.getParent();
renderer = new GLRenderer(context, view);
setRenderer(renderer);
}
答案 0 :(得分:2)
在活动中setContentView()
之前,请先尝试展开布局。然后,您可以检查默认布局行为是否将GLSurfaceView附加到LinearLayout:
View parentView = getLayoutInflater().inflate(R.layout.main,null,false);
view = (GlView)parentView.findViewById(R.id.mySurfaceView);
if(view.getParent()==null || !view.getParent() instanceof View ){
// throw new Exception("GLView had no parent or wrong parent");
} else {
setContentView(parentView);
}
您无法在onDraw()
,onSurfaceChanged()
或onSurfaceCreated()
方法中实际更改渲染器中的父视图(线性布局)或任何其他视图,因为它们都被称为通过GL线程。只有主/ UI线程(在您的活动中调用onCreate()
的线程)才能更改UI。如果您尝试在((TextView)view.findViewById(R.id.textView2)).setText("Some text");
中执行onSurfaceCreated()
,则会导致异常
更好的方法是从活动内部设置渲染器:
public class WholettheballoutActivity extends Activity {
GLView view;
GLRenderer renderer;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.score);
view = (GLView) findViewById(R.id.mySurfaceView);
LinearLayout parentView = findViewById(R.id.parent);
// Handler declaration goes in UI thread
Handler handle = new Handler(new Handler.Callback(){
@Override
public boolean handleMessage(Message msg){
// message is handled by the UI thread
TextView tv = WholettheballoutActivity .this.findViewById(R.id.textView2);
tv.setText("You Rock!");
return true;
}
});
renderer = new GLRenderer(context, parent, handler);
view.setRenderer(renderer);
}
}
然后在渲染器中:
public class GLRenderer implements GLSurfaceView.Renderer{
View parent;
Context context;
Handler handler;
public GLRenderer(Context context, View parent, Handler handler){
this.context = context;
this.parent = parent;
this.handler = handler;
}
public void onDraw(GL10 gl){
// drawing etc
handler.sendEmptyMessage(0);
}
}
Handler的handleMessage方法中的任何内容都会排队等待UI线程在下一次循环时执行。有other ways to pass messages between other threads and the UI thread,但这个虽然不是很明显,但对于非UI线程对UI进行单个异步更新最有意义
编辑:处理程序必须在要使用的线程中声明(除非你正在做一些时髦的see here)
答案 1 :(得分:0)
文档说
Gets the parent of this view. Note that the parent is a ViewParent and
not necessarily a View.