0

ビューが画面に表示されるたびに、ビューが独自にビデオの再生を開始するカスタム surfaceview を作成しようとしています。ビューがUIに表示され、ユーザーに表示されたときに、ビュー内のどのメソッドが通知されるのか疑問に思っていました。ビューページャーを使用しているため、画面に表示される前にビューが作成されるため、SurfaceCreated は機能しません。

4

1 に答える 1

1

画面に表示されたときにビューページャーでビデオを自動的に開始する方法

これが根本的な問題でした。OPは、賢明なことに、ある意味で「画面に表示される」ポイントを分離しようとしました。問題は、これが多くのことを意味する可能性があることです:

最初に質問を聞いたとき、良いケースだと思いましたonAttachedToWindow- see the docs . 元のタイトルに基づいてこの質問を読んでいる人にとって、これはあなたが望むものです.

ほとんどの場合、ビューはインフレートされ、アクティビティの onCreate で作成されます (たとえば、setContentView を使用した場合)。

OP は、surfaceCreated コールバックでもうまくいきませんでした。そのため、上記のコメントで、OP が 3 つのドロー ステージに関心があるかどうかを検討しlayoutましmeasuredraw。Android で実際に「画面にビューを配置する」には、測定とレイアウト パスの 2 つの段階があります

問題は、OPが自分のビューを画面にアニメーション化していたことが判明したため、アニメーション後にビューが画面に「到着」したことをどのように伝えるかという問題になりました。

重要な点は、実際には、描画プロセスのかなり後の段階でステージを検出したかったということです。これは理解できます! アニメーションは多くの呼び出しで機能し、そのビューに対してinvalidate多くの が必要になります。そのため、ビデオを再生する段階は、ビューが UI に最初に表示されたときではありません。drawCanvas

この特定のシナリオのソリューション

インスタンスでアニメーション リスナーを使用しViewAnimatorます (例: ViewPager)。アクティビティでそれらに煩わされる必要がないように、独自のビューを展開し、AdapterAndroid が非常に好む型パターンを使用して、常に変化するデータを管理します。

非常に急いで書かれた実装は次のようになります。

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();
    }
};
}

お役に立てれば。

于 2013-07-24T17:57:00.700 に答える