2011-12-24 18 views
1

GLSurfaceViewクラスを拡張するGLViewというカスタムビューがあります。このGLViewの中で、親線形レイアウトに含まれる他のTextViewにアクセスしたいと思います。私がthis.getParentを呼び出すと、NULLを返します。だから私は見て、実際には、その親がnullであると言います。なぜ誰が知っていますか?GLSurfaceViewの親がLinearLayoutにネストされていてもnullです

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> 

はおそらくここでは必要ではなく

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(); 
    } 
} 

ビューを呼び出してActivityクラスは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

どのようにデバッグしていますか?私はアンドロイドでopencvと同様の問題を理解しようと狂った。ハードウェアの問題のために、ドロイドXのようなモトローラのデバイスはいつもクラッシュすることになる... Nexus Sはうまくいった。 –

答えて

2

あなたが活動にsetContentView()を行う前に、最初のレイアウトを拡大してみます。あなたは、デフォルトのレイアウト動作がのLinearLayoutにGLSurfaceViewを装着されているかどうかを確認することができます。

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を変更できます。レンダラーに続いて

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); 

    } 

} 

:あなたはonSurfaceCreated()((TextView)view.findViewById(R.id.textView2)).setText("Some text");を行うには、たとえばしようとした場合、それは例外

に活動の中からレンダラを設定することですこれを行うには良い方法を引き起こす

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に対する非同期的な更新を1つだけ行うのが最も理にかかります。

EDIT:ハンドラを使用するスレッドで宣言する必要がありますどのようなデバイスでどのようにデバッグしていますか?see here

+0

助けてくれてありがとう、長い待ち時間のために申し訳ありません。私は上記の修正を試みましたが、私が変更しなければならなかったのは、新しいglrenderer(this、parentView)と同じアクティビティのレンダラーを作成することでした。私はview.setrenderer(レンダラー)を試してみると問題があります。デバッグ時にソースが見つからないと表示されます。 –

+0

私はレンダラーを一度しか設定できないことを知ったので、glviewコンストラクターにあったsetrendererをコメントアウトしました。ただし、ハンドラがondrawメソッドで設定されているときにエラーが発生するようになりました。それはプログラムをクラッシュさせます。 –

+0

ああ、申し訳ありません。実際には、UIスレッドでHandlerが常に呼び出されるのは間違っていました。宣言されたスレッドから呼び出されます。つまり、onCreate()でハンドラを宣言し、それをレンダラコンストラクタに渡します。私の答えは –

0

ているドキュメントは

を語ります

Gets the parent of this view. Note that the parent is a ViewParent andnot necessarily a View.

+0

ええ、私はそれを知っています、私はそれを型キャストしました。しかし、それでもViewParentを返しません –