example - navegar entre fragments android studio
El fragmento de VideoView dentro provoca un parpadeo de la pantalla en negro (4)
Tenemos una aplicación de Android que se ejecuta en Android API 4.0. Una de las actividades tiene un diseño que divide la pantalla en 2 partes. En el lado izquierdo tenemos una parte estática con algunos botones. En el lado derecho tenemos un FrameLayout que cambiará al fragmento correspondiente dependiendo del botón que se presione.
Problema: uno de los fragmentos en el lado derecho contiene una VideoView. Cuando el usuario hace clic en el botón para mostrar este fragmento, se muestra el fragmento y, sin embargo, el video comienza inmediatamente a reproducirse: al reproducir este fragmento, la pantalla completa parpadea en negro, lo que es muy molesto.
Aquí hay un código de la clase VideoFragment:
public class VideoFragment extends Fragment {
public VideoView videoView;
private ExternalVideo mVideo;
private boolean mVideoExists;
private String mDestination;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDestination = ApplicationParams.MEDIA_STORAGE_PATH + "videos/"
+ FilenameUtils.getBaseName(((DetailActivity)getActivity()).getProduct().getVideoUrl())
+ "."
+ FilenameUtils.getExtension(((DetailActivity) getActivity()).getProduct().getVideoUrl());
File file = new File(mDestination);
mVideoExists = file.exists() && file.isFile();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view;
if (mVideoExists) {
getActivity().getWindow().setFormat(PixelFormat.TRANSLUCENT);
view = inflater.inflate(R.layout.video, null);
mVideo = new ExternalVideo(mDestination);
videoView = (VideoView) view.findViewById(R.id.video_video);
MediaController mediaController = new MediaController(getActivity());
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
videoView.setVideoPath(mVideo.getFullPath());
videoView.requestFocus();
videoView.setVisibility(View.VISIBLE);
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
videoView.start();
}
});
} else {
TextView textView = new TextView(getActivity());
textView.setText(getActivity().getString(R.string.videofragment_video_coming_soon));
textView.setPadding(50, 50, 50, 50);
view = textView;
}
return view;
}
}
Aquí está el diseño del fragmento de video:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<VideoView android:id="@+id/video_video"
android:layout_width="fill_parent"
android:layout_alignParentRight="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_height="fill_parent"/>
</RelativeLayout>
¿Alguien tiene una idea de qué podría estar causando este problema de parpadeo al representar el fragmento que contiene VideoView? ¡Una solución sería apreciada!
EDIT1: Si hago clic en el fragmento donde está VideoView en la pantalla parpadea al principio. Cuando navego hacia un fragmento anoter y vuelvo al que contiene el VideoView, el parpadeo desaparece.
KennyDs tiene razón, pero es mejor que ocultes el SurfaceView, de lo contrario tendrás un comportamiento realmente extraño si animas fragmentos, entonces no verás nada más que una pantalla negra en el lugar del fragmento animado. Afortunadamente, este problema colateral tiene una solución fácil también:
<SurfaceView
android:layout_width="0px"
android:layout_height="0px"
android:visibility="gone" />
Pude solucionar esto agregando un 0px por 0px SurfaceView en el diseño de la actividad principal del fragmento:
<SurfaceView
android:layout_width="0px"
android:layout_height="0px" />
Si se pregunta por qué agregar un SurfaceView de tamaño cero resuelve el problema, puede echarle un vistazo a esta pregunta. SurfaceView parpadea en negro al cargar . Lo explica bien
Citado de la respuesta de Evos
cuando la vista de superficie aparece en la ventana la primera vez, solicita el cambio de los parámetros de la ventana llamando a un método privado IWindowSession.relayout (..). Este método "le da" un nuevo marco, ventana y superficie de ventana. Creo que la pantalla parpadea en ese momento. La solución es bastante simple: si su ventana ya tiene los parámetros adecuados, no actualizará todas las cosas de la ventana y la pantalla no parpadeará. La solución más simple es agregar un SurfaceView de 0px de altura al primer diseño de su actividad. Esto recreará la ventana antes de que se muestre la actividad en la pantalla, y cuando configure su segundo diseño, simplemente continuará usando la ventana con los parámetros actuales.
Y aquí hay una forma más clara de resolver este problema, llámalo antes de llamar a setContentView (), que acaba de probarse en mi ViewPager con algunos fragmentos que contienen VideoView, funciona tan bien como agregar SurfaceView de tamaño cero:
getWindow().setFormat(PixelFormat.TRANSLUCENT);
Simplemente agregue el color de fondo transparente de VideoView
. Solucionará el problema.
android:background="@color/transparent"