Родитель GLSurfaceView является нулевым, даже если он вложен в LinearLayout - PullRequest
1 голос
/ 24 декабря 2011

У меня есть собственное представление под названием GLView, которое расширяет класс GLSurfaceView. Внутри этого GLView я хочу получить доступ к другому TextView, который содержится в родительском Linear Layout. Когда я вызываю this.getParent, он возвращает NULL, поэтому я посмотрел, и затмение действительно говорит, что mparent равен нулю. кто-нибудь знает почему?

Класс активности, который вызывает представление

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

   }

Ответы [ 2 ]

2 голосов
/ 25 декабря 2011

Попробуйте сначала развернуть макет, прежде чем выполнять 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. Только основной поток / поток пользовательского интерфейса (тот, который вызывает onCreate() в вашей активности) может изменить пользовательский интерфейс. Например, если вы попытаетесь сделать ((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);

    }

}

Все, что находится внутри метода handleMessage Обработчик , помещается в очередь для выполнения потока пользовательского интерфейса в следующий раз, когда он зацикливается. Существуют другие способы передачи сообщений между другими потоками и потоком пользовательского интерфейса , но этот, хотя и не сразу очевидный, наиболее целесообразен для потоков, не являющихся пользовательскими интерфейсами, которые выполняют отдельные асинхронные обновления пользовательского интерфейса

РЕДАКТИРОВАТЬ: обработчик должен быть объявлен в потоке, в котором он будет использоваться (если вы не делаете что-то напуганное см. Здесь )

0 голосов
/ 24 декабря 2011

В документации написано

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

...