살펴보아야할부분
url파싱
페이징처리 ( addNetworkData() 함수)
메인액티비티.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: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/layoutTop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp"
android:orientation="horizontal">
<EditText
android:id="@+id/editSearch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:hint="검색어 입력..."
android:inputType="textPersonName"
android:textSize="26sp" />
<ImageView
android:id="@+id/imgSearch"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_gravity="center"
app:srcCompat="@drawable/ic_baseline_search_24" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/layoutTop"
android:layout_alignParentBottom="false" />
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone" />
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
video_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<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"
app:srcCompat="@drawable/ic_baseline_ondemand_video_24" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
기능추가 ( 카드뷰 선택시 웹브라우저 실행(유튜브 앱이있다면 앱이 실행됨), 썸네일 선택시 썸네일확대)
메인액티비티
package com.leopard4.youtubeapiapp;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
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.leopard4.youtubeapiapp.adapter.VideoAdapter;
import com.leopard4.youtubeapiapp.config.Config;
import com.leopard4.youtubeapiapp.model.Video;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
EditText editSearch;
ImageView imgSearch;
ProgressBar progressBar;
RecyclerView recyclerView;
VideoAdapter adapter;
ArrayList<Video> videoList = new ArrayList<>();
String keyword;
String pageToken;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editSearch = findViewById(R.id.editSearch);
imgSearch = findViewById(R.id.imgSearch);
progressBar = findViewById(R.id.progressBar);
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// 맨 마지막 데이터가 화면에 보이면!!!!
// 네트워크 통해서 데이터를 추가로 받아와라!!
int lastPosition = ((LinearLayoutManager)recyclerView.getLayoutManager()).findLastCompletelyVisibleItemPosition();
int totalCount = recyclerView.getAdapter().getItemCount();
// 스크롤을 데이터 맨 끝까지 한 상태.
if(lastPosition + 1 == totalCount){
// 네트워크 통해서 데이터를 받아오고, 화면에 표시!
addNetworkData();
}
}
});
// editSearch를 클릭했을때
// editSearch에 있는 텍스트를 지워준다.
editSearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
editSearch.setText("");
}
});
imgSearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
keyword = editSearch.getText().toString().trim();
if(keyword.isEmpty()){
return;
}
// 네트워크 데이터 처리하는 함수 호출
getNetworkData();
}
});
}
private void getNetworkData() {
// 유투브 API 호출
RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
String url = Config.BASE_URL + Config.PATH
+ Config.API_KEY
+ "&part=snippet&q="+keyword
+"&maxResults=20&type=video";
JsonObjectRequest request = new JsonObjectRequest(
Request.Method.GET,
url,
null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
progressBar.setVisibility(View.GONE);
// 검색어를 다른것으로 바꿧을때처리
// 초기화 작업
videoList.clear();
pageToken = null;
try {
pageToken = response.getString("nextPageToken");
JSONArray items = response.getJSONArray("items");
for(int i = 0; i < items.length(); i++){
JSONObject item = items.getJSONObject(i);
String videoId = item.getJSONObject("id").getString("videoId");
String title = item.getJSONObject("snippet").getString("title");
String description = item.getJSONObject("snippet").getString("description");
String mediumUrl = item.getJSONObject("snippet").getJSONObject("thumbnails").getJSONObject("medium").getString("url");
String highUrl = item.getJSONObject("snippet").getJSONObject("thumbnails").getJSONObject("high").getString("url");
Video video = new Video(videoId, title, description, mediumUrl, highUrl);
videoList.add(video);
}
} catch (JSONException e) {
e.printStackTrace();
return;
}
// 어댑터가 null이면 새로 만들어주고, null이 아니면 데이터를 갱신해준다.
if(adapter == null){
adapter = new VideoAdapter(MainActivity.this, videoList);
recyclerView.setAdapter(adapter);
}else{
adapter.notifyDataSetChanged();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
progressBar.setVisibility(View.GONE);
}
}
);
progressBar.setVisibility(View.VISIBLE);
queue.add(request);
}
private void addNetworkData(){
RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
String url = Config.BASE_URL + Config.PATH
+ Config.API_KEY
+ "&part=snippet&q="+keyword
+"&type=video&maxResults=20&pageToken="+pageToken;
JsonObjectRequest request = new JsonObjectRequest(
Request.Method.GET,
url,
null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
progressBar.setVisibility(View.GONE);
try {
pageToken = response.getString("nextPageToken");
JSONArray items = response.getJSONArray("items");
for(int i = 0; i < items.length(); i++){
JSONObject item = items.getJSONObject(i);
String videoId = item.getJSONObject("id").getString("videoId");
String title = item.getJSONObject("snippet").getString("title");
String description = item.getJSONObject("snippet").getString("description");
String mediumUrl = item.getJSONObject("snippet").getJSONObject("thumbnails").getJSONObject("medium").getString("url");
String highUrl = item.getJSONObject("snippet").getJSONObject("thumbnails").getJSONObject("high").getString("url");
Video video = new Video(videoId, title, description, mediumUrl, highUrl);
videoList.add(video);
}
} catch (JSONException e) {
return;
}
adapter.notifyDataSetChanged();
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
progressBar.setVisibility(View.GONE);
}
}
);
progressBar.setVisibility(View.VISIBLE);
queue.add(request);
}
// 웹 브라우저 실행시키는 인텐트
public void openWebPage(String url) {
Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri); // 액션이 VIEW로 되어있고 인텐트타입이 uri
startActivity(intent);
}
}
videoAdapter
package com.leopard4.youtubeapiapp.adapter;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.leopard4.youtubeapiapp.MainActivity;
import com.leopard4.youtubeapiapp.PhotoActivity;
import com.leopard4.youtubeapiapp.R;
import com.leopard4.youtubeapiapp.model.Video;
import java.util.ArrayList;
public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.ViewHolder>{
Context context;
ArrayList<Video> videoList;
public VideoAdapter(Context context, ArrayList<Video> videoList) {
this.context = context;
this.videoList = videoList;
}
@NonNull
@Override
public VideoAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.video_row, parent, false);
return new VideoAdapter.ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull VideoAdapter.ViewHolder holder, int position) {
Video video = videoList.get(position);
holder.txtTitle.setText(video.title);
holder.txtDescription.setText(video.description);
Glide.with(context).load(video.mediumUrl)
.placeholder(R.drawable.ic_baseline_ondemand_video_24)
.into(holder.imgThumb);
}
@Override
public int getItemCount() {
return videoList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
CardView cardView;
TextView txtTitle, txtDescription;
ImageView imgThumb;
public ViewHolder(@NonNull View itemView) {
super(itemView);
cardView = itemView.findViewById(R.id.cardView);
txtTitle = itemView.findViewById(R.id.txtTitle);
txtDescription = itemView.findViewById(R.id.txtDescription);
imgThumb = itemView.findViewById(R.id.imgThumb);
imgThumb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int index = getAdapterPosition();
Intent intent = new Intent(context, PhotoActivity.class);
intent.putExtra("highUrl", videoList.get(index).highUrl);
context.startActivity(intent);
}
});
cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int index = getAdapterPosition();
Video video = videoList.get(index);
// https://www.youtube.com/watch?v="videoId"
String url = "https://www.youtube.com/watch?v=" + video.videoId;
((MainActivity) context).openWebPage(url);
}
});
}
}
}
PhotoActivity
package com.leopard4.youtubeapiapp;
import androidx.appcompat.app.AppCompatActivity;
import android.net.Uri;
import android.os.Bundle;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
public class PhotoActivity extends AppCompatActivity {
ImageView imgPhoto;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_photo);
imgPhoto = findViewById(R.id.imgPhoto);
String url = getIntent().getStringExtra("highUrl");
Glide.with(PhotoActivity.this)
.load(url)
.placeholder(R.drawable.ic_baseline_wallpaper_24)
.into(imgPhoto);
}
}
'Android' 카테고리의 다른 글
Android [AWS람다 메모앱] Retrofit2를 이용한 프론트엔드 CRUD, 로그인,회원가입,메인리사이클뷰,메모생성,조회,수정,삭제 (0) | 2023.02.10 |
---|---|
Android [메모앱] Retrofit2 기본설정, 회원가입, 로그인 (0) | 2023.02.09 |
Android 유튜브 API 썸네일 이미지를 안드로이드에서 열어보기 (0) | 2023.02.07 |
Android [공유인텐트] (0) | 2023.02.07 |
Android [프로필 리사이클앱] 이미지 레이아웃 배치 / 선택한 이미지 크게보기 (0) | 2023.02.07 |