관리 메뉴

정상에서 IT를 외치다

[Android, RecyclerView] 리사이클러 뷰 만들기 본문

안드로이드

[Android, RecyclerView] 리사이클러 뷰 만들기

Black-Jin 2018. 9. 18. 15:12
728x90
반응형


안녕하세요. 블랙진입니다.


이번 시간부터 안드로이드 리사이클러뷰에 관해 단계별로 포스팅을 하겠습니다.

그 첫번 째 시간으로 아래와 같은 리사이클러뷰를 만들어 보겠습니다.





0.  package 준비






1.  app 단계의 build.gradle 추가

implementation 'com.android.support:appcompat-v7:28.0.0-rc02'
implementation "com.android.support:recyclerview-v7:28.0.0-rc02"
implementation "com.android.support:cardview-v7:28.0.0-rc02"

implementation "com.github.bumptech.glide:glide:3.7.0"

recyclerView, cardView, glide 3가지 라이브러리를 추가해줍니다

이때 recyclerView, cardView 의 버전 '28.0.0-rc02' 는 본인의 support:appcompat-v7 의 버전과 동일하게 설정해 줍니다.



ex) 만약 본인의  support:appcompat-v7:27.1.1 이면 아래와 같이 설정해주시면 됩니다.

implementation 'com.android.support:appcompat-v7:27.1.1'
implementation "com.android.support:recyclerview-v7:27.1.1"
implementation "com.android.support:cardview-v7:27.1.1"

implementation "com.github.bumptech.glide:glide:3.7.0"



2. 인터넷 접근 권한 설정


AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />

이미지는 서버로 부터 받아올 예정입니다. 

이에 AndroidManifest 상단에 인터넷 접근 권한을 설정해 줍니다.


아래는 사용할 이미지 주소입니다. 모두 구글 이미지 검색을 통해 얻은 주소입니다:)

이미지1, 이미지2, 이미지3




3.  activity_main.xml , item_movie.xml 을 준비해 줍니다.


 activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

</android.support.constraint.ConstraintLayout>


item_movie.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
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.support.v7.widget.CardView
android:id="@+id/cv_item_movie_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="4dp"
app:cardUseCompatPadding="true"
app:cardElevation="4dp">

<ImageView
android:id="@+id/iv_item_movie"
android:scaleType="centerCrop"
android:layout_width="match_parent"
android:layout_height="240dp" />

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:paddingLeft="16dp"
android:paddingRight="8dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:alpha="0.6"
android:background="@android:color/black"
android:orientation="vertical">

<TextView
android:id="@+id/tv_item_movie_genre"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Movie Genre"
android:textColor="@android:color/white"
android:textSize="12dp"/>

<TextView
android:id="@+id/tv_item_movie_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:text="Title"
android:textColor="@android:color/white"
android:textSize="18dp"/>


<TextView
android:id="@+id/tv_item_movie_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Movie Content"
android:textColor="@android:color/white"/>

</LinearLayout>

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

</FrameLayout>




4. Movie 데이터를 저장할 객체를 생성해 줍니다.

public class Movie {

private String url;
private String genre;
private String title;
private String content;

public Movie(String url, String genre, String title, String content) {

this.url = url;
this.genre = genre;
this.title = title;
this.content = content;

}

public String getUrl() {
return url;
}

public String getGenre() {
return genre;
}

public String getTitle() {
return title;
}

public String getContent() {
return content;
}
}




5. Adapter 를 생성해 줍니다.

public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.ViewHolder> {

private ArrayList<Movie> items = new ArrayList<>();

@NonNull
@Override
public MovieAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {

View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_movie, parent, false);
ViewHolder viewHolder = new ViewHolder(itemView);

return viewHolder;
}

@Override
public void onBindViewHolder(@NonNull MovieAdapter.ViewHolder viewHolder, int position) {

Movie item = items.get(position);

Glide.with(viewHolder.itemView.getContext())
.load(item.getUrl())
.into(viewHolder.ivMovie);

viewHolder.tvTitle.setText(item.getTitle());
viewHolder.tvContent.setText(item.getContent());
viewHolder.tvGenre.setText(item.getGenre());

}

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

public void setItems(ArrayList<Movie> items) {
this.items = items;
}

class ViewHolder extends RecyclerView.ViewHolder {

ImageView ivMovie;
TextView tvTitle, tvContent, tvGenre;

ViewHolder(View itemView) {
super(itemView);

ivMovie = itemView.findViewById(R.id.iv_item_movie);

tvTitle = itemView.findViewById(R.id.tv_item_movie_title);
tvContent = itemView.findViewById(R.id.tv_item_movie_content);
tvGenre = itemView.findViewById(R.id.tv_item_movie_genre);
}
}
}



6. 샘플 데이터를 생성해 줍니다.

public class SampleData {

ArrayList<Movie> items = new ArrayList<>();

public ArrayList<Movie> getItems() {

Movie movie1 = new Movie("http://static.hubzum.zumst.com/hubzum/2018/02/06/09/962ec338ca3b4153b037168ec92756ac.jpg",
"action", "Black Panther", "this movie open in 2018.01");

Movie movie2 = new Movie("https://t1.daumcdn.net/cfile/tistory/0138F14A517F77713A",
"action", "Iron Man 3", "this movie open in 2013.04");

Movie movie3 = new Movie("https://i.ytimg.com/vi/5-mWvUR7_P0/maxresdefault.jpg",
"action", "Ant Man", "this movie open in 2015.06");

items.add(movie1);
items.add(movie2);
items.add(movie3);

items.add(movie1);
items.add(movie2);
items.add(movie3);

items.add(movie1);
items.add(movie2);
items.add(movie3);

return items;
}
}




7. MainActivity 에서 뷰 초기화 및 어댑터를 연결해 줍니다.

public class MainActivity extends AppCompatActivity {

private MovieAdapter adapter = new MovieAdapter();

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

//recycleView 초기화
RecyclerView recyclerView = findViewById(R.id.recycler_view);

recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);

//아이템 로드
adapter.setItems(new SampleData().getItems());

}
}


1~7 번 까지 코드를 모드 따라 하시면 멋지게 리사이클러뷰를 만드셨을 겁니다.


설명보다는 빠른 구현을 위해 코드 위주로 설명했습니다. 혹시 궁금한 점이나 안되신 점이 있으면 댓글 부탁드리겠습니다.


완성코드 공유 하도록 하겠습니다! 그럼 안뇨옹 :)



<리사이클러뷰에 관한 또 다른 포스팅 gogo ~!>


리사이클러뷰 레이아웃 매니저의 종류

리사이클러뷰에 아이템 데코레이션 적용해 보기

반응형
12 Comments
  • 프로필사진 Lee 2018.09.19 23:35 안녕하세요.
    이해하기 쉽게 코드를 설명해 주셔서 감사합니다.
    위의 경우에는 한 화면에서의 리사이클러뷰의 경우였습니다.
    혹시 탭레이아웃을 사용하여 다른 탭에 다른 리사이클러뷰를 만들경우 어떻게 하나요?(여러탭이 존재할 경우 adapter도 여러개 생성하나요?)
    아직 코드 사용이 익숙하지 못해 응용하는데 어려움이 있습니다.
    혹시 시간 있으시면 예시로 알려주시면 감사하겠습니다.
  • 프로필사진 Black-Jin 2018.09.20 09:53 신고 안녕하세요. 먼저 긴 글 읽어 주셔서 감사합니다 :)

    다른 화면에서 리사이클러뷰를 만들 경우 댓글에 적어주신것처럼 adapter 도 여러개 생성해주시는 게 좋습니다.

    예시는
    '탭 레이아웃이 모든 것' 이라는 포스팅이 있습니다.
    http://black-jin0427.tistory.com/49

    A ~ E 5개의 프래그먼트로 이루어진 탭 레이아웃입니다. 이 예제를 이용해 각 화면마다 adapter 를 생성해서 테스트 해보시면 좋을 것 같습니다. 작업하시면서 궁금한 점은 언제든지 질문 해주세요.
  • 프로필사진 Lee 2018.09.20 22:04 빠른 답변 너무 감사드립니다. 알려주신 블랙진님의 포스팅을 보고 다시 공부하겠습니다.
  • 프로필사진 Black-Jin 2018.09.21 10:02 신고 저도 글 읽어주셔서 감사합니다 :)
  • 프로필사진 dlsrud0415 2019.04.29 23:32 안녕하세요. 너무 자세하게 포스팅 해주셔서 공부에 많은 도움이 되고 있습니다.
    한 가지 궁금한 점이 있는 데 공유해주신 파일을 다운받아 실행해 보았는데
    모두 제대로 실행되고 있으나 사진 세개 중 하나만 정상으로 나오고 두개는 나오지 않고 있습니다.
    어떤 점을 개선해야 할까요?
  • 프로필사진 Black-Jin 2019.04.30 09:26 신고 안녕하세요. dlsrud0415님 :)
    모두 제대로 실행 되었고 일부 이미지만 나온다면 안나오는 이미지 주소가 정확한지 확인해보세요. 확인하실러면 이미지 주소를 인터넷 브라우저 주소창에 적으면 정상적으로 이미지가 나와야합니다.

    이미지 주소가 문제가 아니라면 깃 허브에 있는 완성코드를 보고 비교해 보시면 좋을 것 같습니다 :)
  • 프로필사진 yoo 2019.05.06 22:32 activity가 아닌 fragment에 recyclerview를 하고 싶은데 계속 오류가 나네요ㅠ
    해결방법이 있을까요?
  • 프로필사진 Black-Jin 2019.05.13 22:29 신고 fragment에서 사용시 this -> getActivity() 로 변경되는 것 말고는 거의 동일합니다. 다른 부분의 오류 내용이면 댓글에 남겨주시면 문제를 해결하는데 좀더 도움을 드릴 수 있을 것 같습니다.
  • 프로필사진 saii 2020.06.26 17:25 프래그먼트에서 view = inflater...~ 이렇게 된다면 view.findViewByID(R.id.recyclerview) 하면 프래그먼트에서 리사이클러뷰 인식하여 사용 가능합니다. LayoutManage는 프래그먼트에선 Actvity가 아니기 때문에 this가 안됩니다. 그래서 this 대신 getActivity()) 하면됩니다.
  • 프로필사진 ㅈㅇㅅ 2021.03.26 15:22 멋있는 자료 이렇게 올려주셔서 정말 감사합니다. 덕분에 많은 도움을 받고 갑니다. 감사합니다.
  • 프로필사진 Black-Jin 2021.03.28 16:39 신고 도움이 되셨다니 저도 좋습니다!
    댓글 감사합니다. > ,. < //
  • 프로필사진 kkk 2021.10.24 14:47 안녕하세요. 글 잘읽었습니다. 다름아니라 제가 aws lambda에서 json( url, time , serial)로 받아서 https://jbin0512.tistory.com/125?category=984038 이분 글 보고 데이터들 다 불러오는데는 성공했습니다. 이제 여기서recycler 안에 이미지뷰에서 glide로 json 속 url을 불러오고 싶은데 코드를 어떻게 작성해야될지를 모르겠어요 ㅠ
댓글쓰기 폼