-----------------------------

디버깅 하는 법

 

로그를 먼저 찍고 보는 연습하고 디버그 하자

 

 

 

 

 

 

Step Over 같은 깊이 F8

Step Into 함수안으로 F7

 

sts에서도 라인에 더블클릭하여 디버깅 함

-----------------------

 

https://recipes4dev.tistory.com/154

 

안드로이드 리사이클러뷰 기본 사용법. (Android RecyclerView)

1. 안드로이드 리사이클러뷰(RecyclerView) 리사이클러뷰(RecyclerView)는, "많은 수의 데이터 집합을, 제한된 영역 내에서 유연하게(flexible) 표시할 수 있도록 만들어주는 위젯"입니다. [안드로이드 개발

recipes4dev.tistory.com

 

mxl 가져오기

https://github.com/codingspecialist/Android-Retrofit2-MovieApp-V1-Design

 

codingspecialist/Android-Retrofit2-MovieApp-V1-Design

Contribute to codingspecialist/Android-Retrofit2-MovieApp-V1-Design development by creating an account on GitHub.

github.com

 

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"/>

    <include layout="@layout/card_item" />
    <include layout="@layout/card_item" />
    <include layout="@layout/card_item" />
    <include layout="@layout/card_item" />
    <include layout="@layout/card_item" />

    <!--리사이클러뷰 넣어야 함-->

</LinearLayout>

 

card_item.xml

더보기
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    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>

 

 

https://github.com/codingspecialist/Android-Retrofit2-MovieApp-V2-Complete

 

codingspecialist/Android-Retrofit2-MovieApp-V2-Complete

Contribute to codingspecialist/Android-Retrofit2-MovieApp-V2-Complete development by creating an account on GitHub.

github.com

 

YtsData

더보기
package com.jaybon.movieapp;

import java.util.List;

import lombok.Data;

@Data
public class YtsData {
    private String status;
    private String status_message;
    private MyData data;

    @Data
    public class MyData { // 외부에서 접근할 필요가 있는 것은 public

        private int movie_count;
        private int limit;
        private int page_number;
        private List<Movie> movies;

        @Data
        class Movie{
            private String title;
            private float rating;
            private String medium_cover_image;
        }
    }

}

 

 

레트로핏 서비스(레파지토리) 예시

package com.jaybon.movieapp;

import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.GET;
import retrofit2.http.Path;
import retrofit2.http.Query;

// YtsService 또는 레파지토리로 만들면된다
public interface YtsService {

    @GET("list_movies.json")
    Call<YtsData> 영화목록가져오기(
            @Query("sort_by") String sort_by,
            @Query("limit") int limit,
            @Query("page") int page
    );

    // onCreate에서 안만들고 여기서 바로 만들어버림
    // 서비스가 많아지면 컨피그 인터페이스 파일 만들어서 세팅
    public static final Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://yts.mx/api/v2/")
            .addConverterFactory(GsonConverterFactory.create())
            .build();
}

 

 

메인액티비티

 

 

 

activity_main.xml

 

YtsAdapter

 

피카소 버전에 따라 with나 get을 사용해야한다

implementation 'com.squareup.picasso:picasso:2.71828'

 

더보기
package com.jaybon.movieapp;

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 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.MyViewHolder>{

    private static final String TAG = "YtsAdapter";

    // 어댑터는 항상 데이터(컬렉션)을 들고 있어야한다.
    private List<YtsData.MyData.Movie> movies = new ArrayList<>();

    // 아이템을 개별로 넣기
    public void addItem(YtsData.MyData.Movie movie){
        movies.add(movie);
    }

    // 리스트를 바로 넣기
    public void addItems(List<YtsData.MyData.Movie> movies){
        this.movies = movies;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View cardItemView = inflater.inflate(R.layout.card_item, parent, false); // false : 동적
        return new MyViewHolder(cardItemView);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        holder.setItem(movies.get(position));
    }

    @Override
    public int getItemCount() {
        return movies.size();
    }

    // 책꽂이 (View들을 채워 두면 됨)
    // 뷰가 만들어지려면 card_item이 들고있는 모든 뷰들을 전역변수로 설정해야함
    public static class MyViewHolder extends RecyclerView.ViewHolder {

        private ImageView ivPoster;
        private TextView tvTitle;
        private TextView tvRating;
        private RatingBar ratingBar;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            ivPoster = itemView.findViewById(R.id.iv_poster);
            tvTitle = itemView.findViewById(R.id.tv_title);
            tvRating = itemView.findViewById(R.id.tv_rating);
            ratingBar = itemView.findViewById(R.id.rating_bar);
        }

        public void setItem(YtsData.MyData.Movie movie){
            tvTitle.setText(movie.getTitle());
            tvRating.setText(movie.getRating()+"");
            Picasso.get().load(movie.getMedium_cover_image()).into(ivPoster);
            ratingBar.setRating(movie.getRating()/2);
        }

    }

}

 

MainActivity

더보기
package com.jaybon.movieapp;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.content.Context;
import android.os.Bundle;
import android.util.Log;
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; // 메인액티비티는 액티비티+xml정보

    private RecyclerView recyclerView;
    private RecyclerView.LayoutManager layoutManager; // 리사이클러뷰는 무조건 이것이 필요하다
    private YtsAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 오브젝트 초기화
        init();



        // 다운로드
        initDownload();
        
    }

    private void init(){
        recyclerView = findViewById(R.id.recycler_view);
//        recyclerView.setHasFixedSize(); // 리사이클러뷰 높이

        layoutManager = new LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false);
        recyclerView.setLayoutManager(layoutManager);
        adapter = new YtsAdapter();
    }

    // Yts 데이터 받기
    private void initDownload(){
        YtsService ytsService = YtsService.retrofit.create(YtsService.class);

        // 미래의 데이터를 call에 담기 (퓨처)
        Call<YtsData> call = ytsService.영화목록가져오기("rating",10,1);

        // enqueue가 하는 역할은 응답 받아주는 것 (프로미스의 then 과 같음)
        call.enqueue(new Callback<YtsData>() {
            @Override
            public void onResponse(Call<YtsData> call, Response<YtsData> response) {
                if(response.isSuccessful() == true){
                    YtsData ytsData = response.body();
                    // 리사이클러뷰 어댑터에 연결
                    recyclerView.setAdapter(adapter);
                    adapter.addItems(ytsData.getData().getMovies());

                }
            }

            @Override
            public void onFailure(Call<YtsData> call, Throwable t) { // 에러가 궁금하면 t.를 통해서 확인
                Toast.makeText(MainActivity.this, "다운로드 실패", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

 

이벤트다는법

1. 라이브러리 없이 뷰를 연결

뷰가 만들어지는 곳에서 이벤트 달기

교재 417

 

2.메인adapter에 setItemClicklistener달기

교재 434

 

3. 메인에 리스너

 

 

 

4. 라이브러리

 

 

 

 

 

+ Recent posts