Ошибка при обновлении View поверх SurfaceView - PullRequest
2 голосов
/ 17 января 2012

Я столкнулся с проблемой, когда хочу отобразить объект обычного вида поверх вида поверхности.Проблема заключается в следующем: если я установил видимость обычного вида невидимым в XML-файле макета, обновление представления будет неправильным - перекрывающаяся область вида и вид поверхности не могут быть обновлены.Если я установлю видимость обычного вида на видимый в макете XML, проблем не будет.

Вот мой тестовый код:

package com.test;

import java.io.IOException;


import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.widget.LinearLayout;


public class TESTActivity extends Activity implements Callback, OnPreparedListener {
    private SurfaceView mSurface1;
    private SurfaceHolder mSurfaceHolder1;
    private MediaPlayer mMediaPlayer1;
    private LinearLayout mLayout;

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

        mLayout = (LinearLayout) findViewById(R.id.channel_subscribe);

        new Handler() {
            @Override
            public void handleMessage(Message m) {
                if(mLayout.getVisibility() == View.INVISIBLE)
                    mLayout.setVisibility(View.VISIBLE);
                else
                    mLayout.setVisibility(View.INVISIBLE);
                this.sendEmptyMessageDelayed(0, 4000);
            } 
        }.sendEmptyMessageDelayed(0, 4000);

        mSurface1 = (SurfaceView) findViewById(R.id.video_surface);
        mSurfaceHolder1 = mSurface1.getHolder();
        mSurfaceHolder1.addCallback(this);
        mSurfaceHolder1.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        mMediaPlayer1 = new MediaPlayer();
        mMediaPlayer1.setOnPreparedListener(this);

        try {
            mMediaPlayer1.setDataSource("/sdcard/d4.avi");
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
        // TODO Auto-generated method stub

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        Log.w("XXXXX", "Surface1 created");
        mMediaPlayer1.setDisplay(holder);
        mMediaPlayer1.prepareAsync();

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        Log.w("XXXXX", "Mediaplayer prepared");
        mp.start();
    }
}

А вот файл макета:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent"
  xmlns:android="http://schemas.android.com/apk/res/android">
    <SurfaceView android:id="@+id/video_surface"
        android:layout_width="480dip" 
        android:layout_height="270dip"
        android:layout_marginLeft="180dip"
        android:layout_marginTop="40dip"
        />
    <LinearLayout android:id="@+id/channel_subscribe" android:visibility="invisible" android:orientation="vertical" android:background="#bb161616" android:layout_width="436.0sp" android:layout_height="148.0sp" android:layout_alignParentBottom="true">
      <TextView android:textSize="14.0dip" android:textStyle="normal" android:textColor="#ffb7b7b7" android:id="@+id/subscribe_title" android:layout_width="wrap_content" android:layout_height="70.0sp" android:layout_marginLeft="38.0sp" android:layout_marginTop="18.0sp" android:layout_marginRight="34.0sp" android:text="We Hope you enjoyed the channel preview. To subscribe this channel, please press the button below." />
      <Button android:id="@+id/subscribe_now_button" android:layout_width="184.0sp" android:layout_height="42.0sp" android:layout_marginLeft="38.0sp" android:layout_marginRight="34.0sp" android:layout_marginBottom="18.0sp" android:text="SubscribeNow" />
     </LinearLayout>



</RelativeLayout>

1 Ответ

13 голосов
/ 18 января 2012

Проблема решена.

курс:

  1. Виджет диалога подписки инициализируется как невидимый во время раздувания макета активности.
  2. А затем SurfaceView, используемый для воспроизведения видео, присоединяется к окну активности.
  3. Когда SurfaceView вызывает mParent.requestTransparentRegion (this); в обратном вызове onAttachedToWindow () виджет диалога невидим
  4. Когда ViewRoot вычисляет прозрачную область, перекрывающаяся область считается невидимой, и тогда рисование области является неправильным.

Чтобы устранить эту проблему, пожалуйста, вызовите requestTransparentRegion, когда вы изменяете видимость виджета, если он не виден, когда SurfaceView присоединен к окну.

Например, вы можете вызвать mWidget.getParent (). RequestTransparentRegion (mSurfaceView).

Поскольку ViewRoot является корневым родителем иерархии представления, это будет иметь тот же эффект, что и вызов родительского объекта SurfaceView для запроса transparentRegion.

...