Skip to main content

YouTube API V3 for Android

Official Website for YouTube API V3 https://developers.google.com/youtube/v3/getting-started

In YouTube API we can load videos with authentication or credential.
 
Google Sample for getting credential in android https://github.com/googlesamples/android-credentials , but we will modify it for our sample application step by step.

Create a OAuth 2.0 client IDs in Google API Console with your application package name for API for Android and this API key is not needed to be copied or pasted in your application its just to register your project for OAuth 2.0.
 
Add these library in your gradle file:

compile 'com.google.android.gms:play-services-auth:9.0.2' 
compile 'com.google.api-client:google-api-client-android:1.22.0' 
compile 'com.google.apis:google-api-services-youtube:v3-rev171-1.22.0'
compile 'com.github.bumptech.glide:glide:3.6.1'
compile 'com.android.support:design:23.4.0'
compile 'com.android.support:cardview-v7:23.4.0'  
 
Create some interface to handle the Youtube Response:

public interface ServerResponseListener {

   public void prepareRequest(Object... objects);
   public void goBackground(Object... objects);
   public void completedRequest(Object... objects);

}
 
public interface ServiceTaskInterface {

    NetHttpTransport transport = new NetHttpTransport();
    JacksonFactory jsonFactory = new JacksonFactory();

}
 
public interface UserRecoverableAuth {
    void handelUserRecoverableAuth(boolean state, 
                                     UserRecoverableAuthIOException authException);
} 
 
Create a AsyncTask for network call and to get videos from youtube api.
 

public class MyUploads extends AsyncTask<Object, Void, Object[]> implements 
                                                           ServiceTaskInterface {

    private static final String TAG = MyUploads.class.getSimpleName();
    private ServerResponseListener mServerResponseListener = null;
    private int mRequestCode = 0;
    GoogleAccountCredential credential;
    Context mContext;
    
    public static final int CHANNEL_VIDEO = 1;
    public static final int PLAYLIST_VIDEO = 2;
    public static final int CHANNEL_DETAILS = 3; 
 
    public void setmServerResponseListener(ServerResponseListener mServerResponseListener) {
        this.mServerResponseListener = mServerResponseListener;
    }

    public MyUploads(Context mContext, int iReqCode, GoogleAccountCredential credential) {
        mRequestCode = iReqCode;
        this.credential = credential;
        this.mContext = mContext;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        mServerResponseListener.prepareRequest(mRequestCode);
    }

    @Override
    protected Object[] doInBackground(Object... params) {
        if (params == null)
            throw new NullPointerException("Parameters to the async task can never be null");

        mServerResponseListener.goBackground();

        Object[] resultDetails = new Object[2];
        resultDetails[0] = mRequestCode;

        switch (mRequestCode) {
            case CHANNEL_DETAILS:
                resultDetails[1] = getChannel((String) params[0]);
                break;
            case CHANNEL_VIDEO:
                resultDetails[1] = getPlaylistItemListResponse((String) params[0]);
                break;
            case PLAYLIST_VIDEO:
                resultDetails[1] = getVideos((String) params[0], (String) params[1]);
                break;
        }

        return resultDetails;
    }

    @Override
    protected void onPostExecute(Object[] result) {
        super.onPostExecute(result);
        mServerResponseListener.completedRequest(result);
    }

    private ChannelListResponse getChannel(String forUserName) {
        try {
            YouTube youtube = new YouTube.Builder(transport, jsonFactory, credential)
                                        .setApplicationName(AppConstants.APP_NAME).build();
            ChannelListResponse channelRequest = youtube.channels()
                   .list("snippet,contentDetails").setForUsername(forUserName).execute();

            List<Channel> channelsList = channelRequest.getItems();

            if (channelsList != null) {
                return channelRequest;
            }
        } catch (GoogleJsonResponseException e) {
            e.printStackTrace();
            System.err.println("There was a service error: " + e.getDetails()
                                        .getCode() + " : " + e.getDetails().getMessage());
        } catch (UserRecoverableAuthIOException ue) {
            handleException(ue);
        } catch (Throwable t) {
            t.printStackTrace();
        }

        return null;
    }

    private PlaylistItemListResponse getPlaylistItemListResponse(String forUserName) {

        try {
            YouTube youtube = new YouTube.Builder(transport, jsonFactory, credential)
                         .setApplicationName(mContext.getString(R.string.app_name)).build();
            ChannelListResponse channelRequest = youtube.channels().list("contentDetails")
                                                      .setForUsername(forUserName).execute();

            List<Channel> channelsList = channelRequest.getItems();

            if (channelsList != null) {
                String uploadPlaylistId = channelsList.get(0).getContentDetails()
                                                        .getRelatedPlaylists().getUploads();
                YouTube.PlaylistItems.List playlistItemRequest = youtube.playlistItems()
                                                           .list("id,snippet,contentDetails");
                playlistItemRequest.setPlaylistId(uploadPlaylistId);
                playlistItemRequest.setMaxResults((long) 50);
                playlistItemRequest.setPart("snippet");
                
                String nextToken = "";
                playlistItemRequest.setPageToken(nextToken);
                PlaylistItemListResponse playlistItemResult = playlistItemRequest.execute();
                
                return playlistItemResult;
            }
        } catch (GoogleJsonResponseException e) {
            e.printStackTrace();
        } catch (UserRecoverableAuthIOException ue) {
            handleException(ue);
        } catch (Throwable t) {
            t.printStackTrace();
        }

        return null;
    }

    private PlaylistItemListResponse getVideos(String nextToken, String uploadPlaylistId) {
        try {
            YouTube youtube = new YouTube.Builder(transport, jsonFactory, credential)
                    .setApplicationName(mContext.getString(R.string.app_name)).build();
            YouTube.PlaylistItems.List playlistItemRequest = youtube.playlistItems()
                                                    .list("id,snippet,contentDetails");
            playlistItemRequest.setPlaylistId(uploadPlaylistId);
            playlistItemRequest.setMaxResults((long) 50);
            playlistItemRequest.setPart("snippet");
            playlistItemRequest.setPageToken(nextToken);
            PlaylistItemListResponse playlistItemResult = playlistItemRequest.execute();
            
            return playlistItemResult;
        } catch (GoogleJsonResponseException e) {
            e.printStackTrace();
        } catch (UserRecoverableAuthIOException ue) {
            handleException(ue);
        } catch (Throwable t) {
            t.printStackTrace();
        }

        return null;
    }
 
    private void handleException(Exception e) {
        if (e.getClass().equals(UserRecoverableAuthIOException.class)) {
            UserRecoverableAuthIOException r = (UserRecoverableAuthIOException) e;

            Intent intent = null;
            try {
                intent = r.getIntent();
            } catch (Exception ee) {
                // ignore, this happens if we kill the activity quickly before 
                //our async task finishes
            }
            if (intent != null)
                doHandleAuthIntent(r);
        } else if (e.getClass().equals(GoogleAuthIOException.class)) {
            // could be a bad user name, let's pass it to the listener to check
            doHandleAuthIntent(null);
        } else if (e.getClass().equals(GoogleJsonResponseException.class)) {
            GoogleJsonResponseException r = (GoogleJsonResponseException) e;

            e.printStackTrace();

            doHandleExceptionMessage("JSON Error: " + r.getDetails().getCode() + 
                   " : " + r.getDetails().getMessage());
        } else {
            doHandleExceptionMessage("Exception Occurred: " + e.toString());

            e.printStackTrace();
        }
    }

    private void doHandleAuthIntent(UserRecoverableAuthIOException authIntent) {
        UserRecoverableAuth userRecoverableAuth = (UserRecoverableAuth) mContext;
        userRecoverableAuth.handelUserRecoverableAuth(true, authIntent);
        //toast(mContext, "Need Authorization");
    }

    private void doHandleExceptionMessage(String message) {
        toast(mContext, message);
    }
    
public static void toast(Context context, final String message) {
    // Toasts only work on the main thread
    if (context != null && message != null) {
        final Context appContext = context.getApplicationContext();

        Handler handler = new Handler(Looper.getMainLooper());

        handler.post(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(appContext, message, Toast.LENGTH_SHORT).show();
            }
        });
    }
}
 
} 


Create a UI activity.xml:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginBottom="10dp"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    android:gravity="center"
    android:orientation="vertical"
    android:weightSum="3">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/listRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipToPadding="false"
        android:scrollbars="vertical"></android.support.v7.widget.RecyclerView>

    <LinearLayout
        android:id="@+id/google_signIn"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone"
        android:gravity="center"
        android:orientation="vertical">

        <com.google.android.gms.common.SignInButton
            android:id="@+id/sign_in_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

        </com.google.android.gms.common.SignInButton>

    </LinearLayout>

</LinearLayout>
 

 
Create a YoutubeActivity.class:
 
It has a limit of 50 videos at a time can be feteched from api.
 
public class YoutubeActivity extends ActivityBase implements View.OnClickListener, 
                                                        ServerResponseListener,
        GoogleApiClient.OnConnectionFailedListener, UserRecoverableAuth{

    private static final String TAG = "YoutubeActivity";
    private static final int RC_SIGN_IN = 9001;
    private static final int REQUEST_ACCOUNT_PICKER = 2;
    private static final int REQUEST_AUTHORIZATION = 3;

    public static final String ACCOUNT_KEY = "accountName";
    private String mChosenAccountName;
    GoogleAccountCredential credential;
    private GoogleApiClient mGoogleApiClient;

    Context mContext;
    String userNameYoutube = "";
 
    LinearLayout googleSignInLinearLayout;

    RecyclerView listRecyclerView;
    YoutubeAdapter youtubeAdapter;
    LinearLayoutManager mLayoutManager;

    List<PlaylistItem> videoList = new ArrayList<PlaylistItem>();
    List<YoutubeVideos> youtubeVideosList = new ArrayList<YoutubeVideos>();

    String nextToken = "-1";
    String playlistId = "";
    public int totalLength = 0;
    private int previousTotal = 0;
    private boolean loading = true;
    private int visibleThreshold = 5;
    int firstVisibleItem, visibleItemCount, totalItemCount;
    
    final String[] SCOPES = {Scopes.PROFILE, YouTubeScopes.YOUTUBE};
    public static final int CHANNEL_VIDEO = 1;
    public static final int PLAYLIST_VIDEO = 2;
    public static final int CHANNEL_DETAILS = 3; 
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity);

        mContext = this;       
        
        initializeViews();

        //we need read contacts permission for more on Marshmallow 6.0 permission  
        //check this link
        //http://yuvarockers.blogspot.in/2016/04/android-marshmallow-60-permissions.html 

        if (Build.VERSION.SDK_INT >= 23) {
            if (!Constant_Methods.hasPermissions(this, Constant_Methods.PERMISSIONS)) {
                ActivityCompat.requestPermissions(this, Constant_Methods.PERMISSIONS, 1);
            }
        }

        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(
                 GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail()
                .build();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .enableAutoManage(this, this)
                .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
                .build();

        SignInButton signInButton = (SignInButton) findViewById(R.id.sign_in_button);
        signInButton.setSize(SignInButton.SIZE_WIDE);
        signInButton.setScopes(gso.getScopeArray());

        credential = GoogleAccountCredential.usingOAuth2(getApplicationContext(), 
                                                       Arrays.asList(SCOPES));
        // set exponential backoff policy
        credential.setBackOff(new ExponentialBackOff());

        if (savedInstanceState != null) {
            mChosenAccountName = savedInstanceState.getString(ACCOUNT_KEY);
        } else {
            loadAccount();
        }
        credential.setSelectedAccountName(mChosenAccountName);

    }

    public void initializeViews() {
        googleSignInLinearLayout = (LinearLayout) findViewById(R.id.google_signIn);
        listRecyclerView = (RecyclerView) findViewById(R.id.listRecyclerView);
        findViewById(R.id.sign_in_button).setOnClickListener(this);
        setRecyclerViewAdapter();
    }

    public void setRecyclerViewAdapter() {
        youtubeAdapter = new YoutubeAdapter(mContext, videoList, youtubeVideosList);
        listRecyclerView.setHasFixedSize(true);
        mLayoutManager = new LinearLayoutManager(getApplicationContext());
        listRecyclerView.setLayoutManager(mLayoutManager);
        youtubeAdapter.setData(videoList);        
        listRecyclerView.setItemAnimator(new DefaultItemAnimator());
        listRecyclerView.addItemDecoration(new DividerItemDecoration(this, 
                                                     LinearLayoutManager.VERTICAL));
        listRecyclerView.setAdapter(youtubeAdapter);
        youtubeAdapter.notifyDataSetChanged();

        listRecyclerView.addOnItemTouchListener(new RecyclerItemClickListener(mContext, 
                                        new RecyclerItemClickListener.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {

                TextView yearTag = (TextView) view.findViewById(R.id.item_date);
                String videoId = yearTag.getTag().toString();

                    try {
                        Intent intent = new Intent(Intent.ACTION_VIEW, 
                                            Uri.parse("vnd.youtube:" + videoId));
                        startActivity(intent);
                    } catch (ActivityNotFoundException ex) {
 
                    }
            }
        }));

        listRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                visibleItemCount = listRecyclerView.getChildCount();
                totalItemCount = mLayoutManager.getItemCount();
                firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();

                if (loading) {
                    if (totalItemCount > previousTotal) {
                        loading = false;
                        previousTotal = totalItemCount;
                    }
                }
                if (!loading && (totalItemCount - visibleItemCount) <= 
                                             (firstVisibleItem + visibleThreshold)) {
                    if (!nextToken.equals("-1")) {
                            MyUploads myUploads = new MyUploads(mContext, PLAYLIST_VIDEO, 
                                                                               credential);
                            myUploads.setmServerResponseListener(YoutubeActivity.this);
                            myUploads.execute(new String[]{nextToken, playlistId});
                            loading = true;
                    }
                }
            }
        });

    }

    @Override
    public void onStart() {
        super.onStart();
        OptionalPendingResult<GoogleSignInResult> opr = Auth.GoogleSignInApi.silentSignIn(
                                                                         mGoogleApiClient);
        if (opr.isDone()) {
            // If the user's cached credentials are valid, the OptionalPendingResult 
            // will be "done"
            // and the GoogleSignInResult will be available instantly.
            Log.d(TAG, "Got cached sign-in");
            GoogleSignInResult result = opr.get();
            handleSignInResult(result);
        } else {
            // If the user has not previously signed in on this device or the sign-in 
            // has expired,
            // this asynchronous branch will attempt to sign in the user silently.  
            // Cross-device
            // single sign-on will occur in this branch.
            //showProgressDialog();
            opr.setResultCallback(new ResultCallback<GoogleSignInResult>() {
                @Override
                public void onResult(GoogleSignInResult googleSignInResult) {
                    //hideProgressDialog();
                    handleSignInResult(googleSignInResult);
                }
            });
        }
    }

    private void handleSignInResult(GoogleSignInResult result) {
        Log.d(TAG, "handleSignInResult:" + result.isSuccess());
        if (result.isSuccess()) {
            // Signed in successfully, show authenticated UI.
            GoogleSignInAccount acct = result.getSignInAccount();
            String accountName = acct.getEmail();
            if (accountName != null) {
                mChosenAccountName = accountName;
                credential.setSelectedAccountName(accountName);
                saveAccount();
            }
            updateUI(true);
        } else {
            // Signed out, show unauthenticated UI.
            updateUI(false);
        }
    }

    private void signIn() {
        Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
        startActivityForResult(signInIntent, RC_SIGN_IN);
    }

    private void updateUI(boolean signedIn) {
        if (signedIn) {
            findViewById(R.id.google_signIn).setVisibility(View.GONE);
            listRecyclerView.setVisibility(View.VISIBLE);
            if (totalLength == 0) {
                MyUploads myUploads = new MyUploads(mContext, CHANNEL_DETAILS, credential);
                myUploads.setmServerResponseListener(this);
                myUploads.execute(new String[]{userNameYoutube});
            }
        } else {
            findViewById(R.id.google_signIn).setVisibility(View.VISIBLE);
            listRecyclerView.setVisibility(View.GONE);
        }
    }

    public void loadAccount() {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(
                                                             getApplicationContext());
        mChosenAccountName = sp.getString(ACCOUNT_KEY, null);
        invalidateOptionsMenu();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case RC_SIGN_IN:
                GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(
                                                                               data);
                handleSignInResult(result);
                break;
            case REQUEST_AUTHORIZATION:
                if (resultCode != Activity.RESULT_OK) {
                    chooseAccount();
                }
                break;
            case REQUEST_ACCOUNT_PICKER:
                if (resultCode == Activity.RESULT_OK && data != null && data.getExtras() 
                                                                              != null) {
                    String accountName = data.getExtras().getString(
                                                         AccountManager.KEY_ACCOUNT_NAME);
                    if (accountName != null) {
                        mChosenAccountName = accountName;
                        credential.setSelectedAccountName(accountName);
                        saveAccount();
                    }
                }
                break;
        }
    }

    private void chooseAccount() {
        startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
    }

    public void saveAccount() {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(
                                                 SampleApplication.getAppContext());
        sp.edit().putString(ACCOUNT_KEY, mChosenAccountName).commit();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString(ACCOUNT_KEY, mChosenAccountName);
        Log.e("mChosenAccountName", "" + mChosenAccountName);
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        switch (id) {
            case R.id.sign_in_button:
                signIn();
                break;
        }

    }


    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        if (connectionResult.hasResolution()) {
            Toast.makeText(getApplicationContext(),
                    R.string.connection_to_google_play_failed, Toast.LENGTH_SHORT)
                    .show();

            Log.e("TAG", String.format(
                    "Connection to Play Services Failed, error: %d, reason: %s",
                    connectionResult.getErrorCode(),
                    connectionResult.toString()));
            try {
                connectionResult.startResolutionForResult(YoutubeActivity.this, 0);
            } catch (IntentSender.SendIntentException e) {
                Log.e("TAG", e.toString(), e);
            }
        }
    }

    @Override
    public void prepareRequest(Object... objects) {
        // Parse the response based upon type of request
        Integer reqCode = (Integer) objects[0];

        if (reqCode == null || reqCode == 0)
            throw new NullPointerException("Request Code's value is Invalid.");
        switch (reqCode) {
            case CHANNEL_DETAILS:
                break;
            case CHANNEL_VIDEO:
                break;
            case PLAYLIST_VIDEO:
                break;
        }

    }

    @Override
    public void goBackground(Object... objects) {

    }

    @Override
    public void completedRequest(Object... objects) {
        // Parse the response based upon type of request
        Integer reqCode = (Integer) objects[0];

        if (reqCode == null || reqCode == 0)
            throw new NullPointerException("Request Code's value is Invalid.");

        switch (reqCode) {
            case CHANNEL_DETAILS: //To get the channel details
                ChannelListResponse channelsResponse = (ChannelListResponse) objects[1];
                if (channelsResponse != null) {
                    if (channelsResponse.getItems().size() > 0) {
                        channelsResponse.getItems().get(0).getSnippet().getDescription());
                    }
                }
                if (NetworkUtils.isConnectingToInternet(mContext)) {
                    MyUploads myUploads1 = new MyUploads(mContext, CHANNEL_VIDEO, credential);
                    myUploads1.setmServerResponseListener(this);
                    myUploads1.execute(new String[]{userNameYoutube});
                } else {
                    Toast.makeText(getApplicationContext(), "No Internet Connection", 
                                                              Toast.LENGTH_LONG).show();
                }
                break;
            case CHANNEL_VIDEO://To get the channel's first 50 videos
                PlaylistItemListResponse playlistItemListResponse = (PlaylistItemListResponse)
                                                                      objects[1];
                if (playlistItemListResponse != null) {
                    totalLength = playlistItemListResponse.getPageInfo().getTotalResults();
                    videoList.addAll(playlistItemListResponse.getItems());
                    nextToken = (playlistItemListResponse.containsKey("nextPageToken"))
                                         ? playlistItemListResponse.getNextPageToken() : "-1";
                    playlistId = (playlistItemListResponse.getItems().size() > 0) ? 
                                     playlistItemListResponse.getItems().get(0).getSnippet()
                                                              .getPlaylistId() : "";
                    if (playlistItemListResponse.getItems().size() > 0) {

                        for (int i = 0; i < playlistItemListResponse.getItems().size(); i++) {
                            YoutubeVideos youtubeVideos = new YoutubeVideos();
                                youtubeVideos.setId(playlistItemListResponse.getItems()
                                                                          .get(i).getId());
                                youtubeVideos.setSeen(false);
                                youtubeVideosList.add(youtubeVideos);
                            }
                            youtubeVideos = null;
                        }

                        setRecyclerViewAdapter();
                    }
                }
                break;
            case PLAYLIST_VIDEO: //Get videos using next token to get another list of videos
                PlaylistItemListResponse playlistItemListResponse1 = (PlaylistItemListResponse)
                                                                                objects[1];
                if (playlistItemListResponse1 != null) {
                    videoList.addAll(playlistItemListResponse1.getItems());
                    nextToken = (playlistItemListResponse1.containsKey("nextPageToken")) 
                                      ? playlistItemListResponse1.getNextPageToken() : "-1";
                    playlistId = (playlistItemListResponse1.getItems().size() > 0)
                                     ? playlistItemListResponse1.getItems().get(0)
                                                      .getSnippet().getPlaylistId() : "";
                    if (playlistItemListResponse1.getItems().size() > 0) {

                        for (int i = 0; i < playlistItemListResponse1.getItems().size(); i++) {
                            YoutubeVideos youtubeVideos = new YoutubeVideos();
                                youtubeVideos.setId(playlistItemListResponse1.getItems()
                                               .get(i).getId());
                                youtubeVideos.setSeen(false);
                                youtubeVideosList.add(youtubeVideos);
                            }
                            youtubeVideos = null;
                        }

                        youtubeAdapter.notifyDataSetChanged();
                    }

                }
                break;
        }
    }

    
    @Override
    public void handelUserRecoverableAuth(boolean state, 
                                            UserRecoverableAuthIOException authException) {
        startActivityForResult(authException.getIntent(), REQUEST_AUTHORIZATION);
    }
}
 
 
Create a YoutubeAdapter for loading the videos thumbnail and show description:
 
I have used this library https://github.com/yuvaraj119/android-parallax-recyclerview 
for YoutubeAdapter.
 
public class YoutubeAdapter extends ParallaxRecyclerAdapter<PlaylistItem> {

    private List<PlaylistItem> videoList;
    Context mContext;
    List<YoutubeVideos> youtubeVideosList = new ArrayList<YoutubeVideos>();

    public YoutubeAdapter(Context mContext, List<PlaylistItem> moviesList, 
                                           List<YoutubeVideos> youtubeVideosList) {
        super(moviesList);
        this.mContext = mContext;
        this.videoList = moviesList;
        this.youtubeVideosList = youtubeVideosList;
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView title, year, genre;
        public ImageView imageViewVideoThumb;

        public MyViewHolder(View view) {
            super(view);
            title = (TextView) view.findViewById(R.id.item_heading);
            genre = (TextView) view.findViewById(R.id.item_content);
            year = (TextView) view.findViewById(R.id.item_date);
            imageViewVideoThumb = (ImageView) view.findViewById(R.id.imageViewVideoThumb);
        }
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolderImpl(ViewGroup parent, 
                                    ParallaxRecyclerAdapter<PlaylistItem> adapter, int i) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(
                                       R.layout.youtube_item_view, parent, false);
        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolderImpl(RecyclerView.ViewHolder viewHolder, 
                              ParallaxRecyclerAdapter<PlaylistItem> adapter, int position) {
        MyViewHolder holder = (MyViewHolder) viewHolder;
        PlaylistItem playlistItem = videoList.get(position);
        YoutubeVideos youtubeVideos = youtubeVideosList.get(position);
        
        holder.title.setText(playlistItem.getSnippet().getTitle());
        holder.genre.setText(playlistItem.getSnippet().getDescription());
        holder.year.setText(playlistItem.getSnippet().getPublishedAt().toString());
        holder.year.setTag("" + playlistItem.getSnippet().getResourceId().getVideoId());

        try {
            String imageUrl = (playlistItem.getSnippet().getThumbnails()
                            .containsKey("standard")) ? playlistItem.getSnippet()
                            .getThumbnails().getStandard().getUrl()
                            : playlistItem.getSnippet().getThumbnails().getDefault().getUrl();

            Glide.with(mContext)
                    .load(imageUrl)
                    .diskCacheStrategy(DiskCacheStrategy.ALL)
                    .crossFade()
                    .into(holder.imageViewVideoThumb);
        } catch (NullPointerException ne) {
            ne.printStackTrace();
        } catch (IllegalArgumentException ia) {
            ia.printStackTrace();
        }
    }

    @Override
    public int getItemCountImpl(ParallaxRecyclerAdapter<PlaylistItem> adapter) {
        return videoList.size();
    }
}
 
 
Create a youtube_item_view layout:
 

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="180dp"
    android:layout_marginBottom="5dp"
    android:layout_marginTop="5dp"
    android:elevation="5dp">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/imageViewVideoThumb"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:adjustViewBounds="true"
            android:scaleType="centerCrop" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal|bottom"
            android:background="@color/very_dark_grayish_cyan"
            android:orientation="vertical">

            <TextView
                android:id="@+id/item_heading"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:textAppearance="@android:style/TextAppearance.Small"
                android:textStyle="bold" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:weightSum="3">

                <TextView
                    android:id="@+id/item_content"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_weight=".8"
                    android:layout_marginLeft="5dp"
                    android:textAppearance="@android:style/TextAppearance.Small"
                    android:gravity="left|bottom"
                    android:ellipsize="end"
                    android:maxLines="2" />

                <TextView
                    android:id="@+id/item_invisible"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textAppearance="@android:style/TextAppearance.Small"
                    android:layout_weight="1.2"
                    android:visibility="invisible" />

                <TextView
                    android:id="@+id/item_date"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_marginRight="5dp"
                    android:textAppearance="@android:style/TextAppearance.Small"
                    android:layout_weight="1"
                    android:gravity="right|bottom" />

            </LinearLayout>


        </LinearLayout>

    </FrameLayout>
</android.support.v7.widget.CardView>
 
  

Comments

  1. Utilizing the YouTube API V3 for Android opens up a world of possibilities for developers looking to integrate rich multimedia functionality into their apps. With seamless access to YouTube's vast library of videos, live streams, and user data, developers can create immersive experiences tailored to their users' preferences. Whether it's building a video-sharing app, implementing advanced search features, or integrating personalized recommendations, the YouTube API V3 empowers developers to craft innovative solutions that engage and delight users on the Android platform.

    ReplyDelete

Post a Comment

Popular posts from this blog

Vertical AutoScrolling TextView in Android

In android by default we can scroll the text in horizontal using marquee in layout, but if we want to scroll the text in vertical its not possible by default. So here we will learn to create a custom TextView which will auto-scroll in vertical direction. Source Code:  VerticalScrollingTextView-Android Create a AutoScrollingTextView.class which extends TextView: @SuppressLint ( "AppCompatCustomView" ) public class AutoScrollingTextView extends TextView { private static final float DEFAULT_SPEED = 65.0f ; public Scroller scroller ; public float speed = DEFAULT_SPEED ; public boolean continuousScrolling = true; public AutoScrollingTextView (Context context) { super (context) ; init( null, 0 ) ; scrollerInstance(context) ; } public AutoScrollingTextView (Context context , AttributeSet attrs) { super (context , attrs) ; init(attrs , 0 ) ; scr...

Flexbox inside the RecyclerView as a LayoutManager (FlexboxLayoutManager).

Currently google has release the Flexbox which can be used for building flexible layouts using FlexboxLayout, it can be interpreted as an advanced LinearLayout because both layouts align their child views sequentially. For more detail on this flexbox-layout But here we are gonna work on Flexbox with RecyclerView. Flexbox with a large number of items in a scrollable container! Let's first see what are the Supported attributes / features comparison Due to some characteristics of the RecyclerView, some Flexbox attributes are not available/not implemented to the FlexboxLayoutManager. Here is a quick overview of the attributes/features comparison between the two containers. Attribute / Feature FlexboxLayout                FlexboxLayoutManager (RecyclerView) flexDirection flexWrap (except wrap_reverse ) justifyContent alignItems alignContent - layout_order - layout_fle...

Android RecyclerView and StaggeredGridLayoutManager with Picasso/Glide

This project is there in GitHub https://github.com/yuvaraj119/Picasso-RecyclerView-StaggeredGridLayoutManager You can download and start customizing it for your project also. How to use with Picasso Picasso + RecyclerView + StaggeredGridLayoutManager Its the enhanced version of this project https://github.com/pohh/slotmachinepicasso were there was a problem with Picasso + RecyclerView + StaggeredGridLayoutManager shuffles resizable recycler views infinitely issue posted on github https://github.com/square/picasso/issues/918 I have made some changes now it works with Picasso and Glide without any shuffles and position change Currently this project is done with Picasso If you want to use it with Glide How to use with Glide Glide + RecyclerView + StaggeredGridLayoutManager Add dependencies for Glide https://github.com/bumptech/glide Remove Picasso library from dependency and remove all the codes of Picasso from MyGridAdapter.java and also from other p...