2013-04-04 35 views
5

Tôi đang cố gắng sử dụng một YouTubePlayerSupportFragment trong một mục ListView. ListView nằm trong một số Fragment nằm trong số Activity. Vì có các đoạn lồng nhau, tôi đang sử dụng phương thức getChildFragmentManager() để cố gắng tìm đoạn từ bố cục XML. Đây là mã.YouTubePlayerSupportFragment trong mục ListView là null

Java

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> 

Vấn đề là khi tôi cố gắng để tạo ra các đoạn bằng cách làm findFragmentById() để có được nó từ XML, nó sẽ trả về null, và đó là những gì được đăng lên dấu vết ngăn xếp.

Tôi đang cố gắng làm theo các mẫu API YouTube và thực hiện các thay đổi cần thiết cho các đoạn lồng nhau nhưng tôi không thể tìm hiểu nguyên nhân gây ra sự cố.

+0

Bạn có thể chia sẻ đầu ra của lệnh này 'adb shell dumpsys activity '? Nó chứa danh sách các mảnh vỡ hoạt động và được thêm vào. –

+0

bạn có sử dụng các đoạn thư viện hỗ trợ không? – Yuraj

+0

Có. Tôi có các mảnh thư viện hỗ trợ. –

Trả lời

3

Có vấn đề với toàn bộ cách tiếp cận bạn đã thực hiện.

Đầu tiên, các đoạn mã con lạm phát trực tiếp từ XML là not supported. Khi lồng các mảnh, bạn phải thêm chúng bằng cách sử dụng getChildFragmentManager trong đoạn gốc.

Thứ hai, ngay cả khi nó hoạt động (và có thể trong một số trường hợp), bạn đã tăng lượt xem nhưng không thêm nó vào bố cục của đoạn thực tế. Đó là những gì các second and third parameters trong phương pháp inflate có cho. Các FragmentManager sẽ tìm mảnh trong bố trí hiện tại của nó, hoặc sự kiện trong backstack, nhưng không thể tìm thấy fragments thổi phồng trong một XML ngẫu nhiên và không bao giờ đưa vào sử dụng.

Cuối cùng và quan trọng nhất, bạn không bao giờ nên thêm các đoạn như các mục trong một ListView. Các mảnh vỡ mong đợi có vòng đời gắn liền với Hoạt động mà chúng đang có, trong khi ListView, hoặc bất kỳ AdapterView nói chung, sẽ tạo ra, phá hủy và tái chế các con của nó khi cần thiết.

giải pháp có thể:

  • bao nhiêu video bạn cần trong danh sách của bạn? Nếu không có nhiều người trong số họ, một ScrollView + LinearLayout thực sự có thể là giải pháp đơn giản nhất.

  • Nếu bạn thực sự cần Xem tái chế, có thể bạn có thể làm mà không có video trực tiếp trong mỗi hàng? Cân nhắc sử dụng một số YouTubeThumbnailView trong hàng của bạn, sau đó chuyển hướng người dùng của bạn đến một hoạt động khác/tải video trong một YoutubeFragment duy nhất nằm bên ngoài danh sách trên bố cục của bạn.

  • Nếu bạn chắc chắn muốn video phát trực tiếp trên mọi hàng trong danh sách, bạn sẽ cần phải sử dụng YoutubePlayerView thay vì các đoạn trên bố cục hàng của bạn. Trong trường hợp này, hãy đọc kỹ tài liệu, bởi vì bạn sẽ cần phải xử lý việc khởi tạo video và xem tự tái chế.

+0

Tôi đã cố gắng sử dụng YouTubePlayerView bên trong chế độ xem danh sách nhưng có sự cố xảy ra khi khởi chạy cho mỗi hàng. Sau đó, tôi cũng đã thử listview với YouTubePlayerSupportFragment nhưng cùng một cách khi hàng đợi video nó thay đổi vị trí để tải video. Nó không được tải trong mỗi hàng. bạn có thể chia sẻ bất kỳ ví dụ nào cho mỗi hàng phát video trực tiếp hay không. –

1

ứng dụng của bạn sẽ sụp đổ Khi bạn cố gắng để thổi phồng xem với cùng Fragment mỗi ListView mục (Như sự trùng lặp trong id mảnh như quiz này)

Có hai giải pháp (một trong số họ từ @ivagarz câu trả lời):

1- bạn có thể chỉ hiển thị một video youtube Sử dụng YouTubePlayerView trên ListView của bạn vào Activity bố trí của bạn Nhưng Activity Phải của bạn kéo dài YouTubeBaseActivity Giống như YouTube Android Player API Doc (I Think Giải pháp này sẽ không giúp bạn giải quyết vấn đề của mình)

2- bạn có thể sử dụng YouTubeThumbnailView để hiển thị hình thu nhỏ của hình ảnh của video cho mỗi mục vào ListView bằng nút trình phát youtube trên youtube Hình thu nhỏ được sử dụng để hiển thị video.

Giống như Các Hình tiếp theo:

enter image description here

Khi tài nhấp chuột vào nút nghe nhạc youtube, bạn có hai cách:

Đầu tiên tùy chọn sử dụng YouTubePlayerSupportFragment: bạn có thể thay thế YouTubeThumbnailView với YouTubePlayerSupportFragment Nếu bạn chọn Tùy chọn này, bạn phải:

A- thêm YouTubePlayerSupportFragment lập trình trên Fly (để tránh trùng lặp ở số Fragment Id).

B- Chỉ hiển thị một video vào ListView của bạn là answer of this Question.

Ex:

list_item.xml bố trí cho ListView mục:

<?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> 

trong getView mehtod của ListView adapter:

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

      } 
     }); 
} 

tôi đã được tạo ra riêng tôi Fragment kéo dài từ 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()); 
      } 
     }); 
    } 
} 

Second tùy chọn sử dụng YouTubeStandalonePlayer hoặc tạo riêng của bạn Activity kéo dài YouTubeBaseActivity: Chỉ khi người dùng bấm vào nút nghe nhạc youtube, bạn có thể tạo một Intent để mở hoạt động mới để hiển thị video

Intent intent = YouTubeStandalonePlayer.createVideoIntent(context, YOUR_DEVELOPER_KEY, VIDEO_ID); 
startActivity(intent); 
+0

Tuyệt vời +100, bạn là giải thích tuyệt vời cho điểm 1 –