https://codebunny99.tistory.com/163
μ νλΈ λ°μ΄ν° APIλ₯Ό Postman(ν¬μ€νΈλ§¨)μΌλ‘ μ¬μ©νλ λ°©λ²
https://console.cloud.google.com/welcome/new?hl=ko&project=eastern-surface-426200-r0&supportedpurview=project Google ν΄λΌμ°λ νλ«νΌλ‘κ·ΈμΈ Google ν΄λΌμ°λ νλ«νΌμΌλ‘ μ΄λaccounts.google.com youtube data κ²μν΄μ μ¬μ© λλ₯΄
codebunny99.tistory.com
ν€(key) κ°μ μμ ν¬μ€ν μ λ¨Όμ μ°Έκ³ ν΄ κ°μ Έμ¨λ€.
μ νλΈ APIλ₯Ό PostmanμΌλ‘ μ€νμν€λ©΄, λ€μκ³Ό κ°μ΄ Json νμΌμ μ€λ€.


MainActivity
λμμΈ(xml νμΌ)

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
ββββxmlns:app="http://schemas.android.com/apk/res-auto"
ββββxmlns:tools="http://schemas.android.com/tools"
ββββandroid:id="@+id/main"
ββββandroid:layout_width="match_parent"
ββββandroid:layout_height="match_parent"
ββββtools:context=".MainActivity">
ββββ<RelativeLayout
ββββββββandroid:layout_width="match_parent"
ββββββββandroid:layout_height="match_parent"
ββββββββapp:layout_constraintBottom_toBottomOf="parent"
ββββββββapp:layout_constraintEnd_toEndOf="parent"
ββββββββapp:layout_constraintStart_toStartOf="parent"
ββββββββapp:layout_constraintTop_toTopOf="parent">
ββββββββ<LinearLayout
ββββββββββββandroid:id="@+id/topLayout"
ββββββββββββandroid:layout_width="match_parent"
ββββββββββββandroid:layout_height="wrap_content"
ββββββββββββandroid:layout_alignParentTop="true"
ββββββββββββandroid:layout_margin="10dp"
ββββββββββββandroid:orientation="horizontal">
ββββββββββββ<EditText
ββββββββββββββββandroid:id="@+id/editSearch"
ββββββββββββββββandroid:layout_width="wrap_content"
ββββββββββββββββandroid:layout_height="wrap_content"
ββββββββββββββββandroid:layout_marginRight="5dp"
ββββββββββββββββandroid:layout_weight="5"
ββββββββββββββββandroid:ems="10"
ββββββββββββββββandroid:hint="κ²μμ΄ μ
λ ₯..."
ββββββββββββββββandroid:inputType="text"
ββββββββββββββββandroid:textSize="22sp" />
ββββββββββββ<ImageView
ββββββββββββββββandroid:id="@+id/imgSearch"
ββββββββββββββββandroid:layout_width="45dp"
ββββββββββββββββandroid:layout_height="45dp"
ββββββββββββββββapp:srcCompat="@drawable/search_24dp" />
ββββββββ</LinearLayout>
ββββββββ<androidx.recyclerview.widget.RecyclerView
ββββββββββββandroid:id="@+id/recyclerView"
ββββββββββββandroid:layout_width="match_parent"
ββββββββββββandroid:layout_height="match_parent"
ββββββββββββandroid:layout_below="@id/topLayout" />
ββββββββ<ProgressBar
ββββββββββββandroid:id="@+id/progressBar"
ββββββββββββstyle="?android:attr/progressBarStyle"
ββββββββββββandroid:layout_width="wrap_content"
ββββββββββββandroid:layout_height="wrap_content"
ββββββββββββandroid:layout_centerInParent="true" />
ββββ</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.java (νμ±νκΈ°)
package com.~.youtube;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import com.google.android.material.snackbar.Snackbar;
import com.~.youtube.adapter.YoutubeAdapter;
import com.~.youtube.config.Config;
import com.~.youtube.model.Youtube;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
ββββProgressBar progressBar;
ββββImageView imgSearch;
ββββEditText editSearch;
ββββ// 리μ¬μ΄ν΄λ¬λ·°λ κ΄λ ¨λ λ©€λ²λ³μ 2κ° λ μμ±ν΄μΌ νλ€
ββββRecyclerView recyclerView;
ββββArrayList<Youtube> YoutubeArrayList = new ArrayList<>();
ββββYoutubeAdapter adapter;
ββββ@Override
ββββprotected void onCreate(Bundle savedInstanceState) {
ββββββββsuper.onCreate(savedInstanceState);
ββββββββsetContentView(R.layout.activity_main);
ββββββββgetSupportActionBar().setTitle("YoutubeApp");
ββββββββ// λ€μ μ½λλ μμΌλ‘ 무쑰건 κ°μ΄ μμ±
ββββββββrecyclerView = findViewById(R.id.recyclerView);
ββββββββrecyclerView.setHasFixedSize(true);
ββββββββrecyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
ββββββββprogressBar = findViewById(R.id.progressBar);
ββββββββimgSearch = findViewById(R.id.imgSearch);
ββββββββeditSearch = findViewById(R.id.editSearch);
ββββββββ// νλ‘κ·Έλ μ€ λ°λ₯Ό μ μ μ λμμ μ¬λΌμ§κ² νλ μ½λ
ββββββββprogressBar.setVisibility(View.GONE);
ββββββββimgSearch.setOnClickListener(new View.OnClickListener() {
ββββββββββββ@Override
ββββββββββββpublic void onClick(View v) {
ββββββββββββββββString keyword = editSearch.getText().toString().trim();
ββββββββββββββββif(keyword.isEmpty()){
ββββββββββββββββββββSnackbar.make(imgSearch, "κ²μμ΄λ₯Ό μ
λ ₯νμΈμ.", Snackbar.LENGTH_SHORT).show();
ββββββββββββββββββββreturn;
ββββββββββββββββ}
ββββββββββββββββ// νλ‘κ·Έλ μ€ λ°λ₯Ό μ μ μ λμ 보μ΄κ² νλ μ½λ
ββββββββββββββββprogressBar.setVisibility(View.VISIBLE);
ββββββββββββββββ// 1. request queue λ₯Ό λ§λ λ€
ββββββββββββββββRequestQueue queue = Volley.newRequestQueue(MainActivity.this);
ββββββββββββββββ// 2. request(μμ²)μ λ§λ λ€.
ββββββββββββββββ// λ°μ΄ν° νμ
μ, μλ΅μ json νμμ λ³΄κ³ κ²°μ νλ€.
ββββββββββββββββJsonObjectRequest request = new JsonObjectRequest(
ββββββββββββββββββββββββRequest.Method.GET,
ββββββββββββββββββββββββ"https://www.googleapis.com/youtube/v3/search?key=" + Config.YoutubeKey + "&part=snippet&maxResults=20&order=date&q=" + keyword + "&type=video",
ββββββββββββββββββββββββnull,
ββββββββββββββββββββββββnew Response.Listener<JSONObject>() {
ββββββββββββββββββββββββββββ@Override
ββββββββββββββββββββββββββββpublic void onResponse(JSONObject response) {
ββββββββββββββββββββββββββββββββ// νλ‘κ·Έλ μ€ λ°λ₯Ό μ μ μ λμμ μ¬λΌμ§κ² νλ μ½λ
ββββββββββββββββββββββββββββββββprogressBar.setVisibility(View.GONE);
ββββββββββββββββββββββββββββββββtry {
ββββββββββββββββββββββββββββββββββββJSONArray items = response.getJSONArray("items");
ββββββββββββββββββββββββββββββββββββYoutubeArrayList.clear(); // κΈ°μ‘΄ λ°μ΄ν° μ΄κΈ°ν
ββββββββββββββββββββββββββββββββββββfor (int i = 0; i < items.length(); i++) {
ββββββββββββββββββββββββββββββββββββββββJSONObject data = items.getJSONObject(i);
ββββββββββββββββββββββββββββββββββββββββJSONObject id = data.getJSONObject("id");
ββββββββββββββββββββββββββββββββββββββββString videoId = id.getString("videoId");
ββββββββββββββββββββββββββββββββββββββββJSONObject snippet = data.getJSONObject("snippet");
ββββββββββββββββββββββββββββββββββββββββString title = snippet.getString("title");
ββββββββββββββββββββββββββββββββββββββββString description = snippet.getString("description");
ββββββββββββββββββββββββββββββββββββββββJSONObject thumbnails = snippet.getJSONObject("thumbnails");
ββββββββββββββββββββββββββββββββββββββββJSONObject medium = thumbnails.getJSONObject("medium");
ββββββββββββββββββββββββββββββββββββββββString thumbUrl = medium.getString("url");
ββββββββββββββββββββββββββββββββββββββββJSONObject high = thumbnails.getJSONObject("high");
ββββββββββββββββββββββββββββββββββββββββString url = high.getString("url");
ββββββββββββββββββββββββββββββββββββββββYoutube youtube = new Youtube(videoId, title, description, thumbUrl, url);
ββββββββββββββββββββββββββββββββββββββββYoutubeArrayList.add(youtube);
ββββββββββββββββββββββββββββββββββββ}
ββββββββββββββββββββββββββββββββββββ// μ΄λν°λ₯Ό λ§λ€κ³
ββββββββββββββββββββββββββββββββββββadapter = new YoutubeAdapter(MainActivity.this, YoutubeArrayList);
ββββββββββββββββββββββββββββββββββββ// 리μ¬μ΄ν΄λ¬λ·°μ μ΄λν°λ₯Ό μ μ©νλ©΄ νλ©΄μ λμ¨λ€
ββββββββββββββββββββββββββββββββββββrecyclerView.setAdapter(adapter);
ββββββββββββββββββββββββββββββββ} catch (JSONException e) {
ββββββββββββββββββββββββββββββββββββToast.makeText(MainActivity.this, "νμ± μλ¬", Toast.LENGTH_SHORT).show();
ββββββββββββββββββββββββββββββββββββe.printStackTrace();
ββββββββββββββββββββββββββββββββ}
ββββββββββββββββββββββββββββ}
ββββββββββββββββββββββββ},
ββββββββββββββββββββββββnew Response.ErrorListener() {
ββββββββββββββββββββββββββββ@Override
ββββββββββββββββββββββββββββpublic void onErrorResponse(VolleyError volleyError) {
ββββββββββββββββββββββββββββββββ// νλ‘κ·Έλ μ€ λ°λ₯Ό μ μ μ λμμ μ¬λΌμ§κ² νλ μ½λ
ββββββββββββββββββββββββββββββββprogressBar.setVisibility(View.GONE);
ββββββββββββββββββββββββββββββββToast.makeText(MainActivity.this, "λ€νΈμν¬ ν΅μ μλ¬", Toast.LENGTH_SHORT).show();
ββββββββββββββββββββββββββββ}
ββββββββββββββββββββββββ}
ββββββββββββββββ);
ββββββββββββββββ// 3. λ€νΈμν¬λ‘ 보λΈλ€.
ββββββββββββββββqueue.add(request);
ββββββββββββ}
ββββββββ});
ββββ}
}
Config ν΄λμ€
package com.~.youtube.config;
public class Config {
ββββpublic static final String YoutubeKey = "μμ μ ν€κ° μ
λ ₯";
}
Youtube ν΄λμ€
package com.~.youtube.model;
import java.io.Serializable;
public class Youtube implements Serializable {
ββββpublic String videoId;
ββββpublic String thumbUrl;
ββββpublic String url;
ββββpublic String title;
ββββpublic String description;
ββββpublic Youtube(){
ββββ}
ββββpublic Youtube(String videoId, String title, String description, String thumbUrl, String url) {
ββββββββthis.videoId = videoId;
ββββββββthis.thumbUrl = thumbUrl;
ββββββββthis.url = url;
ββββββββthis.title = title;
ββββββββthis.description = description;
ββββ}
}
activity_row .xml λ§λ€κΈ°
λμμΈ(xml νμΌ)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
ββββandroid:layout_width="match_parent"
ββββandroid:layout_height="wrap_content"
ββββandroid:orientation="vertical">
ββββ<androidx.cardview.widget.CardView
ββββββββandroid:id="@+id/cardView"
ββββββββandroid:layout_width="match_parent"
ββββββββandroid:layout_height="match_parent"
ββββββββandroid:layout_marginLeft="15dp"
ββββββββandroid:layout_marginTop="7dp"
ββββββββandroid:layout_marginRight="15dp"
ββββββββandroid:layout_marginBottom="7dp">
ββββββββ<LinearLayout
ββββββββββββandroid:layout_width="match_parent"
ββββββββββββandroid:layout_height="wrap_content"
ββββββββββββandroid:layout_margin="10dp"
ββββββββββββandroid:orientation="vertical">
ββββββββββββ<TextView
ββββββββββββββββandroid:id="@+id/txtTitle"
ββββββββββββββββandroid:layout_width="match_parent"
ββββββββββββββββandroid:layout_height="wrap_content"
ββββββββββββββββandroid:ellipsize="end"
ββββββββββββββββandroid:maxLines="1"
ββββββββββββββββandroid:text="TextView"
ββββββββββββββββandroid:textSize="24sp" />
ββββββββββββ<TextView
ββββββββββββββββandroid:id="@+id/txtDescription"
ββββββββββββββββandroid:layout_width="match_parent"
ββββββββββββββββandroid:layout_height="wrap_content"
ββββββββββββββββandroid:layout_marginLeft="20dp"
ββββββββββββββββandroid:layout_marginTop="7dp"
ββββββββββββββββandroid:layout_marginBottom="10dp"
ββββββββββββββββandroid:ellipsize="end"
ββββββββββββββββandroid:maxLines="2"
ββββββββββββββββandroid:text="TextView"
ββββββββββββββββandroid:textSize="20sp" />
ββββββββββββ<ImageView
ββββββββββββββββandroid:id="@+id/imgThumb"
ββββββββββββββββandroid:layout_width="320dp"
ββββββββββββββββandroid:layout_height="180dp"
ββββββββββββββββandroid:layout_gravity="center"
ββββββββββββββββandroid:src="@drawable/image_24dp" />
ββββββββ</LinearLayout>
ββββ</androidx.cardview.widget.CardView>
</LinearLayout>
Adapter λ§λ€κΈ°
package com.~.youtube.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.~.youtube.R;
import com.~.youtube.model.Youtube;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
public class YoutubeAdapter extends RecyclerView.Adapter<YoutubeAdapter.ViewHolder>{
ββββContext context;
ββββArrayList<Youtube> YoutubeArrayList;
ββββpublic YoutubeAdapter(Context context, ArrayList<Youtube> YoutubeArrayList) {
ββββββββthis.context = context;
ββββββββthis.YoutubeArrayList = YoutubeArrayList;
ββββ}
ββββ@NonNull
ββββ@Override
ββββpublic ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
ββββββββView view = LayoutInflater.from(parent.getContext())
ββββββββββββββββ.inflate(R.layout.activity_row, parent, false);
ββββββββreturn new YoutubeAdapter.ViewHolder(view);
ββββ}
ββββ@Override
ββββpublic void onBindViewHolder(@NonNull ViewHolder holder, int position) {
ββββββββYoutube youtube = YoutubeArrayList.get(position);
ββββββββholder.txtTitle.setText( youtube.title );
ββββββββholder.txtDescription.setText( youtube.description );
ββββββββGlide.with(context).load( youtube.thumbUrl ).into( holder.imgThumb );
ββββ}
ββββ@Override
ββββpublic int getItemCount() {
ββββββββreturn YoutubeArrayList.size();
ββββ}
ββββpublic class ViewHolder extends RecyclerView.ViewHolder {
ββββββββTextView txtTitle;
ββββββββTextView txtDescription;
ββββββββImageView imgThumb;
ββββββββpublic ViewHolder(@NonNull View itemView) {
ββββββββββββsuper(itemView);
ββββββββββββtxtTitle = itemView.findViewById(R.id.txtTitle);
ββββββββββββtxtDescription = itemView.findViewById(R.id.txtDescription);
ββββββββββββimgThumb = itemView.findViewById(R.id.imgThumb);
ββββββββ}
ββββ}
}

μΉ΄λλ·° μ ννλ©΄ μ νλΈλ‘ μ΄λνκ² νκΈ°
- Adapterμμ μΆκ°νλ€.

μΉ΄λλ·°λ₯Ό ν΄λ¦νλ©΄ μ νλΈλ‘ μ΄λνλ κ²λ μΆκ°ν΄μ€λ€.

public class ViewHolder extends RecyclerView.ViewHolder {
ββββββββTextView txtTitle;
ββββββββTextView txtDescription;
ββββββββImageView imgThumb;
ββββββββCardView cardView;
ββββββββ
ββββββββpublic ViewHolder(@NonNull View itemView) {
ββββββββββββsuper(itemView);
ββββββββββββtxtTitle = itemView.findViewById(R.id.txtTitle);
ββββββββββββtxtDescription = itemView.findViewById(R.id.txtDescription);
ββββββββββββimgThumb = itemView.findViewById(R.id.imgThumb);
ββββββββββββcardView = itemView.findViewById(R.id.cardView);
ββββββββββββcardView.setOnClickListener(new View.OnClickListener() {
ββββββββββββββββ@Override
ββββββββββββββββpublic void onClick(View v) {
ββββββββββββββββββββint index = getAdapterPosition();
ββββββββββββββββββββYoutube youtube = YoutubeArrayList.get(index);
ββββββββββββββββββββString url = "https://www.youtube.com/watch?v=" + youtube.videoId;
ββββββββββββββββββββopenWebPage(url);
ββββββββββββββββ}
ββββββββββββ});
ββββββββ}
ββββββββ// μΉλΈλΌμ°μ μ‘ν°λΉν°λ₯Ό μ€νμν€λ ν¨μ
ββββββββvoid openWebPage(String url){
ββββββββββββUri uri = Uri.parse(url);
ββββββββββββIntent intent = new Intent(Intent.ACTION_VIEW, uri);
ββββββββββββcontext.startActivity(intent);
ββββββββ}
ββββ}