YouTubePlayerSupportFragment en el elemento ListView es nulo
Estoy tratando de utilizar un YouTubePlayerSupportFragment
en un elemento ListView
. El ListView
está dentro de un Fragment
que está en una Activity
. Como hay fragmentos anidados, estoy usando el método getChildFragmentManager()
para intentar encontrar el fragmento del diseño XML. Aquí está el código.
Java
- Reproducir video de Youtube en segundo plano usando el reproductor de youtube api
- Añadir fragmento en un fragmento (fragmento anidado)
- ¿Hay una versión HD (Higher Quality) .3gp de vídeo en youtube para los jugadores de HTML?
- Vídeo incrustado de youtube en el dispositivo táctil que muestra el menú contextual del botón derecho
- YouTubePlayerFragment no funciona (Reproduciendo) en CollapsingToolbarLayout
convertView = inflater.inflate(R.layout.youtube_post_layout, null); YouTubePlayerSupportFragment youTubePlayerFragment = (YouTubePlayerSupportFragment) getChildFragmentManager().findFragmentById(R.id.youtube_video); if (youTubePlayerFragment == null) { Log.i("YouTube", "player is null"); } else { Log.i("YouTube", youTubePlayerFragment.toString()); }
XML
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <include layout="@layout/post_base_layout" /> <fragment android:name="com.google.android.youtube.player.YouTubePlayerSupportFragment" android:id="@+id/youtube_video" android:layout_width="match_parent" android:layout_height="240dp" android:layout_marginLeft="62dp" android:layout_marginRight="32dp" android:background="@color/light_grey" android:cropToPadding="true" android:padding="1dp" android:scaleType="centerCrop" /> <include layout="@layout/post_bottom_layout" /> </LinearLayout>
El problema es que cuando intento crear el fragmento haciendo findFragmentById()
para obtenerlo del XML, devuelve null, y eso es lo que se registra en el rastreo de la pila.
Estoy intentando seguir las muestras de la API de YouTube y realizar los cambios necesarios para los fragmentos anidados, pero no puedo averiguar qué está causando el problema.
- YotubePlayerSupportFragment vista de pantalla completa en modo horizontal
- Cómo terminar YoutubeStandAlonePlayer después de completar el video en Android?
- Cómo utilizar Youtube Player con UI moderna en Android usando YoutubePlayerSupportFragment
- Obtener todas las ID de video de la lista de reproducción de YouTube
- Android webview html5 vídeo autoplay no funciona en android 4.0.3
- No se pueden reproducir algunos vídeos de Youtube con la API de reproductor de YouTube para Android
- Youtube SDK se bloquea con DeadObjectException cuando se mueve a la aplicación de youtube
- Heredando ActionBarSherlock y Android YouTubePlayer
Hay problemas con todo el enfoque que ha tomado.
En primer lugar, inflar fragmentos secundarios directamente desde un XML no es compatible . Cuando anida fragmentos, debe agregarlos dinámicamente usando getChildFragmentManager
en el fragmento padre.
En segundo lugar, incluso si funcionó (y podría en algunos casos), ha inflado la vista pero no la ha agregado al diseño del fragmento real. Eso es lo que el segundo y tercer parámetro en el método de inflate
están ahí para. El FragmentManager
buscará el fragmento en su disposición actual, o evento en el backstack, pero no puede encontrar fragmentos inflados en un XML aleatorio y nunca poner en uso.
Por último, y lo más importante, nunca debe agregar fragmentos como elementos en un ListView
. Los fragmentos esperan tener un ciclo de vida vinculado a la Actividad en la que se encuentran, mientras que un ListView
, o cualquier AdapterView
en general, creará, destruirá y reciclará a sus hijos según sea necesario.
Soluciones posibles:
-
¿Cuántos videos necesitas en tu lista? Si no hay muchos de ellos, un ScrollView + LinearLayout podría ser la solución más fácil.
-
Si realmente necesita ver el reciclaje, tal vez usted puede hacer sin vídeo en vivo en cada fila? Considere la posibilidad de utilizar YouTubeThumbnailView en sus filas, luego redirigir a su usuario a otra actividad / cargar un video en un solo
YoutubeFragment
situado fuera de la lista en su diseño. -
Si definitivamente quieres que los videos se reproduzcan directamente en cada fila de la lista, necesitarás usar YoutubePlayerView en lugar de fragmentos en el diseño de la fila. En este caso, lea atentamente la documentación, ya que tendrá que manejar la inicialización de vídeo y ver el reciclaje usted mismo.
Su aplicación se bloqueará Cuando intente inflar la vista con el mismo Fragment
cada elemento ListView
(como la duplicación en id de fragmento como este concurso )
Hay dos solución (uno de ellos de respuesta @ivagarz ):
1- Puedes mostrar solo un video de youtube Usando YouTubePlayerView
encima de tu ListView
en tu presentación de Activity
Pero tu Activity
debe extender YouTubeBaseActivity
Al igual que YouTube Player API de Android Doc (Creo que esta solución no te ayudará a resolver tu problema)
2- puedes usar YouTubeThumbnailView
para mostrar youtube Imagen en miniatura del video para cada elemento en ListView
con el botón del reproductor youtube sobre youtube Imagen en miniatura utilizada para mostrar vídeo.
Al igual que la siguiente foto:
Cuando el usuario haga clic en el botón del reproductor youtube, tiene dos formas:
Primera opción con YouTubePlayerSupportFragment
: puede reemplazar YouTubeThumbnailView
con YouTubePlayerSupportFragment
Si toma esta opción debe:
A- Añada YouTubePlayerSupportFragment
programática al vuelo (para evitar la duplicación en Fragment
Id).
B- Mostrar sólo un video en su ListView
Como respuesta a esta pregunta .
Ej :
list_item.xml
layout para el elemento ListView
:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/parent_relativeLayout" android:layout_width="match_parent" android:layout_height="match_parent" > <com.google.android.youtube.player.YouTubeThumbnailView android:id="@+id/youtube_thumbnail" android:layout_width="fill_parent" android:layout_height="250dp" android:scaleType="centerCrop" android:visibility="gone"/> <RelativeLayout android:id="@+id/relativeLayout_over_youtube_thumbnail" android:layout_width="fill_parent" android:layout_height="250dp" android:background="@color/color_background_transparent" android:visibility="gone"> <ImageView android:id="@+id/btnYoutube_player" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="center" android:src="@drawable/youtube_player"/> </RelativeLayout> </RelativeLayout>
En getView
mehtod del adaptador ListView
:
public View getView(int position, View convertView, ViewGroup parent) { convertView = inflator.inflate(R.layout.list_item.xml, parent, false); final RelativeLayout relativeLayoutOverYouTubeThumbnailView = (RelativeLayout) convertView.findViewById(R.id.relativeLayout_over_youtube_thumbnail); final YouTubeThumbnailView youTubeThumbnailView = (YouTubeThumbnailView) convertView.findViewById(R.id.youtube_thumbnail); // get parent relative layout RelativeLayout parentRelativeLayout = (RelativeLayout) convertView.findViewById(R.id.parent_relativeLayout); // then create dynamic FrameLayout FrameLayout.LayoutParams dynamicFrameLayoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT); final FrameLayout dynamicFrameLayout = new FrameLayout(ctx); dynamicFrameLayout.setId(Different_ID); dynamicFrameLayout.setLayoutParams(dynamicFrameLayoutParams); // then add dynamic FrameLayout as children in parent relative layout parentRelativeLayout.addView(dynamicFrameLayout); ImageView youtubePlayerButton = (ImageView) convertView.findViewById(R.id.btnYoutube_player); youtubePlayerButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { View parentView = (View) v.getParent().getParent(); YouTubeThumbnailView youTubeThumbnailView = (YouTubeThumbnailView) parentView.findViewById(R.id.youtube_thumbnail); RelativeLayout relativeLayoutOverYouTubeThumbnailView = (RelativeLayout) parentView.findViewById(R.id.relativeLayout_over_youtube_thumbnail); youTubeThumbnailView.setVisibility(View.GONE); relativeLayoutOverYouTubeThumbnailView.setVisibility(View.GONE); YouTubeFragment youTubeFragment = new YouTubeFragment(); youTubeFragment.youTubeFragmentInitialize(VideoID, youTubeFragment, parentView); getSupportFragmentManager() .beginTransaction() .replace(dynamicFrameLayout.getId(), youTubeFragment) .commit(); } }); final YouTubeThumbnailLoader.OnThumbnailLoadedListener onThumbnailLoadedListener = new YouTubeThumbnailLoader.OnThumbnailLoadedListener(){ @Override public void onThumbnailError(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader.ErrorReason errorReason) { } @Override public void onThumbnailLoaded(YouTubeThumbnailView youTubeThumbnailView, String s) { loadingImage.setVisibility(View.GONE); youTubeThumbnailView.setVisibility(View.VISIBLE); relativeLayoutOverYouTubeThumbnailView.setVisibility(View.VISIBLE); } }; youTubeThumbnailView.initialize(API_KEY, new YouTubeThumbnailView.OnInitializedListener() { @Override public void onInitializationSuccess(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader youTubeThumbnailLoader) { youTubeThumbnailLoader.setVideo(VideoID); youTubeThumbnailLoader.setOnThumbnailLoadedListener(onThumbnailLoadedListener); } @Override public void onInitializationFailure(YouTubeThumbnailView youTubeThumbnailView, YouTubeInitializationResult youTubeInitializationResult) { } }); }
Me crearon mi propio Fragment
extiende desde YouTubePlayerSupportFragment
:
public class YouTubeFragment extends YouTubePlayerSupportFragment { public void youTubeFragmentInitialize(final String videoId, final YouTubeFragment fragment, final View parent) { fragment.initialize(apiKey, new YouTubePlayer.OnInitializedListener() { @Override public void onInitializationSuccess(YouTubePlayer.Provider provider, final YouTubePlayer youTubePlayer, boolean wasRestored) { youTubePlayer.setShowFullscreenButton(false); if (!wasRestored) { youTubePlayer.loadVideo(videoId); } } @Override public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) { Log.e("app", youTubeInitializationResult.toString()); } }); } }
La segunda opción con YouTubeStandalonePlayer
o la creación de tu propia Activity
amplía YouTubeBaseActivity
: justo cuando el usuario haga clic en el botón del reproductor de youtube, puedes crear una intención para abrir una nueva actividad para mostrar vídeo
Intent intent = YouTubeStandalonePlayer.createVideoIntent(context, YOUR_DEVELOPER_KEY, VIDEO_ID); startActivity(intent);
- Cómo llamar a invalidate () tarde a ViewPager
- Consultas multi tabla utilizando Azure Mobile Services y android