我正在尝试创建一个自定义表面视图,每次视图出现在屏幕上时,视图都会自行开始播放视频。我想知道当视图显示在 UI 上并被用户看到时,会通知 View 中的什么方法。我正在使用 viewpager,因此 SurfaceCreated 不起作用,因为视图是在它们显示在屏幕上之前创建的。
1 回答
当视频出现在屏幕上时,如何在视图寻呼机中自动启动视频
这是根本问题。OP,明智地,想尝试隔离它的点,在某种意义上“出现在屏幕上”。问题是这可能意味着很多事情:
当我第一次听到这个问题时,我认为一个很好的案例是onAttachedToWindow
- 查看文档。对于根据原始标题阅读此问题的人来说,这就是您想要的。
大多数情况下,视图会在 Activity 的 onCreate 中膨胀并创建(例如,如果您使用了 setContentView)。
OP 对 surfaceCreated 回调也没有运气。因此,我们在上面的评论中考虑了 OP 是否会对三个抽签阶段感兴趣layout
,measure
并且draw
。在 android 中实际“在屏幕上放置视图”有两个阶段 - 测量和布局通道 - 请参见此处。
问题是,原来 OP 正在将他的视图动画到屏幕上,所以问题变成了如何判断动画后视图何时“到达”屏幕上。
重要的一点是:您实际上想在绘图过程中检测到更晚的阶段,这是可以理解的!动画通过许多调用来工作,而这些调用invalidate
又需要许多draw
s 用于该视图Canvas
- 所以您想要播放视频的阶段绝不是视图首次显示在 UI 中的时候。
这种特殊情况的解决方案。
在您的实例上使用动画侦听ViewAnimator
器(例如ViewPager
)。为了不必在活动中打扰它们,我会推出你自己的视图,然后使用Adapter
Android 非常喜欢的类型模式来管理不断变化的数据:
一个非常仓促的实现将是:
public class VideoStartingViewFliper extends ViewFlipper {
private final Animation fromRight;
private final Animation toLeft;
private final Animation fromLeft;
private final Animation toRight;
private VideoViewAdapter mAdapter;
public VideoStartingViewFliper(final Context context, final AttributeSet attrs) {
super(context, attrs);
fromRight = new YourChoiceOfAnimation();
fromRight.setAnimationListener(videoStartingAnimationListener);
toLeft = new YourChoiceOfAnimation();
toLeft.setAnimationListener(videoStartingAnimationListener);
fromLeft = new YourChoiceOfAnimation();
fromLeft.setAnimationListener(videoStartingAnimationListener);
toRight = new YourChoiceOfAnimation();
toRight.setAnimationListener(videoStartingAnimationListener);
}
static interface VideoViewAdapter {
public String getVideoPath(int childId);
}
public void setVideoViewAdapter(final VideoViewAdapter adapter) {
mAdapter = adapter;
}
// or even call this showNextVideo and don't override!
@Override
public void showNext() {
setInAnimation(fromRight);
setOutAnimation(toLeft);
super.showNext();
}
@Override
public void showPrevious() {
setInAnimation(fromLeft);
setOutAnimation(toRight);
super.showPrevious();
}
private final AnimationListener videoStartingAnimationListener = new AnimationListener() {
@Override
public void onAnimationStart(final Animation animation) {
final VideoView video = ((VideoView) getCurrentView());
video.stopPlayback();
}
@Override
public void onAnimationRepeat(final Animation animation) {
}
@Override
public void onAnimationEnd(final Animation animation) {
final VideoView video = ((VideoView) getCurrentView());
// check null here!
video.setVideoPath(mAdapter.getVideoPath(getCurrentView().getId()));
video.start();
}
};
}
希望这可以帮助。