반응형

리스트뷰처럼 여러 개의 아이템을 한꺼번에 화면에 보여주고 싶은데 상하 스크롤이 아니라 좌우 스크롤일 때는 어떻게 해야 할까요?

리스트뷰는 상하 스크롤만을 지원합니다.

이 때문에 리스트뷰와 같은 기능을 가지고 있으면서도 좀더 확장 가능한 위젯이 외부 라이브러리로 제공됩니다.

바로 리싸이클러뷰라는 것인데요리스트뷰와 비슷하지만 약간 다르게 사용합니다.

리싸이클러뷰를 이용해 여러 개의 아이템을 어떻게 보여주는지 알아봅시다.



RecyclerView

리싸이클러뷰는 리스트뷰처럼 상하 스크롤이 가능하게 만들 수도 있고 좌우 스크롤이 가능하게 만들 수도 있습니다.

왜냐하면 처음 만들어질 때부터 레이아웃을 유연하게 구성할 때 있도록 설계되었기 때문입니다.

그리고 각각의 아이템이 화면에 보이는 과정에서 메모리를 덜 사용하도록 캐시 메커니즘이 구현되어 있습니다.

리스트뷰도 뷰홀더(ViewHolder)를 이용해 캐시 메커니즘을 사용할 수 있지만 리싸이클러뷰는 이 방식을 기본적으로 사용합니다.

이러한 장점들 때문에 실무에서는 리스트뷰보다 리싸이클러뷰를 사용하는 경우가 더 많습니다.

롤리팝(5.0) 버전부터 리싸이클러뷰가 안드로이드 SDK에 포함되었으니 지금은 상당히 많은 앱들에서 리싸이클러뷰가 사용됩니다.

리싸이클러뷰도 선택 위젯이므로 어댑터를 사용한다는 것을 잊으면 안됩니다.

 

화면 레이아웃에 추가하기

리싸이클러뷰는 support 패키지 안에 포함되어 있습니다.

외부 라이브러리이므로 File>Project Structure 메뉴에서 리싸이클러뷰를 사용하기 위한 라이브러리를 포함시켜야 합니다.

라이브러리를 포함시키면 build.gradle (Module: app)의 dependencies 항목에 다음과 같이 추가됩니다.

implementation 'com.android.support:recyclerview-v7:26.1.0'

외부 라이브러리의 버전은 사용 시점에 따라 달라질 수 있다는 점에 주의합니다.

리싸이클러뷰를 사용할 수 있게 되었다면 화면을 위한 XML 레이아웃에 태그를 추가합니다.

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

외부 라이브러리에 들어있는 뷰이므로 패키지 이름까지 모두 입력해줍니다.

 

어댑터 만들기

리싸이클러뷰는 껍데기 역할만 하므로 각 아이템을 위한 데이터를 담아둘 수 있는 어댑터가 필요합니다.

우선 각 아이템을 위한 데이터를 위해 클래스를 하나 정의합니다.

public class SingerItem {

    String name;
    String mobile;

SingerItem 클래스에는 두 개의 변수를 선언하였으며 이름과 전화번호를 담아둘 수 있게 되어 있습니다.

어댑터에는 이 클래스를 이용해 만들어진 객체를 여러 개 담아둘 수 있도록 하고 화면에 보일 때 사용되는 각각의 뷰는 뷰홀더에 담아두게 됩니다.

static class ViewHolder extends RecyclerView.ViewHolder {
    TextView textView;
    TextView textView2;

    OnItemClickListener listener;

    public ViewHolder(View itemView) {
        super(itemView);

        textView = (TextView) itemView.findViewById(R.id.textView);
        textView2 = (TextView) itemView.findViewById(R.id.textView2);

        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int position = getAdapterPosition();

                if (listener != null) {
                    listener.onItemClick(ViewHolder.this, view, position);
                }
            }
        });
    }

    public void setItem(SingerItem item) {
        textView.setText(item.getName());
        textView2.setText(item.getMobile());
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        this.listener = listener;
    }

}

뷰홀더 객체가 생성될 때 뷰가 전달되도록 만듭니다.

이 뷰홀더 객체는 뷰를 담아두는 역할을 하면서 동시에 뷰에 표시될 데이터를 설정하는 역할을 맡을 수 있습니다.

setItem 메소드는 SingerItem 객체를 전달받아 뷰홀더 안에 있는 뷰에 데이터를 설정하는 역할을 합니다.

어댑터는 RecyclerView.Adapter 클래스를 상속하여 만듭니다.

어댑터 안에는 ArrayList 변수를 선언하고 그 안에 여러 개의 SingerItem 객체가 들어갈 수 있도록 합니다.

이 어댑터에는 세 개의 중요한 메소드가 재정의되어야 합니다.

getItemCount는 어댑터에서 관리하는 아이템의 개수를 반환합니다.

onCreateViewHolder 안에서는 각 아이템을 위한 XML 레이아웃을 이용해 뷰 객체를 만든 후 뷰홀더에 담아 반환합니다.

이때 XML 레이아웃을 인플레이션하여 설정할 ViewGroup 객체는 onCreateViewHolder 메소드의 파라미터로 전달됩니다.

onBindViewHolder 메소드에서는 뷰홀더에 각 아이템의 데이터를 설정하게 됩니다.

public class SingerAdapter extends RecyclerView.Adapter<SingerAdapter.ViewHolder> {
    Context context;

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

    OnItemClickListener listener;

    public static interface OnItemClickListener {
        public void onItemClick(ViewHolder holder, View view, int position);
    }

    public SingerAdapter(Context context) {
        this.context = context;
    }

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

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View itemView = inflater.inflate(R.layout.singer_item, parent, false);

        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        SingerItem item = items.get(position);
        holder.setItem(item);

        holder.setOnItemClickListener(listener);
    }

    public void addItem(SingerItem item) {
        items.add(item);
    }

    public void addItems(ArrayList<SingerItem> items) {
        this.items = items;
    }

    public SingerItem getItem(int position) {
        return items.get(position);
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        this.listener = listener;
    }

뷰홀더는 재사용되며 각각의 뷰홀더가 화면에 보여지기 전에 onBindViewHolder 메소드가 호출되므로 그 메소드 안에서 데이터가 설정되게 됩니다.

 

리싸이클러뷰에 어댑터 설정

리싸이클러뷰에 어댑터를 설정하는 방법은 리스트뷰와 거의 같습니다.

차이가 나는 것은 레이아웃 매니저를 설정해야 한다는 것입니다.

리싸이클러뷰의 setLayoutManager 메소드를 이용해 레이아웃 매니저를 설정하게 되는데 레이아웃 매니저는 상하 방향으로 레이아웃을 만들 것인지, 아니면 좌우 방향으로 레이아웃을 만들 것인지를 결정합니다.

recyclerView = (RecyclerView) findViewById(R.id.recyclerView);

LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(layoutManager);

adapter = new SingerAdapter(getApplicationContext());

adapter.addItem(new SingerItem("소녀시대", "010-1000-1000"));
adapter.addItem(new SingerItem("걸스데이", "010-2000-2000"));
adapter.addItem(new SingerItem("여자친구", "010-3000-3000"));

recyclerView.setAdapter(adapter);

adapter.setOnItemClickListener(new SingerAdapter.OnItemClickListener() {
    @Override
    public void onItemClick(SingerAdapter.ViewHolder holder, View view, int position) {
        SingerItem item = adapter.getItem(position);

        Toast.makeText(getApplicationContext(), "아이템 선택됨 : " + item.getName(), Toast.LENGTH_LONG).show();
    }
});

어댑터 객체는 setAdapter 메소드를 이용해 설정할 수 있습니다.

 

반응형

'안드로이드 개발 > 부스트코스(안드로이드 프로그래밍)' 카테고리의 다른 글

트윈 애니메이션  (0) 2019.04.02
스레드 애니메이션  (0) 2019.04.02
음성 녹음하기  (0) 2019.03.29
동영상 재생하기  (0) 2019.03.29
음악 재생하기  (0) 2019.03.29
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기