- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我想在水平 ScrollView 中显示多个 YouTube 视频。为此,我正在动态添加 YouTubePlayerFragments。这是我的代码 fragment :
//set videos
int count = 0;
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
for (final Video video : mVideos) {
//create an instance of a video fragment
final VideoFragment fragment = new VideoFragment();// VideoFragment extends YouTubePlayerFragment
Bundle bundle = new Bundle();
if (null != mVideos && 0 < mVideos.size()) {
bundle.putString(VideoFragment.KEY_VIDEO_KEY, video.getKey());
}
fragment.setArguments(bundle);
FrameLayout frameLayout = new FrameLayout(getActivity());
frameLayout.setLayoutParams(new FrameLayout.LayoutParams(900, 500));
frameLayout.setPadding(10, 0, 10, 0);
frameLayout.setId(12345 + ++count);
mLayoutTrailers.addView(frameLayout);//mLayoutTrailers is a LinearLayout inside my Horizontal ScrollView
transaction.add(frameLayout.getId(), fragment, VideoFragment.TAG + count);
}
transaction.commit();
我正在我的 VideoFragment 的 OnResume 中初始化 youtube 播放器。下面是视频的加载方式。
它显示了所有玩家最后加载的视频。我调试了 - 它用第一个视频初始化所有播放器,然后用第二个视频初始化所有播放器等等,直到最后一个。
The issue is already discussed here.在我的 VideoFragment 中的“setUserVisibleHint(boolean isVisibleToUser)”中初始化播放器似乎可以解决这个问题,而不是使用 OnResume(),但我不知道如何将它用于我的 HorizontalScrollView
有没有办法在 Horizontal ScrollView 中加载多个 YouTube 视频?
我们将不胜感激任何形式的帮助!
最佳答案
我认为不可能创建多个 YouTube Player Fragment 实例,因为它是 Singleton
。
无论你创建了多少个实例,它们都是一样的,你的水平 ScrollView 将显示你添加的最后一个 VideoFragment 的缩略图。
或者,您可以通过显示视频拇指并点击拇指在 youtube 播放器的帮助下播放视频来产生多个 YouTube fragment 的错觉
// get thumbnail image of that video by videoID
String videoThumbUrl="http://img.youtube.com/vi/"+videoId+"/0.jpg";
//Load thumb in viewpager/Hrizontal scrollview/Recycle View with the
//help of Picasso/Glide/UIL etc
Picasso.with(getActivity())
.load(videoThumbUrl)
.into(videoThumbImageView);
然后单击拇指,您可以在包含 imageview 的 View 容器中添加 youtube fragment ,并开始使用视频 ID 播放视频
videoThumbImageView.setOnClickListenr(..)
{...
//Add Youtube fragment in container and start playing video
}
这只是一个伪代码,但你明白了。
编辑
添加了有关如何在点击缩略图时播放和停止视频的代码。
我处于离线状态,因此无法使用 YouTube fragment ,所以我使用 Videoview 播放随机视频,您可以用 YouTube fragment 替换 videoview 和。保证它仍然很好用
保存视频列表的数组列表
public static ArrayList<VideoModel> listOfVideos = new ArrayList<>();
跟踪当前播放视频的变量
// Allows to remember the last item shown on screen
private int lastPosition = 0;
Recycler 查看元素点击监听
videoGridAdapter.setOnCardClickListner(new VideoGridAdapter.OnCardClickListner() {
@Override
public void OnCardClicked(View view, int position) {
//Make Lats Tapped item playing false
listOfVideos.get(lastPosition).setPlaying(false);
//Make current Tapped item playing true
listOfVideos.get(position).setPlaying(true);
// update pointer of last tapped video to current tapped video
lastPosition = position;
//LET RCYCLERVIEW ADAPTER DO THE MAGIC
videoGridAdapter.notifyDataSetChanged();
}
});
视频模型类
**
* Created by Hitesh on 20-07-2016.
*/
public class VideoModel {
public int getImageURLTest() {
return imageURLTest;
}
//Test Data
private int imageURLTest;
//Real Time Data
private String videoURL;
private String imageURL;
private boolean isPlaying;
public VideoModel(String videoURL, boolean isSelected, int imageURLTest) {
this.videoURL = videoURL;
this.isPlaying = isSelected;
this.imageURLTest = imageURLTest;
}
public boolean isPlaying() {
return isPlaying;
}
public void setPlaying(boolean playing) {
isPlaying = playing;
}
/**
* @return Youtube URl of Video
*/
public String getVideoURL() {
return videoURL;
}
/**
* @return Thumbnail of Video using video ID
*/
public String getImageURL() {
//Derive Image URl from Video URl using Video ID
return imageURL;
}
}
适配器本身
import android.content.Context;
import android.media.MediaPlayer;
import android.net.Uri;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import com.hiteshsahu.videoinraw.R;
import com.hiteshsahu.videoinraw.ui.activity.VideoGridActivity;
import com.squareup.picasso.Callback;
import com.squareup.picasso.NetworkPolicy;
import com.squareup.picasso.Picasso;
public class VideoGridAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private OnCardClickListner onCardClickListner;
public VideoGridAdapter() {
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
RecyclerView.ViewHolder viewHolder;
context = parent.getContext();
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.video_row, parent, false);
// set the view's size, margins, paddings and layout parameters
viewHolder = new VideoViewHolder(v);
return viewHolder;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
VideoViewHolder videoHolder = (VideoViewHolder) holder;
if (VideoGridActivity.listOfVideos.get(position).isPlaying()) {
//Playing Video :- Show VideoView and make play button GONE
((VideoViewHolder) holder).getVideoView().setVisibility(View.VISIBLE);
((VideoViewHolder) holder).getPlayButton().setVisibility(View.GONE);
//Play Video in video View
((VideoViewHolder) holder).getVideoView().setVisibility(View.VISIBLE);
((VideoViewHolder) holder).getVideoView().setVideoURI(Uri.parse(VideoGridActivity.listOfVideos.get(position).getVideoURL()));
// MediaControlandroid.widget.VideoView videoView = (VideoView) headerView.findViewById(R.id.vdo_banner);ler md = new MediaController(getActivity());
((VideoViewHolder) holder).getVideoView().setMediaController(null);
((VideoViewHolder) holder).getVideoView().requestFocus();
// videoView.setZOrderOnTop(true);
((VideoViewHolder) holder).getVideoView().start();
((VideoViewHolder) holder).getVideoView().setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
return true;
}
});
((VideoViewHolder) holder).getVideoView().setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
mp.setLooping(true);
}
});
} else {
//Not playing make videoview gone and show play button
((VideoViewHolder) holder).getVideoView().setVisibility(View.GONE);
((VideoViewHolder) holder).getPlayButton().setVisibility(View.VISIBLE);
}
//set thumbnail image using video url
Picasso.with(context)
.load(VideoGridActivity.listOfVideos.get(position).getImageURL()).fit().placeholder(VideoGridActivity.listOfVideos.get(position).getImageURLTest())
.networkPolicy(NetworkPolicy.OFFLINE).fit()
.centerCrop()
.into(((VideoViewHolder) holder).getVideoThumb(), new Callback() {
@Override
public void onSuccess() {
}
@Override
public void onError() {
// Try again online if cache failed
Picasso.with(context)
.load(VideoGridActivity.listOfVideos.get(position).getImageURL()).fit().placeholder(VideoGridActivity.listOfVideos.get(position).getImageURLTest())
.centerCrop()
.into(((VideoViewHolder) holder).getVideoThumb());
}
});
((VideoViewHolder) holder).getContainer().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onCardClickListner.OnCardClicked(v, position);
}
});
}
@Override
public int getItemCount() {
return VideoGridActivity.listOfVideos.size();
}
public void setOnCardClickListner(OnCardClickListner onCardClickListner) {
this.onCardClickListner = onCardClickListner;
}
public interface OnCardClickListner {
void OnCardClicked(View view, int position);
}
}
主要布局 Activity
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".ui.activity.VideoGridActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/video_grid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:foregroundGravity="center"
app:layout_behavior="@string/appbar_scrolling_view_behavior"></android.support.v7.widget.RecyclerView>
</RelativeLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_dialer" />
</android.support.design.widget.CoordinatorLayout>
回收站查看项目
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root_container"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_margin="5dp">
<ImageView
android:id="@+id/video_thumb"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY" />
<VideoView
android:id="@+id/video_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:visibility="gone" />
<!--Add a mask over video thumbnail with a play button icon-->
<RelativeLayout
android:id="@+id/play_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#68472986">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:src="@android:drawable/ic_media_play" />
</RelativeLayout>
</FrameLayout>
关于android - Horizontal ScrollView 中的多个 YouTubePlayerFragments - 所有播放器都显示最后加载的视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38400015/
我想要显示正在加载的 .gif,直到所有内容都已加载,包括嵌入的 iframe。但是,目前加载 gif 会在除 iframe 之外的所有内容都已加载后消失。我怎样才能让它等到 iframe 也加载完毕
首先,这是我第一次接触 Angular。 我想要实现的是,我有一个通知列表,我必须以某种方式限制 limitTo,因此元素被限制为三个,在我单击按钮后,其余的应该加载。 我不明白该怎么做: 设置“ V
我正在尝试在我的设备上运行这个非常简单的应用程序(使用 map API V2),并且出于某种原因尝试使用 MapView 时: 使用 java 文件: public class MainMap e
我正在使用 Python 2.6、Excel 2007 Professional 和最新版本的 PyXLL。在 PyXLL 中加载具有 import scipy 抛出异常,模块未加载。有没有人能够在
我想做这个: 创建并打包原始游戏。然后我想根据原始游戏中的蓝图创建具有新网格/声音/动画和蓝图的其他 PAK 文件。原始游戏不应该知道有关其他网格/动画/等的任何信息。因此,我需要在原始游戏中使用 A
**摘要:**在java项目中经常会使用到配置文件,这里就介绍几种加载配置文件的方法。 本文分享自华为云社区《【Java】读取/加载 properties配置文件的几种方法》,作者:Copy工程师。
在 Groovy 脚本中是否可以执行条件导入语句? if (test){ import this.package.class } else { import that.package.
我正在使用 NVidia 视觉分析器(来自 CUDA 5.0 beta 版本的基于 eclipse 的版本)和 Fermi 板,我不了解其中两个性能指标: 全局加载/存储效率表示实际内存事务数与请求事
有没有办法在通过 routeProvider 加载特定 View 时清除 Angular JS 存储的历史记录? ? 我正在使用 Angular 创建一个公共(public)安装,并且历史会积累很多,
使用 Xcode 4.2,在我的应用程序中, View 加载由 segue 事件触发。 在 View Controller 中首先调用什么方法? -(void) viewWillAppear:(BOO
我在某些Django模型中使用JSONField,并希望将此数据从Oracle迁移到Postgres。 到目前为止,当使用Django的dumpdata和loaddata命令时,我仍然没有运气来保持J
创建 Nib 时,我需要创建两种类型:WindowNib 或 ViewNib。我看到的区别是,窗口 Nib 有一个窗口和一个 View 。 如何将 View Nib 加载到另一个窗口中?我是否必须创建
我想将多个env.variables转换为静态结构。 我可以手动进行: Env { is_development: env::var("IS_DEVELOPMENT")
正如我从一个测试用例中看到的:https://godbolt.org/z/K477q1 生成的程序集加载/存储原子松弛与普通变量相同:ldr 和 str 那么,宽松的原子变量和普通变量之间有什么区别吗
我有一个重定向到外部网站的按钮/链接,但是外部网站需要一些时间来加载。所以我想添加一个加载屏幕,以便外部页面在显示之前完全加载。我无法控制外部网站,并且外部网站具有同源策略,因此我无法在 iFrame
我正在尝试为我的应用程序开发一个Dockerfile,该文件在初始化后加载大量环境变量。不知何故,当我稍后执行以下命令时,这些变量是不可用的: docker exec -it container_na
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我刚刚遇到一个问题,我有一个带有一些不同选项的选择标签。 现在我想检查用户选择了哪些选项。 然后我想将一个新的 html 文件加载到该网站(取决于用户选中的选项)宽度 javascript,我该怎么做
我知道两种保存/加载应用程序设置的方法: 使用PersistentStore 使用文件系统(存储,因为 SDCard 是可选的) 我想知道您使用应用程序设置的做法是什么? 使用 PersistentS
我开始使用 Vulkan 时偶然发现了我的第一个问题。尝试创建调试报告回调时(验证层和调试扩展在我的英特尔 hd vulkan 驱动程序上可用,至少它是这么说的),它没有告诉我 vkCreateDeb
我是一名优秀的程序员,十分优秀!