사용할 포스팅 :
https://itstudy-mary.tistory.com/222
결과화면 :
(연결될 의존성)
앱 수준의 build.gradle :
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'com.squareup.retrofit2:retrofit:2.1.0'
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.google.android.material:material:1.2.0-alpha02'
implementation 'com.makeramen:roundedimageview:2.3.0'
compileOnly 'org.projectlombok:lombok:1.18.10'
annotationProcessor 'org.projectlombok:lombok:1.18.10'
먼저 이 리사이클러 뷰로 돌릴 하나의 카드를 제작한다.
card_item.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
android:id="@+id/frame_card"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:id="@+id/cardView"
android:layout_margin="20dp"
android:layout_width="match_parent"
android:layout_height="120dp"
app:cardCornerRadius="10dp"
app:cardElevation="20dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:textStyle="bold"
android:text="벤자민 버튼의 시간은 거꾸로 간다."
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_rating"
android:layout_width="29dp"
android:layout_height="23dp"
android:layout_marginTop="12dp"
android:text="9.9"
app:layout_constraintEnd_toEndOf="@+id/tv_title"
app:layout_constraintTop_toBottomOf="@+id/tv_title" />
<RatingBar
android:id="@+id/rating_bar"
style="?android:attr/ratingBarStyleIndicator"
android:layout_width="186dp"
android:layout_height="36dp"
android:layout_marginTop="28dp"
android:numStars="5"
app:layout_constraintEnd_toEndOf="@+id/tv_rating"
app:layout_constraintTop_toTopOf="@+id/tv_rating" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.makeramen.roundedimageview.RoundedImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/iv_poster"
android:src="@drawable/main"
android:layout_marginLeft="40dp"
android:layout_marginTop="10dp"
android:layout_width="110dp"
android:layout_height="120dp"
android:scaleType="fitXY"
app:riv_corner_radius="20dip"
app:riv_border_width="2dip"
app:riv_border_color="#FFFFFF"
app:riv_mutate_background="true"
app:riv_tile_mode="clamp" />
</RelativeLayout>
</FrameLayout>
그리고 툴바는 커스텀 툴바를 이용한다.
toolbar_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar
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"
android:id="@+id/toolbar"
android:elevation="20dp"
app:contentInsetStart="0dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_marginLeft="10dp"
android:id="@+id/menu_Icon"
android:layout_width="45dp"
android:layout_height="40dp"
android:src="@drawable/ic_dehaze"
android:scaleType="fitXY"
android:layout_centerVertical="true"/>
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:textSize="25sp"
android:textStyle="bold"
android:text="Movie"
android:gravity="center_vertical|center_horizontal" />
<ImageView
android:layout_marginRight="10dp"
android:id="@+id/search_icon"
android:layout_width="45dp"
android:layout_height="40dp"
android:src="@drawable/ic_search"
android:scaleType="fitXY"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"/>
</RelativeLayout>
</androidx.appcompat.widget.Toolbar>
이제 메인화면에 리사이클러 뷰와 툴바를 붙인다.
activity_main.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"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<include layout="@layout/toolbar_main"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rc_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#F5F3F3"/>
</LinearLayout>
먼저, 레트로핏을 이용해 데이터를 가져온다.
데이터를 가지고 올 모델 클래스를 만든다
YtsData.java
package com.mary.movieapp;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class YtsData {
private String status;
private String status_message;
private MyData data;
@Data
public class MyData {
private int movie_count;
private int limit;
private int page_number;
private List<Movie> movies;
@Data
public class Movie {
private String title;
private float rating;
private String medium_cover_image;
}
@Override
public String toString() {
return "MyData{" +
"movie_count=" + movie_count +
", limit=" + limit +
", page_number=" + page_number +
", movies=" + movies +
'}';
}
}
@Override
public String toString() {
return "YtsData{" +
"status='" + status + '\'' +
", status_message='" + status_message + '\'' +
", data=" + data +
'}';
}
}
package com.mary.movieapp;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class YtsData {
private String status;
private String status_message;
private MyData data;
@Data
public class MyData {
private int movie_count;
private int limit;
private int page_number;
private List<Movie> movies;
@Data
public class Movie {
private String title;
private float rating;
private String medium_cover_image;
}
@Override
public String toString() {
return "MyData{" +
"movie_count=" + movie_count +
", limit=" + limit +
", page_number=" + page_number +
", movies=" + movies +
'}';
}
}
@Override
public String toString() {
return "YtsData{" +
"status='" + status + '\'' +
", status_message='" + status_message + '\'' +
", data=" + data +
'}';
}
}
다음 연결할 인터페이스를 생성한다.
YtsService.java
package com.mary.movieapp;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.GET;
import retrofit2.http.Query;
import retrofit2.http.QueryMap;
public interface YtsService {
@GET("list_movies.json")
Call<YtsData> 영화목록가져오기(
@Query("sort_by") String sort_by,
@Query("limit") int limit,
@Query("page") int page
);
public static final Retrofit retrofit=new Retrofit.Builder()
.baseUrl("https://yts.mx/api/v2/")
.addConverterFactory(GsonConverterFactory.create())
.build();
}
이전 데이터에서는 데이터를 가져오는 자원 리소스를 메인에 설정했지만, 여기서는 가독성을 위해 따로 빼서 제작했다.
MainActivity.java
package com.mary.movieapp;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Main_Activity";
private Context mContext=MainActivity.this;
private ImageView ivImage;
private TextView tvTitie, tvScore;
private YtsAdapter cardAdapter=new YtsAdapter();
private RecyclerView.LayoutManager layoutManager;
private RecyclerView rcCard;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
initDownload();
listener();
}
private void init(){
ivImage=findViewById(R.id.iv_poster);
tvTitie=findViewById(R.id.tv_title);
tvScore=findViewById(R.id.tv_rating);
rcCard=findViewById(R.id.rc_card);
layoutManager=new LinearLayoutManager(mContext,RecyclerView.VERTICAL,false);
rcCard.setLayoutManager(layoutManager);
}
private YtsData initDownload(){
YtsService ytsService=YtsService.retrofit.create(YtsService.class);
Call<YtsData> call= ytsService.영화목록가져오기("rating",10,1);
call.enqueue(new Callback<YtsData>() {
@Override
public void onResponse(Call<YtsData> call, Response<YtsData> response) {
if(response.isSuccessful()==true) {
YtsData ytsData = response.body();
Log.d(TAG, "onResponse: "+ytsData);
//리사이클러 뷰에 여기서 연결하기
rcCard.setAdapter(cardAdapter);
cardAdapter.addCardModel(ytsData.getData().getMovies());
}
}
@Override
public void onFailure(Call<YtsData> call, Throwable t) {
Log.d(TAG, "onFailure: "+t);
Toast.makeText(mContext, "다운로드 실패", Toast.LENGTH_SHORT).show();
}
});
return null;
}
담아온 데이터를 돌려줄 리사이클러뷰 어댑터를 제작한다.
YtsAdapter.java
package com.mary.movieapp;
import android.media.Rating;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
import java.util.List;
public class YtsAdapter extends RecyclerView.Adapter<YtsAdapter.CardView> {
private static final String TAG = "YtsAdapter";
private List<YtsData.MyData.Movie> cardModels = new ArrayList<>();
public void addCardModel(YtsData.MyData.Movie movie) {
cardModels.add(movie);
}
public void addCardModel(List<YtsData.MyData.Movie> movies) {
cardModels = movies;
}
@NonNull
@Override
public CardView onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.card_item, parent, false);
return new CardView(view);
}
@Override
public void onBindViewHolder(@NonNull CardView holder, int position) {
Log.d(TAG, "onBindViewHolder: "+position);
holder.setCard(cardModels.get(position));
}
@Override
public int getItemCount() {
return cardModels.size();
}
public static class CardView extends RecyclerView.ViewHolder {
private TextView tvTitle, tvScore;
private ImageView ivImage;
private RatingBar ratingBar;
public CardView(@NonNull View itemView) {
super(itemView);
tvTitle = itemView.findViewById(R.id.tv_title);
tvScore = itemView.findViewById(R.id.tv_rating);
ivImage = itemView.findViewById(R.id.iv_poster);
ratingBar = itemView.findViewById(R.id.rating_bar);
}
public void setCard(YtsData.MyData.Movie movie) {
tvTitle.setText(movie.getTitle());
tvScore.setText(movie.getRating() + "");
Picasso.get().load(movie.getMedium_cover_image()).into(ivImage);
ratingBar.setRating(movie.getRating() / 2);
}
}
}
반응형
'Android' 카테고리의 다른 글
안드로이드 스튜디오, Java] Room 라이브러리를 이용한 내부 데이터베이스 이용하기 (0) | 2020.08.05 |
---|---|
안드로이드 스튜디오, JAVA ] 서비스 (0) | 2020.08.05 |
Android Studio, JAVA] 피카소, Glide 라이브러리 (0) | 2020.07.31 |
안드로이드 스튜디오, JAVA 실습 : 영화 API 사이트에서 데이터 가져오기 (0) | 2020.07.30 |
안드로이드 스튜디오, JAVA] Retrofit2를 이용하여 데이터 통신하기 (0) | 2020.07.29 |