Java/Android

RecyclerView에 대해 알아보자

탕구리당 2017. 4. 29. 07:13
반응형


RecyclerView 란?

1. ListView의 기능을 보완하기 위해서 만들어진 뷰

2. 기존의 ListView에서 레이아웃 매니져를 추가하여 리스트 타입을 쉽게 변경 할 수 있다.

3..ListView와는 다르게 Viewholder의 사용이 필수적이다.( 재활용을 적극 권장하는 구조)


RecyclerView가 호출되는 순서는 다음과 같다.



1) 레이아웃 매니저가 getViewForPosition으로 view를 요청

2) RecyclcerView는 캐시에 getViewForPosition으로 확인. 있으면 LayoutManager에게 반환

3) 캐시에 없으면 adapter에게 type이 뭔지 물어보고 Recycled Pool에 getViewHolderByType으로 요청

4) Pool에 있으면 반환, 없으면 adapter에게 createViewHolder로 아이템 생성.

5) 뷰를 찾으면 adapter에서 bindview를 하고 LayoutManager에게 리턴.

6) LayoutManager는 RecyclerView에게 addView를 수행하고 adapter의 onViewAttachedToWindow가 호출됨.


주요클래스

1. Adapter : 데이터와 뷰를 연결시켜주는 고리(?)라고 생각하면 좋을것 같다.


2.Viewholder : 앞에서 말한거와 같이 뷰의 재사용을 위해 목록에서 사라지는 뷰를 임시저장하는 역할을 한다.

- 일반적인 리스트뷰에선 순서가 지나간 뷰가 없어지고  row를 그릴때마다 findViewById를 호출하게 되어 비용이 높아집니다.


3.LayoutManager : 아이템 항목을 배치한다. 뷰가 어느 위치에 놓일지 정해준다.


우선 RecyclerView을 사용을 위해 그레들에 라이브러리를 추가해준다.

com.android.support:recyclerview-v7:25.1.1

- 추가방법

1. 직접 그래들 파일에 작성하는 방법 

2. file -> ProjectStructure -> app -> Dependencies 에서 추가해주는 방법이 있습니다.



메인 엑티비티 소스 구성

- 기본적인 뷰 선언과

- 아이템 클릭을 확인해볼 클릭리스너 설정

public class RecyclerActivity extends AppCompatActivity
{
    android.support.v7.widget.RecyclerView recyclerView; //리사이클러뷰 선언
    ArrayList mydata; // 리스트에 들어갈 데이터 셋
    RecyclerView_Adpater adapter; //리사이클러뷰 어뎁터
    LinearLayoutManager linearLayoutManager; //사용할 레이아웃 매니저
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recycler_view);


        recyclerView = (RecyclerView)findViewById(R.id.rcv);
        recyclerView.setHasFixedSize(true);
        recyclerView.addItemDecoration(new DividerItemDecoration(getApplicationContext(), DividerItemDecoration.VERTICAL));
        // 이부분에 대해서는 저도잘 모르겠네요
        // 나중에 꼭 찾아서 포스팅 해놓기
        
        //레이아웃 매니저 사용, 설정
        linearLayoutManager = new LinearLayoutManager(this);
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);

        mydata = new ArrayList();

        // 데이터셋과 리스너를 어뎁터 생성자에 셋팅, 리사이클러뷰 어뎁터에 셋어뎁터
        adapter = new RecyclerView_Adpater(mydata, clicklistener);
        recyclerView.setAdapter(adapter);


    }
    public View.OnClickListener clicklistener = new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            final int position = recyclerView.getChildPosition(v);
            Toast.makeText(RecyclerActivity.this, "gdgd", Toast.LENGTH_SHORT).show();
        }
    };
}


두번째로 데이터셋 

- 저는 하나의 이미지 뷰와 두개의 텍스트뷰를 사용할것이기 때문에, 이미지 아이디를 담을 int형 변수,String형 변수를 선언했습니다.


public class mydata
{
    int img;
    String title;
    String content;
    public mydata(int img, String title, String content)
    {
        this.img = img;
        this.title = title;
        this.content = content;
    }

}

세번째로 Adapter

-  RecyclerView.Adpater를 상속받기 위해서는 3가지 메소드를 오버라이드 해주어야됩니다.

-  OnCreateViewHolder는 위에서 언급한 바와 같이 존재하는 children이 없을때 뷰를 새로 만들어준다.

public class RecyclerView_Adpater extends RecyclerView.Adapter<myViewHolder>

{ ArrayList mydata; View.OnClickListener clickListener; public RecyclerView_Adpater(ArrayList mydata, View.OnClickListener clickListener) { this.mydata = mydata; this.clickListener = clickListener; } // 뷰홀더 객체 생성 @Override public myViewholder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listitem, parent, false); //리스트로 만들고자 하는 레이아웃을 객체화 myViewholder myviewholder = new myViewholder(view); // 뷰홀더를 통해 메모리 할당 view.setOnClickListener(clickListener); return myviewholder; } // 어떤 객체를 바인딩 할지 설정 @Override public void onBindViewHolder(myViewholder holder, int position) { holder.img.setImageResource(mydata.get(position).img); holder.tv.setText(mydata.get(position).title); holder.tv1.setText(mydata.get(position).content); } @Override public int getItemCount() { return mydata !=null ? mydata.size():0; } }

네번째 ViewHolder

public class myViewholder extends RecyclerView.ViewHolder
{
    ImageView img;
    TextView tv;
    TextView tv1;

    public myViewholder(View itemView)
    {
        super(itemView);
        img = (ImageView) itemView.findViewById(R.id.pic);
        tv = (TextView)itemView.findViewById(R.id.textView);
        tv1 = (TextView)itemView.findViewById(R.id.textView1);
    }
}


반응형