【问题标题】:Set onclickLister in utube api在 youtube api 中设置 onclickListener
【发布时间】:2013-05-23 20:31:14
【问题描述】:

我正在使用 youtubeApi (https://developers.google.com/youtube/android/player/downloads/),我正在寻找在 VideoWall 上的视频上放置 onclick 监听器的解决方案..

package com.android.youbho.Activities;

import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import com.google.android.youtube.player.YouTubeInitializationResult;
import com.google.android.youtube.player.YouTubePlayer;
import com.google.android.youtube.player.YouTubePlayer.PlayerStyle;
import com.google.android.youtube.player.YouTubePlayerFragment;
import com.google.android.youtube.player.YouTubeThumbnailLoader;
import com.google.android.youtube.player.YouTubeThumbnailView;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.util.Pair;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.Toast;
import com.android.youbho.Utils.Constant;
import com.android.youbho.Utils.FlippingView;
import com.android.youbho.Utils.ImageWallView;

@SuppressLint("NewApi") public class VideoWallActivity extends Activity implements
FlippingView.Listener,
YouTubePlayer.OnInitializedListener,
YouTubeThumbnailView.OnInitializedListener{
    private static final int RECOVERY_DIALOG_REQUEST = 1;
    /** The player view cannot be smaller than 110 pixels high. */
    private static final float PLAYER_VIEW_MINIMUM_HEIGHT_DP = 110;
    private static final int MAX_NUMBER_OF_ROWS_WANTED = 4;
    // Example playlist from which videos are displayed on the video wall
    private static final String PLAYLIST_ID = "PLBA95EAD360E2B0D1";
    private static final int INTER_IMAGE_PADDING_DP = 5;
    // YouTube thumbnails have a 16 / 9 aspect ratio
    private static final double THUMBNAIL_ASPECT_RATIO = 16 / 9d;
    private static final int INITIAL_FLIP_DURATION_MILLIS = 100;
    private static final int FLIP_DURATION_MILLIS = 500;
    private static final int FLIP_PERIOD_MILLIS = 2000;
    private ImageWallView imageWallView;
    private Handler flipDelayHandler;
    private FlippingView flippingView;
    private YouTubeThumbnailView thumbnailView;
    private YouTubeThumbnailLoader thumbnailLoader;
    private YouTubePlayerFragment playerFragment;
    private View playerView;
    private YouTubePlayer player;
    private Dialog errorDialog;
    private int flippingCol;
    private int flippingRow;
    private int videoCol;
    private int videoRow;
    private boolean nextThumbnailLoaded;
    private boolean activityResumed;
    private State state;
    private static final int id_videoPlayer=99;

    private enum State {
        UNINITIALIZED,
        LOADING_THUMBNAILS,
        VIDEO_FLIPPED_OUT,
        VIDEO_LOADING,
        VIDEO_CUED,
        VIDEO_PLAYING,
        VIDEO_ENDED,
        VIDEO_BEING_FLIPPED_OUT,
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
      View view = convertView;
      Toast.makeText(getApplicationContext(), "lol:" + position, Toast.LENGTH_LONG).show();


      return view;
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB) @SuppressLint("NewApi") @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        state = State.UNINITIALIZED;

        ViewGroup viewFrame = new FrameLayout(this);
        DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
        int maxAllowedNumberOfRows = (int) Math.floor((displayMetrics.heightPixels / displayMetrics.density) / PLAYER_VIEW_MINIMUM_HEIGHT_DP);
        int numberOfRows = Math.min(maxAllowedNumberOfRows, MAX_NUMBER_OF_ROWS_WANTED);
        int interImagePaddingPx = (int) displayMetrics.density * INTER_IMAGE_PADDING_DP;
        int imageHeight = (displayMetrics.heightPixels / numberOfRows) - interImagePaddingPx;
        int imageWidth = (int) (imageHeight * THUMBNAIL_ASPECT_RATIO);

        imageWallView = new ImageWallView(this, imageWidth, imageHeight, interImagePaddingPx);
        viewFrame.addView(imageWallView, MATCH_PARENT, MATCH_PARENT);

        thumbnailView = new YouTubeThumbnailView(this);
        thumbnailView.initialize(Constant.DEVELOPER_KEY, this);

        flippingView = new FlippingView(this, this, imageWidth, imageHeight);
        flippingView.setFlipDuration(INITIAL_FLIP_DURATION_MILLIS);
        viewFrame.addView(flippingView, imageWidth, imageHeight);

        playerView = new FrameLayout(this);
        playerView.setId(id_videoPlayer);
        playerView.setVisibility(View.INVISIBLE);
        viewFrame.addView(playerView, imageWidth, imageHeight);

        playerFragment = YouTubePlayerFragment.newInstance();
        playerFragment.initialize(Constant.DEVELOPER_KEY, this);
        getFragmentManager().beginTransaction().add(id_videoPlayer, playerFragment).commit();

        flipDelayHandler = new FlipDelayHandler();

        setContentView(viewFrame);
    }

    @Override
    public void onInitializationSuccess(YouTubeThumbnailView thumbnailView, YouTubeThumbnailLoader thumbnailLoader) {
        thumbnailView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getApplicationContext(), "lol! ", Toast.LENGTH_LONG).show();

            }
        });
        this.thumbnailLoader = thumbnailLoader;
        thumbnailLoader.setOnThumbnailLoadedListener(new ThumbnailListener());
        maybeStartDemo();
    }

    @Override
    public void onInitializationFailure(YouTubeThumbnailView thumbnailView, YouTubeInitializationResult errorReason) {
        if (errorReason.isUserRecoverableError()) {
            if (errorDialog == null || !errorDialog.isShowing()) {
                errorDialog = errorReason.getErrorDialog(this, RECOVERY_DIALOG_REQUEST);
                errorDialog.show();
            }
        } else {
            String errorMessage = String.format( errorReason.toString());
            Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player, boolean wasResumed) {
        VideoWallActivity.this.player = player;
        player.setPlayerStyle(PlayerStyle.CHROMELESS);
        player.setPlayerStateChangeListener(new VideoListener());
        maybeStartDemo();
    }

    @Override
    public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult errorReason) {
        if (errorReason.isUserRecoverableError()) {
            if (errorDialog == null || !errorDialog.isShowing()) {
                errorDialog = errorReason.getErrorDialog(this, RECOVERY_DIALOG_REQUEST);
                errorDialog.show();
            }
        } else {
            String errorMessage = String.format( errorReason.toString());
            Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
        }
    }

    private void maybeStartDemo() {
        if (activityResumed && player != null && thumbnailLoader != null && state.equals(State.UNINITIALIZED)) {
            thumbnailLoader.setPlaylist(PLAYLIST_ID); // loading the first thumbnail will kick off demo         
            state = State.LOADING_THUMBNAILS;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == RECOVERY_DIALOG_REQUEST) {
            // Retry initialization if user performed a recovery action
            if (errorDialog != null && errorDialog.isShowing()) {
                errorDialog.dismiss();
            }
            errorDialog = null;
            playerFragment.initialize(Constant.DEVELOPER_KEY, this);
            thumbnailView.initialize(Constant.DEVELOPER_KEY, this);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        activityResumed = true;
        if (thumbnailLoader != null && player != null) {
            if (state.equals(State.UNINITIALIZED)) {
                maybeStartDemo();
            } else if (state.equals(State.LOADING_THUMBNAILS)) {
                loadNextThumbnail();
            } else {
                if (state.equals(State.VIDEO_PLAYING)) {
                    player.play();
                }
                flipDelayHandler.sendEmptyMessageDelayed(0, FLIP_DURATION_MILLIS);
            }
        }
    }

    @Override
    protected void onPause() {
        flipDelayHandler.removeCallbacksAndMessages(null);
        activityResumed = false;
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        if (thumbnailLoader != null) {
            thumbnailLoader.release();
        }
        super.onDestroy();
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB) private void flipNext() {
        if (!nextThumbnailLoaded || state.equals(State.VIDEO_LOADING)) {
            return;
        }

        if (state.equals(State.VIDEO_ENDED)) {
            flippingCol = videoCol;
            flippingRow = videoRow;
            state = State.VIDEO_BEING_FLIPPED_OUT;
        } else {
            Pair<Integer, Integer> nextTarget = imageWallView.getNextLoadTarget();
            flippingCol = nextTarget.first;
            flippingRow = nextTarget.second;
        }

        flippingView.setX(imageWallView.getXPosition(flippingCol, flippingRow));
        flippingView.setY(imageWallView.getYPosition(flippingCol, flippingRow));
        flippingView.setFlipInDrawable(thumbnailView.getDrawable());
        flippingView.setFlipOutDrawable(imageWallView.getImageDrawable(flippingCol, flippingRow));
        imageWallView.setImageDrawable(flippingCol, flippingRow, thumbnailView.getDrawable());
        imageWallView.hideImage(flippingCol, flippingRow);
        flippingView.setVisibility(View.VISIBLE);
        flippingView.flip();
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB) @Override
    public void onFlipped(FlippingView view) {
        imageWallView.showImage(flippingCol, flippingRow);
        flippingView.setVisibility(View.INVISIBLE);

        if (activityResumed) {
            loadNextThumbnail();

            if (state.equals(State.VIDEO_BEING_FLIPPED_OUT)) {
                state = State.VIDEO_FLIPPED_OUT;
            } else if (state.equals(State.VIDEO_CUED)) {
                videoCol = flippingCol;
                videoRow = flippingRow;
                playerView.setX(imageWallView.getXPosition(flippingCol, flippingRow));
                playerView.setY(imageWallView.getYPosition(flippingCol, flippingRow));
                imageWallView.hideImage(flippingCol, flippingRow);
                playerView.setVisibility(View.VISIBLE);
                player.play();
                state = State.VIDEO_PLAYING;
            } else if (state.equals(State.LOADING_THUMBNAILS) && imageWallView.allImagesLoaded()) {
                state = State.VIDEO_FLIPPED_OUT; // trigger flip in of an initial video
                flippingView.setFlipDuration(FLIP_DURATION_MILLIS);
                flipDelayHandler.sendEmptyMessage(0);
            }
        }
    }

    private void loadNextThumbnail() {
        nextThumbnailLoaded = false;
        if (thumbnailLoader.hasNext()) {
            thumbnailLoader.next();
        } else {
            thumbnailLoader.first();
        }
    }

    /**
     * A handler that periodically flips an element on the video wall.
     */
    @SuppressLint("HandlerLeak")
    private final class FlipDelayHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            flipNext();
            sendEmptyMessageDelayed(0, FLIP_PERIOD_MILLIS);
        }

    }

    /**
     * An internal listener which listens to thumbnail loading events from the
     * {@link YouTubeThumbnailView}.
     */
    private final class ThumbnailListener implements YouTubeThumbnailLoader.OnThumbnailLoadedListener {
        @Override
        public void onThumbnailLoaded(YouTubeThumbnailView thumbnail, String videoId) {
            nextThumbnailLoaded = true;

            if (activityResumed) {
                if (state.equals(State.LOADING_THUMBNAILS)) {
                    flipNext();
                } else if (state.equals(State.VIDEO_FLIPPED_OUT)) {
                    // load player with the video of the next thumbnail being flipped in
                    state = State.VIDEO_LOADING;
                    player.cueVideo(videoId);
                }
            }
        }

        @Override
        public void onThumbnailError(YouTubeThumbnailView thumbnail, YouTubeThumbnailLoader.ErrorReason reason) {
            loadNextThumbnail();
        }

    }

    private final class VideoListener implements YouTubePlayer.PlayerStateChangeListener {

        @Override
        public void onLoaded(String videoId) {
            state = State.VIDEO_CUED;
        }

        @Override
        public void onVideoEnded() {
            state = State.VIDEO_ENDED;
            imageWallView.showImage(videoCol, videoRow);
            playerView.setVisibility(View.INVISIBLE);
        }

        @Override
        public void onError(YouTubePlayer.ErrorReason errorReason) {
            if (errorReason == YouTubePlayer.ErrorReason.UNEXPECTED_SERVICE_DISCONNECTION) {
                // player has encountered an unrecoverable error - stop the demo
                flipDelayHandler.removeCallbacksAndMessages(null);
                state = State.UNINITIALIZED;
                thumbnailLoader.release();
                thumbnailLoader = null;
                player = null;
            } else {
                state = State.VIDEO_ENDED;
            }
        }

        // ignored callbacks

        @Override
        public void onVideoStarted() { }

        @Override
        public void onAdStarted() { }

        @Override
        public void onLoading() { }

    }
}

这样,播放列表中有一个视频列表,每个视频会在第一个视频播放完毕后自动开始播放。我需要点击墙上的每个视频来启动它

【问题讨论】:

    标签: java android youtube


    【解决方案1】:

    您可以在 ImageWallView.java 类中的 ImageViews 中添加一个 onClickListener,如下所示:

    for (int col = 0; col < numberOfColumns; col++) {
      for (int row = 0; row < numberOfRows; row++) {
        int elementIdx = getElementIdx(col, row);
        if (images[elementIdx] == null) {
          ImageView thumbnail = new ImageView(context);
          thumbnail.setLayoutParams(new LayoutParams(imageWidth, imageHeight));
          images[elementIdx] = thumbnail;
          unInitializedImages.add(elementIdx);
          thumbnail.setOnClickListener(new OnClickListener() {
    
              @Override
              public void onClick(View v) {
                  ImageWallView.this.context.startActivity(YouTubeIntents.createPlayVideoIntentWithOptions(
                          ImageWallView.this.context, (String)v.getTag(), true, false));
              }
          });
        }
        addView(images[elementIdx]);
      }
    }
    

    然后您需要在 VideoWallActivity.java

    YouTubeThumbnailView 中添加视频 id 作为标签

    希望有帮助

    【讨论】:

      【解决方案2】:

      您可以按照上一个答案中的建议使用 ImageView OnClickListener:(ImageWallView.java 中的 onSizeChanged)

      for (int col = 0; col < numberOfColumns; col++) {
        for (int row = 0; row < numberOfRows; row++) {
          int elementIdx = getElementIdx(col, row);
          if (images[elementIdx] == null) {
            ImageView thumbnail = new ImageView(context);
            thumbnail.setLayoutParams(new LayoutParams(imageWidth, imageHeight));
            images[elementIdx] = thumbnail;
            unInitializedImages.add(elementIdx);
            thumbnail.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    ImageWallView.this.context.startActivity(YouTubeIntents.createPlayVideoIntentWithOptions(
                            ImageWallView.this.context, (String)v.getTag(), true, false));
                }
            });
      
          }
          addView(images[elementIdx]);
        }
      }     
      

      然后您需要将视频 id 存储到 ImageWallView 的调用视图。 (set 和 get 标记也用于在视图之间存储对象)。 要获取 ImageWallView 的子视图,请使用 imageWallView.getChildAt(index)。 index 是在 ImageWallView 上点击的 ImageView 的位置。要获取此索引,请使用 getElementIdx(col,row)。您需要在 ImageWallView.java 中公开此方法。

      已编辑

      要使用当前缩略图的视频 ID,请将 VideoID 存储在 onFlipped 事件中。这是因为 onThumbnailLoaded 下一个可用缩略图的 VideoID 立即被翻转并在 IamgeWallView 上可用。由于 VideoID 在 onFlipped 事件中不可用,请在 onThumbnailLoaded 事件中使用它

      这里是: 在类中声明下面的字符串

      private String strThumbnailVideoId;
      

      将 onThumbnailLoaded 事件(在 VideoWallActivity.java 中)中的 VideoID 设置为 strThumbnailVideoId。此视频 ID 将是下一个将被翻转的缩略图。

      @Override
      public void onThumbnailLoaded(YouTubeThumbnailView thumbnail, String videoId) {
        nextThumbnailLoaded = true;      
        strThumbnailVideoId = videoId;
        if (activityResumed) {
          if (state.equals(State.LOADING_THUMBNAILS)) {
            flipNext();
          } else if (state.equals(State.VIDEO_FLIPPED_OUT)) {
            // load player with the video of the next thumbnail being flipped in
            state = State.VIDEO_LOADING;
            player.cueVideo(videoId);
          }
        }
      }
      

      现在将 onFlipped 中的 strThumbnailVideoId 设置为 ImageWallView 标记。

      @Override
      public void onFlipped(FlippingView view) {
      imageWallView.showImage(flippingCol, flippingRow);
      flippingView.setVisibility(View.INVISIBLE);
      imageWallView.getChildAt(imageWallView.getElementIdx(flippingCol,     flippingRow)).setTag(strThumbnailVideoId);     
      ......
      ......
      

      【讨论】:

      • 嘿,这很好用。但是,它会加载下一个翻转视频而不是当前视频。我错过了什么:)?
      • 查看帖子的已编辑部分。希望这能解决你的疑问。要使用当前缩略图的视频 ID,请将 VideoID 存储在 onFlipped 事件中。这是因为 onThumbnailLoaded 下一个可用缩略图的 VideoID 立即被翻转并在 IamgeWallView 上可用。由于 VideoID 在 onFlipped 事件中不可用,请在 onThumbnailLoaded 事件中使用它。
      • 太棒了;)我很笨。谢谢。我还有一个问题,如何检测视频是否播放完毕,并让播放器自动关闭?我确实看到了'public void onVideoEnded() { state = State.VIDEO_ENDED; imageWallView.showImage(videoCol, videoRow); playerView.setVisibility(View.INVISIBLE); }' 调用,但它在 MainActivity 中,似乎不起作用。
      • 没关系,这很简单。足以将这一行中的 False 参数更改为 true ImageWallView.this.context, (String)v.getTag(), true, false (here true)))
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-12
      • 2016-04-10
      • 2013-07-15
      • 2011-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多