RecyclerView는 Listview의 기능을 모두 갖고 있으면서도, 더 발전된 항목이라 Listview보다 사용을 추천한다고 한다.
1.App단의 Gradle에 라이브러리를 추가해야한다.
implementation 'androidx.recyclerview:recyclerview:1.2.0-alpha05'
2. Activity의 레이아웃은 비교적 간단하다. 화면을 RecyclerView로 꽉 채우면 된다.
-res/layout/activity_news.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/myRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
3. 그 다음으로 RecyclerView의 각 row(행)을 나타내는 레이아웃을 정의해야한다.
-res/layout/row_news.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="200dp"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<!--겹쳐지는 레이아웃은 relative layout-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="100dp">
<ImageView
android:id="@+id/mImageView"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="@null"
android:src="@drawable/header"/>
<TextView
android:id="@+id/mTextViewTitle"
android:layout_width="match_parent"
android:layout_height="40dp"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:layout_marginTop="5dp"
android:gravity="center"
android:textColor="@color/white"
android:textSize="18sp" />
</RelativeLayout>
<TextView
android:id="@+id/mTextViewContent"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center"
android:background="#15000000"
android:textSize="15sp"
android:ellipsize="end"
android:text="The Title Song of this Album is 'Oh My!'"/>
</LinearLayout>
4. 해당 액티비티에서 xml 레이아웃의 RecyclerView를 가지고 Adapter를 설정한다.
=> 이때, LayoutManager에 따라서 RecyclerView에 보여지는 아이템의 배치 방법이 달라진다.
=> 대부분의 경우에는 그냥 일렬로 나열하면 되므로 LinearLayoutManager를 사용하면 된다.
package com.example.practice;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.RelativeLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.textfield.TextInputEditText;
import java.util.ArrayList;
public class NewsActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private String[] myDataset={"1","2"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_news);
mRecyclerView=(RecyclerView) findViewById(R.id.myRecyclerView);
//xml 레이아웃의 recyclerview를 가져와서 adapter를 설정한다.
// 리사이클러뷰에 LinearLayoutManager 객체 지정.=> 일렬로 늘어놓으면 되므로
mRecyclerView.setLayoutManager(new LinearLayoutManager(this)) ;
// 리사이클러뷰에 어댑터를 세팅한다. 이때, 액티비티에서 원하는 String 배열을 넘겨준다.
mAdapter = new CustomAdapter(myDataset) ;
mRecyclerView.setAdapter(mAdapter) ;
}}
5. 마지막으로 adapter를 정의해야 한다.
1) 우선 CustomAdapater는 Recycler.Adapater<RecyclerView.ViewHolder>를 상속받아서 정의하면 된다.
2) CustomAdapter생성자는 myDataset을 인자로 가지는데, NewsActivity.java에서 뷰를 생성할 때 표시하고자 하는 데이터를 전달했었다.
3) 그 다음 ViewHolder에 각 뷰를 보관해야 한다. ViewHolder 객체는 레이아웃의 태그 필드 안에 각 구성 요소 뷰를 저장하므로 반복적으로 조회하지 않고도 즉시 액세스할수 있다.
- 매 리스트의 row마다 findViewById()를 호출하면 매우 큰 비용이 들기 시작할 것이다. 스크롤을 내릴때마다 시간도 오래 들고, 속도 저하를 초래하게 된다.
=>따라서 각 뷰 객체를 뷰 홀더에 보관함으로써 findViewById와 같은 반복적으로 호출되는 메서드를 효과적으로 줄여 속도 향상에 도움을 주게 된다.
## RecyclerView에서 필수로 오버라이딩 해야 하는 세가지 메서드
- onCreateViewHolder = ViewHolder 객체를 생성한다
- onBindViewHolder= ViewHolder에 데이터를 넣는 작업 수행
- getItemCount = data의 개수를 반환해준다.
package com.example.practice;
import android.media.Image;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
//viewHolder란 각 뷰들을 보관하는 Holder객체를 의미한다.
//Viewholder는 태그 필드 안에 각 구성 요소 뷰들을 저장하므로 반복적으로 조회하지않고 즉시 액세스 가능하다.
private String[] localDataSet;
/**
* Provide a reference to the type of views that you are using
* (custom ViewHolder).
*/
//item view를 저장하는 ViewHolder 클래스
public static class ViewHolder extends RecyclerView.ViewHolder {
private final TextView mTextViewTitle;
private final TextView mTextViewContent;
private final ImageView mImageView;
public ViewHolder(View view) {
super(view);
// Define click listener for the ViewHolder's View
//view 객체에 대한 참조
mTextViewTitle = view.findViewById(R.id.mTextViewTitle);
mTextViewContent=view.findViewById(R.id.mTextViewContent);
mImageView=view.findViewById(R.id.mImageView);
}
public TextView getTextView() {
return mTextViewContent;
}
}
/**
* Initialize the dataset of the Adapter.
*
* @param dataSet String[] containing the data to populate views to be used
* by RecyclerView.
*/
//생성자에서 데이터 객체를 전달받는다. 자료형은 임의로 결정 가능.
public CustomAdapter(String[] dataSet) {
localDataSet = dataSet;
}
// Create new views (invoked by the layout manager)
//아이템 뷰를 위한 뷰홀더 객체를 생성하여 리턴한다.
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
// Create a new view, which defines the UI of the list item
//LayoutInflater = 안드로이드에서 view를 생성하는 방법
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.row_news, viewGroup, false);
return new ViewHolder(view);
}
// Replace the contents of a view (invoked by the layout manager)
//position에 해당하는 데이터를 뷰홀더의 아이템뷰에 표시 (view의 내용을 localDataSet으로 교환)
@Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
// Get element from your dataset at this position and replace the
// contents of the view with that element
viewHolder.mTextViewTitle.setText(localDataSet[position]);
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return localDataSet.length;
}
}
'App > Android' 카테고리의 다른 글
안드로이드 스튜디오 블루투스 프로그래밍 (1) | 2021.01.19 |
---|---|
[Android Studio] button을 LinearLayout으로 대체 (0) | 2021.01.15 |
[Android Studio] 로그인 창 레이아웃 만들기 (0) | 2021.01.15 |
Relative Layout, Linear Layout (0) | 2021.01.11 |