[TUT] Click item in a ListView to show YouTube Video

By blundell  

Following on from the popular ‘Show YouTube Feed for a Users Videos in a ListView’ someone requested that when you click on one of the individual videos in the list that it links off to the YouTube video.

This in itself this is quite simple, but getting the architecture right and having the data you need in the right place takes a little bit of thought.

Using an interface it’s possible to do all the logic within the custom ListView we have written but still allow the Activity to receive the callback and do whatever it wants with the video i.e. start a video viewing Intent.

This blog post is going to brush over the basics of populating the ListView (as this is done in the previously mentioned tutorial) and just talk about how you can add a custom listener to your ListView that sends back to the activity the data for each row.

The whole source code is linked at the bottom of the post and I am just going to talk about the relevant code for the click listener here.

Firstly we need to define an Interface, interfaces allow you to declare that your class can do something but it leaves the implementation up to the class. i.e. if you had an Interface called “Move” and a method called “useLegs()” you could add this interface to your Activity. The activity can now be called by other classes that want to “Move” and they will call the useLegs method. The powerful thing is, it’s up to your activity what happens in the useLegs() method! It could have robot legs .. four legs … run or hop, it doesn’t matter its up to you!

If you don’t quite get that take a look at this. Here is the interface we have made for a special video listener:


package com.blundell.tut.ui;

import com.blundell.tut.domain.Video;

public interface VideoClickListener {

	public void onVideoClicked(Video video);
	
}

It’s declaring it is a VideoClickListener and wants you to implement a method called onVideoClicked. So that means if you implement this interface you will have to react to some type of video being clicked and you get passed the video.
(This sounds great if we were passed the video that was clicked from the list ;-) ).

Now that we have the interface there are two things we need to do. The activity needs to implement the interface (to receive calls to the onVideoClicked method) and also something needs to send those calls.

Let’s send the calls first. In our custom ListView we create a reference to this interface then when the list is clicked we simply call the method. It makes much more sense in practice, look:

package com.blundell.tut.ui.widget;

import java.util.List;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;

import com.blundell.tut.domain.Video;
import com.blundell.tut.ui.VideoClickListener;
import com.blundell.tut.ui.adapter.VideosAdapter;

/**
 * @author paul.blundell
 */
public class VideosListView extends ListView implements android.widget.AdapterView.OnItemClickListener {

	private List<Video> videos;
	private VideoClickListener videoClickListener;

	public VideosListView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	public VideosListView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public VideosListView(Context context) {
		super(context);
	}

	public void setVideos(List<Video> videos){
		this.videos = videos;
		VideosAdapter adapter = new VideosAdapter(getContext(), videos);
		setAdapter(adapter);
		// When the videos are set we also set an item click listener to the list
		// this will callback to our custom list whenever an item it pressed
		// it will tell us what position in the list is pressed
		setOnItemClickListener(this);
	}
	
	// Calling this method sets a listener to the list
	// Whatever class is passed in will be notified when the list is pressed
	// (The class that is passed in just has to 'implement VideoClickListener'
	// meaning is has the methods available we want to call)
	public void setOnVideoClickListener(VideoClickListener l) {
		videoClickListener = l;
	}
	
	@Override
	public void setAdapter(ListAdapter adapter) {
		super.setAdapter(adapter);
	}

	// When we receive a notification that a list item was pressed
	// we check to see if a video listener has been set
	// if it has we can then tell the listener 'hey a video has just been clicked' also passing the video
	@Override
	public void onItemClick(AdapterView<?> adapter, View v, int position, long id) {
		if(videoClickListener != null){
			videoClickListener.onVideoClicked(videos.get(position));
		}
	}
}

So thats it when your ListView is clicked it will tell whatever is listening that it has been clicked and pass the video! However nothing is listening yet we need to update our activity:

package com.blundell.tut.ui.phone;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;

import com.blundell.tut.R;
import com.blundell.tut.domain.Library;
import com.blundell.tut.domain.Video;
import com.blundell.tut.service.task.GetYouTubeUserVideosTask;
import com.blundell.tut.ui.VideoClickListener;
import com.blundell.tut.ui.widget.VideosListView;

/**
 * The Activity can retrieve Videos for a specific username from YouTube</br>
 * It then displays them into a list including the Thumbnail preview and the title</br>
 * There is a reference to each video on YouTube as well but this isn't used in this tutorial</br>
 * </br>
 * <b>Note<b/> orientation change isn't covered in this tutorial, you will want to override
 * onSaveInstanceState() and onRestoreInstanceState() when you come to this
 * </br>
 * @author paul.blundell
 */
public class MainActivity extends Activity implements VideoClickListener {
    // A reference to our list that will hold the video details
	private VideosListView listView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        listView = (VideosListView) findViewById(R.id.videosListView);
        // Here we are adding this activity as a listener for when any row in the List is 'clicked'
        // The activity will be sent back the video that has been pressed to do whatever it wants with
        // in this case we will retrieve the URL of the video and fire off an intent to view it
        listView.setOnVideoClickListener(this);
    }

    public void getUserYouTubeFeed(View v){
    	new Thread(new GetYouTubeUserVideosTask(responseHandler, "blundellp")).start();
    }
   
	Handler responseHandler = new Handler() {
		public void handleMessage(Message msg) {
			populateListWithVideos(msg);
		};
	};

	private void populateListWithVideos(Message msg) {
		Library lib = (Library) msg.getData().get(GetYouTubeUserVideosTask.LIBRARY);
		listView.setVideos(lib.getVideos());
	}
	
	@Override
	protected void onStop() {
		responseHandler = null;
		super.onStop();
	}

	// This is the interface method that is called when a video in the listview is clicked!
	// The interface is a contract between this activity and the listview
	@Override
	public void onVideoClicked(Video video) {
		Intent intent = new Intent(Intent.ACTION_VIEW);
		intent.setData(Uri.parse(video.getUrl()));
		startActivity(intent);
	}
}

Hope I’ve made it clear enough. Now when the list is clicked our activity knows about it. Not only does it know though, it also is passed the video that has been clicked letting us act upon it.

All source code has been commented to help you out!

Enjoy!

Eclipse Source Project – User Feed YouTube Click Through Tut


14 Comments

  1. captin
    Posted May 8, 2013 at 10:45 am | Permalink | Reply

    hi, great work dude,but when I click any video it just goes to YouTube main page.I see that someone else is having the same issue,and you replied him “Hmm maybe they aren’t allowed on mobile, or the url is incorrect?” how is that not allowed ? how could the url be incorrect I use my correct name and also the video thumbnails do appear in the listview which I think means URL is correct!!!Am I right dude?

  2. suvinay
    Posted February 22, 2013 at 12:48 pm | Permalink | Reply

    Hi i had succesful found a code and modified it to streamyoutube videos within the appusingyoutbe api..how do integrate it here?

    • blundell
      Posted February 25, 2013 at 2:05 pm | Permalink | Reply

      Checkout the adapter, using onClick, pass the url to your streamer

  3. GoftZzz
    Posted January 2, 2013 at 2:46 pm | Permalink | Reply

    what the android version that you test? In my version, all videos are go to main page of youtube “http://m.youtube.com./#/home”

    • blundell
      Posted January 3, 2013 at 9:45 am | Permalink | Reply

      Hmm really? Android 4.0 should be fine

  4. venkat
    Posted December 28, 2012 at 9:56 am | Permalink | Reply

    where we add video url”s in the code. how change the videos. click on video then it goes to main page. how to avois it.

  5. Coder
    Posted October 31, 2012 at 2:47 pm | Permalink | Reply

    why do some videos go to youtube main page

    • blundell
      Posted November 1, 2012 at 9:30 am | Permalink | Reply

      Hmm maybe they aren’t allowed on mobile, or the url is incorrect?

  6. Alice
    Posted August 23, 2012 at 12:22 am | Permalink | Reply

    This tutorial and the “Show YouTube Feed for a Users Videos in a ListView” was such a great help. Really awesome!. Thanks!

  7. ram
    Posted June 21, 2012 at 5:14 am | Permalink | Reply

    i got force close exception when i test your code on emulator!! everything i check all permission ,nd all dat!!! when i try to run this source code on emulator its getting force close. can u tel me iz it work perfectly when i test it on real device.

    • blundell
      Posted June 21, 2012 at 7:10 am | Permalink | Reply

      Hi Ram, please check what the error is in LogCat and what Android version your emulator is running as this code should work perfectly

  8. hardik
    Posted June 20, 2012 at 7:12 am | Permalink | Reply

    Thank you soooo much. Its a very useful.

  9. Posted May 28, 2012 at 7:07 am | Permalink | Reply

    Thank you so much for this tutorial. Love your work & style. I purchase from play often, I’ll now do so through your link :)
    Bind all of your tutorials together, sell them as an ebook! Thank you for sharing!

    • Posted May 29, 2012 at 6:31 am | Permalink | Reply

      In Columbo style, one more thing… would you know why some videos open to a default youtube list, when they actually exist?
      Thanks again for sharing

Post a Comment

Your email is never shared. Required fields are marked *

*
*