android - 在 Android 上的 XML 布局文件中为 VideoView 设置 imageUrl
问题描述
我有一个从网站下载 JSON 输入的应用程序,该网站返回图片或视频的 URI。我没有问题让我的 MaterialCardView 通过 ImageView 显示图片。我的计划是设置一个覆盖 VideoView,仅当特定项目是视频类型时才可见。这是 2 个视图的 XML:
<ImageView
android:id="@+id/picture_image"
android:layout_width="377dp"
android:layout_height="429dp"
android:layout_marginBottom="84dp"
android:adjustViewBounds="true"
android:contentDescription="@string/nasa_pictures_list_id"
android:padding="2dp"
android:scaleType="centerCrop"
app:imageUrl="@{picture.imgSrcUrl}"
app:layout_constraintBottom_toTopOf="@+id/picture_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.47"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_conversion_absoluteHeight="191dp"
tools:layout_conversion_absoluteWidth="411dp"
tools:src="@tools:sample/backgrounds/scenic" />
<!-- android:visibility="@{picture.image ? View.VISIBLE : View.GONE}"-->
<VideoView
android:id="@+id/picture_video"
android:layout_width="377dp"
android:layout_height="429dp"
android:layout_marginBottom="84dp"
android:adjustViewBounds="true"
android:contentDescription="@string/nasa_pictures_list_id"
android:padding="2dp"
android:scaleType="centerCrop"
app:imageUrl="@{picture.imgSrcUrl}"
app:layout_constraintBottom_toTopOf="@+id/picture_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.47"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_conversion_absoluteHeight="191dp"
tools:layout_conversion_absoluteWidth="411dp"
tools:src="@tools:sample/backgrounds/scenic" />
<!-- android:visibility="@{picture.video ? View.VISIBLE : View.GONE}"-->
我现在注释掉了 android:visibility 代码。
我的问题是 VideoView 有一个编译错误,app:imageUrl="@{picture.imgSrcUrl}"
它在前面的 ImageView 上工作得很好。错误是:
Cannot find a setter for <android.widget.VideoView app:imageUrl> that accepts parameter type 'java.lang.String'
好的,我明白了,它不喜欢字符串。
- 我的问题是它喜欢什么
- 如何在 XML 布局文件中指定它?
感谢页面
解决方案
我得出的结论是,您不能通过 XML 文件执行此操作。我找不到一个这样做的例子。我所做的是修改我在SampleVideoView
高级 Android 培训中找到的代码,该代码有效,可以在此处找到;https://github.com/google-developer-training/android-advanced/tree/master/SimpleVideoView
首先,我在我的应用程序中创建了一个 Java 类,如下所示:
public class VideoViewAdapter {
private String VIDEO_SAMPLE =
"https://images.all-free-download.com/footage_preview/mp4/rocket_launch_cape_caneveral_nasa_535.mp4";
private Context mContext;
private VideoView mVideoView;
// Current playback position (in milliseconds).
private int mCurrentPosition = 0;
// Tag for the instance state bundle.
private static final String PLAYBACK_TIME = "play_time";
public void initVideo(Context context, VideoView videoView) {
// Set up the media controller widget and attach it to the video view.
mVideoView = videoView;
MediaController controller = new MediaController(context);
controller.setMediaPlayer(mVideoView);
mVideoView.setMediaController(controller);
mContext = context;
}
public void initializePlayer(VideoView videoView,String url, int position) {
if(url!=null) VIDEO_SAMPLE = url;
if(position!=0) mCurrentPosition = position;
mVideoView = videoView;
// Buffer and decode the video sample.
Uri videoUri = getMedia(VIDEO_SAMPLE);
mVideoView.setVideoURI(videoUri);
// Listener for onPrepared() event (runs after the media is prepared).
mVideoView.setOnPreparedListener(
new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
// Restore saved position, if available.
if (mCurrentPosition > 0) {
mVideoView.seekTo(mCurrentPosition);
} else {
// Skipping to 1 shows the first frame of the video.
mVideoView.seekTo(1);
}
// Start playing!
mVideoView.start();
}
});
// Listener for onCompletion() event (runs after media has finished
// playing).
mVideoView.setOnCompletionListener(
new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
Toast.makeText(mContext,
R.string.toast_message,
Toast.LENGTH_SHORT).show();
// Return the video position to the start.
mVideoView.seekTo(0);
}
});
}
// Release all media-related resources. In a more complicated app this
// might involve unregistering listeners or releasing audio focus.
public void releasePlayer() {
mVideoView.stopPlayback();
}
// Get a Uri for the media sample regardless of whether that sample is
// embedded in the app resources or available on the internet.
private Uri getMedia(String mediaName) {
if (URLUtil.isValidUrl(mediaName)) {
// Media name is an external URL.
return Uri.parse(mediaName);
} else {
// Media name is a raw resource embedded in the app.
return Uri.parse("android.resource://" + mContext.getPackageName() +
"/raw/" + mediaName);
}
}
}
这为我提供了一个视图适配器,我可以像这样在 MainActivity 顶部实例化它:
现在在科特林:
.
.
.
lateinit var VIDEOADAPTOR: VideoViewAdapter
.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
.
.
.
VIDEOADAPTOR = VideoViewAdapter()
然后在 Fragment 类文件中为布局片段。我将以下代码放在 onBindViewHolder 覆盖下的 RecyclerView.Adapter 类中。
class DailyPictureAdapter(val callback: PictureClick) : RecyclerView.Adapter<DailyPictureViewHolder>() {
.
.
.
/**
* Called by RecyclerView to display the data at the specified position. This method should
* update the contents of the {@link ViewHolder#itemView} to reflect the item at the given
* position.
*/
override fun onBindViewHolder(holder: DailyPictureViewHolder, position: Int) {
holder.viewDataBinding.also {
it.picture = pictures[position]
it.pictureCallback = callback
if(pictures[position].isVideo) {
VIDEOADAPTOR.initVideo(context, it.pictureVideo)
VIDEOADAPTOR.initializePlayer(it.pictureVideo,it.pictureVideo.pictures[position].imgSrcUrl, 0)
}
}
holder.itemView.setOnClickListener{ callback.onClick(pictures[position])}
}
}
作为 Recycler View 的一部分,它在 Video View 中播放了视频。不错但是....
我的问题是内存使用。对于我的应用程序,一次有 15 到 25 条记录,其中只有少数是视频,这不存在问题。但是,如果这是一个视频列表,我认为我们会很快发现内存问题。
当资源滚出视野时,我找不到释放资源的好地方。如果有人可以对此发表评论,请这样做。
推荐阅读
- php - 将变量而不是硬编码数据传递给贝宝立即购买按钮
- javascript - 如何在允许访问 JavaScript 中的 DOM 和库函数的同时安全地评估代码
- java - Checkmarx 扫描报告 Springboot 应用程序中 main 方法的剩余调试代码
- google-sheets - 如何遍历Google表格中文件的所有表格?
- python - 如何在 PyQt5 中的视频上绘制/动画透明图像/对象?
- python - django 模板脚本部分中 object_list 的元素
- javascript - 使用“子进程”从 python 脚本中检索数据适用于普通 node.js 脚本,但不适用于必需的脚本
- c# - 流布局面板的 C# 上下文菜单
- asp.net - Asp.net 页面显示此站点无法访问页面
- ios - 如何在 StoreKit 中跟踪购买的商品?