YouTubePlayerFragment 可以在 ViewPager 中使用吗?如果没有替代方案?
Can a YouTubePlayerFragment be used in a ViewPager? Alternatives if not?
我想要一个包含 2 或 3 个 YouTube 视频的小视图,嵌入在更宽的布局中(仅限平板电脑)。用户应该能够在视频之间切换(同时保持在相同的 Activity/screen)。是否可以使用 YouTubePlayerFragment 执行此操作?
到目前为止似乎还没有(这里有一个 relevant bug report,但由于尚未对其发表评论,因此还不是确定的 'no')。
单独使用 YouTubePlayerFragment 工作正常,但我在 ViewPager 中遇到了零星的各种问题(其中:未指定的连接问题,没有 YoutubePlayer 回调发生;每个片段显示相同的缩略图;没有回调的空白视图或其他反馈)。
这是从玩具测试项目中提取的一些代码。我可能为此 post 引入了错误编辑,并且为了清晰起见,我跳过了配置更改处理等:
public class MainActivityFragment extends Fragment {
private static String API_KEY = "something";
public MainActivityFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
final ViewPager viewPager = (ViewPager) rootView.findViewById(R.id.viewPager);
TabLayout tabLayout = (TabLayout) rootView.findViewById(R.id.tabLayout);
Adapter adapter = new Adapter(getChildFragmentManager());
viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);
return rootView;
}
class Adapter extends FragmentStatePagerAdapter {
private String[] getVids(){
return new String[]{"ORgucLTtTDI", "WzQ2RvSLR4o","dQw4w9WgXcQ"};
}
public Adapter(final FragmentManager fm) {
super(fm);
}
@Override
public android.support.v4.app.Fragment getItem(final int position) {
YouTubePlayerSupportFragment fragment = new YouTubePlayerSupportFragment();
fragment.initialize(API_KEY, new YouTubePlayer.OnInitializedListener() {
@Override
public void onInitializationSuccess(final YouTubePlayer.Provider provider,
final YouTubePlayer youTubePlayer,
final boolean b) {
youTubePlayer.cueVideo(getVids()[position]);
}
return fragment;
}
@Override
public int getCount() {
return getVids().length;
}
@Override
public CharSequence getPageTitle(final int position) {
return getVids()[position] + " [" + position + "]";
}
}
}
我想知道的是:
- 我是不是做错了什么导致了这些错误?
- 如果不是(即 YouTubePlayerFragment 的错误或限制),是否有解决方法?
- 如果不是(即我对这种方法一无所知),什么可能是值得探索的替代方案?我正在拉票的一些是:
- viewpager 的一些更高级的用法。例如。使用单个 YouTubePlayerFragment 实例,在页面切换时将其放入 ViewPager,然后重新调用。
- 完全跳过 ViewPager。手动实例化 YouTubePlayerFragments 并将其切换为 FrameLayout
- YouTube 播放器的替代品API。也许是香草 VideoView,或 ExoPlayer(尽管它仅支持 API > 15 可能是一个障碍)
我有一个可行的(如果不是理想的)解决方案。这个问题似乎是由于当 ViewPager 将不同的片段滑入到位时,来自前一个片段的流连接仍然打开。
我的解决办法是切换ViewPager时在旧的YoutubePlayer上调用.reset()
,然后在新的YoutubePlayer上再次调用.initialize()
。这需要响应 TabLayout 的 onTabSelected
事件,这意味着我不能使用 .setupWithViewPager
(它吞噬了 ViewPager 和 TabLayouts 视图更改事件)。这大致是适配器中需要的(initialisePlayer
和 shutDownPlayer
被调用以响应选项卡更改,在设置适配器的片段中,ViewPager 和 TabLayout):
private SparseArray<YouTubePlayerSupportFragment> fragments = new SparseArray<>(3);
private SparseArray<YouTubePlayer> players = new SparseArray<>(3);
@Override
public android.support.v4.app.Fragment getItem(final int position) {
YouTubePlayerSupportFragment fragment = new YouTubePlayerSupportFragment();
fragments.put(position, fragment);
return fragment;
}
public void initialisePlayer(final int position) {
YouTubePlayerSupportFragment fragment = fragments.get(position);
fragment.initialize(API_KEY, new YouTubePlayer.OnInitializedListener() {
@Override
public void onInitializationSuccess(final YouTubePlayer.Provider provider, final YouTubePlayer youTubePlayer, final boolean b) {
players.put(position, youTubePlayer);
youTubePlayer.cueVideo(getVids()[position]);
}
@Override
public void onInitializationFailure(final YouTubePlayer.Provider provider, final YouTubeInitializationResult youTubeInitializationResult) {
}
});
}
public void shutDownPlayer(int position) {
YouTubePlayer player = players.get(position);
if (player == null) {
return;
}
player.release();
}
这种方法的缺点:
- 需要存储对 YouTubePlayerSupportFragments 和 YouTubePlayers 的引用
- 标签在每个开关上重新初始化
如果出现任何更好的解决方案,我愿意接受。
我想要一个包含 2 或 3 个 YouTube 视频的小视图,嵌入在更宽的布局中(仅限平板电脑)。用户应该能够在视频之间切换(同时保持在相同的 Activity/screen)。是否可以使用 YouTubePlayerFragment 执行此操作?
到目前为止似乎还没有(这里有一个 relevant bug report,但由于尚未对其发表评论,因此还不是确定的 'no')。
单独使用 YouTubePlayerFragment 工作正常,但我在 ViewPager 中遇到了零星的各种问题(其中:未指定的连接问题,没有 YoutubePlayer 回调发生;每个片段显示相同的缩略图;没有回调的空白视图或其他反馈)。
这是从玩具测试项目中提取的一些代码。我可能为此 post 引入了错误编辑,并且为了清晰起见,我跳过了配置更改处理等:
public class MainActivityFragment extends Fragment {
private static String API_KEY = "something";
public MainActivityFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
final ViewPager viewPager = (ViewPager) rootView.findViewById(R.id.viewPager);
TabLayout tabLayout = (TabLayout) rootView.findViewById(R.id.tabLayout);
Adapter adapter = new Adapter(getChildFragmentManager());
viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);
return rootView;
}
class Adapter extends FragmentStatePagerAdapter {
private String[] getVids(){
return new String[]{"ORgucLTtTDI", "WzQ2RvSLR4o","dQw4w9WgXcQ"};
}
public Adapter(final FragmentManager fm) {
super(fm);
}
@Override
public android.support.v4.app.Fragment getItem(final int position) {
YouTubePlayerSupportFragment fragment = new YouTubePlayerSupportFragment();
fragment.initialize(API_KEY, new YouTubePlayer.OnInitializedListener() {
@Override
public void onInitializationSuccess(final YouTubePlayer.Provider provider,
final YouTubePlayer youTubePlayer,
final boolean b) {
youTubePlayer.cueVideo(getVids()[position]);
}
return fragment;
}
@Override
public int getCount() {
return getVids().length;
}
@Override
public CharSequence getPageTitle(final int position) {
return getVids()[position] + " [" + position + "]";
}
}
}
我想知道的是:
- 我是不是做错了什么导致了这些错误?
- 如果不是(即 YouTubePlayerFragment 的错误或限制),是否有解决方法?
- 如果不是(即我对这种方法一无所知),什么可能是值得探索的替代方案?我正在拉票的一些是:
- viewpager 的一些更高级的用法。例如。使用单个 YouTubePlayerFragment 实例,在页面切换时将其放入 ViewPager,然后重新调用。
- 完全跳过 ViewPager。手动实例化 YouTubePlayerFragments 并将其切换为 FrameLayout
- YouTube 播放器的替代品API。也许是香草 VideoView,或 ExoPlayer(尽管它仅支持 API > 15 可能是一个障碍)
我有一个可行的(如果不是理想的)解决方案。这个问题似乎是由于当 ViewPager 将不同的片段滑入到位时,来自前一个片段的流连接仍然打开。
我的解决办法是切换ViewPager时在旧的YoutubePlayer上调用.reset()
,然后在新的YoutubePlayer上再次调用.initialize()
。这需要响应 TabLayout 的 onTabSelected
事件,这意味着我不能使用 .setupWithViewPager
(它吞噬了 ViewPager 和 TabLayouts 视图更改事件)。这大致是适配器中需要的(initialisePlayer
和 shutDownPlayer
被调用以响应选项卡更改,在设置适配器的片段中,ViewPager 和 TabLayout):
private SparseArray<YouTubePlayerSupportFragment> fragments = new SparseArray<>(3);
private SparseArray<YouTubePlayer> players = new SparseArray<>(3);
@Override
public android.support.v4.app.Fragment getItem(final int position) {
YouTubePlayerSupportFragment fragment = new YouTubePlayerSupportFragment();
fragments.put(position, fragment);
return fragment;
}
public void initialisePlayer(final int position) {
YouTubePlayerSupportFragment fragment = fragments.get(position);
fragment.initialize(API_KEY, new YouTubePlayer.OnInitializedListener() {
@Override
public void onInitializationSuccess(final YouTubePlayer.Provider provider, final YouTubePlayer youTubePlayer, final boolean b) {
players.put(position, youTubePlayer);
youTubePlayer.cueVideo(getVids()[position]);
}
@Override
public void onInitializationFailure(final YouTubePlayer.Provider provider, final YouTubeInitializationResult youTubeInitializationResult) {
}
});
}
public void shutDownPlayer(int position) {
YouTubePlayer player = players.get(position);
if (player == null) {
return;
}
player.release();
}
这种方法的缺点:
- 需要存储对 YouTubePlayerSupportFragments 和 YouTubePlayers 的引用
- 标签在每个开关上重新初始化
如果出现任何更好的解决方案,我愿意接受。