기존 ListView 에서는 개발자가 임의로 관여할 수 있는 기회가 적었던 반면,
RecyclerView 는 그 안에다가 효과, 레이아웃의 변경이 가능하다.
ex) LinearLayoutManager / GridLayoutManager / StaggeredGridLayoutManager (높이가 불규칙한 Grid)
1. Graddle 에 dependency 추가
프로젝트 익스플로러에서 '모듈 우클릭' -> 'open module setting' -> 'dependency 탭 선택' -> '우측의 + 버튼 클릭'
library : 이미 다운 받아진 구글의 라이브러리
file : 개발자가 다운 받은 임의의 jar 파일
module : 현재 개발중인 다른 모듈의 라이브러리
com.android.support:recyclerview-v7:24.1.1 추가
Graddle에 추가된 것 확인
dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:recyclerview-v7:24.1.1'
}
2. recycler view xml 파일 준비
fragment_one.xml
<?xml version="1.0" encoding="utf-8"?><android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/recyclerView" />
recycler view 멤버 변수 추가
OneFragment.java
RecyclerView recyclerView;
2. Holder 패턴
findViewById 의 퍼포먼스 문제로 인해서 한번 가져 온 viewId를 지니고 있다가 활용
OneFragment.java
// findViewId의 성능 이슈부분 솔루션
// 내부적으로 holder 객체는 메모리에 누적되어 한번만 view를 find
class MyViewHolder extends RecyclerView.ViewHolder{ public TextView title; // Adapter에서 획득하고자 하는 view
// 매개변수는 항목 layout.xml 초기화 view 계층의 root 객체이다.
// Adapter가 전달할 것임.
public MyViewHolder(View itemView){ super(itemView); title = (TextView)itemView.findViewById(android.R.id.text1); } }
3. Adapter
OneFragment.java
OneFragment.java
class MyAdapter extends RecyclerView.Adapter<MyViewHolder>{ final List<String> list;
// 항목구성 집합 데이터.. activity가 전달할것임
public MyAdapter(List<String> list){ this.list = list; } // 하나의 항목을 위해 최초에 수행될 부분
// 항목 layout 초기화.. Holder 준비
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { // 항목 layout 초기화
View view = LayoutInflater.from(parent.getContext())
.inflate(android.R.layout.simple_list_item_1, parent, false); return new MyViewHolder(view);
// holder 리턴 시키면 내부적으로 holder 객체를 메모리에 유지
} // 항목 하나를 구성하기 위해서 호출
// 항목구성 데이터, 이벤트 알고리즘이 구성되는 곳
// onCreateViewHolder에서 리턴시킨 holder가 매개변수로
@Override
public void onBindViewHolder(MyViewHolder holder, int position) { String text = list.get(position); holder.title.setText(text); } @Override public int getItemCount() { return list.size(); } }
4. Decoration (optional)
OneFragment.java
class MyDecoration extends RecyclerView.ItemDecoration{ // RecyclerView에 Adapter 작업에 의해 항목이 추가된 후에 호출
// 항목위에 추가 drawing 작업이 필요시 이용
@Override
public void onDrawOver(Canvas c, RecyclerView parent,
RecyclerView.State state) { super.onDrawOver(c, parent, state); int width = parent.getWidth(); int height = parent.getHeight(); Drawable dr = getActivity().getResources()
.getDrawable(R.drawable.kbo); int drWidth = dr.getIntrinsicWidth(); int drHeight = dr.getIntrinsicHeight(); int left = width/2 - drWidth/2; int top = height/2 - drHeight/2; c.drawBitmap( BitmapFactory.decodeResource(getActivity().getResources(), R.drawable.kbo), left, top, null); } // 항목 하나하나를 추가하기 위해서
@Override
public void getItemOffsets(Rect outRect, View view,
RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); // 항목의 index값
int index = parent.getChildAdapterPosition(view)+1; if(index % 3==0){ outRect.set(20,20,20,60); }else{ outRect.set(20,20,20,20); } view.setBackgroundColor(0xFFECE9E9); ViewCompat.setElevation(view, 20.0f);
// 하위버전 호완을 위해서
}
}
4. Fragment에 적용
OneFragment.java
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { recyclerView = (RecyclerView)inflater.inflate(R.layout.fragment_one, container, false); // 항목구성 데이터 준비 List<String> list = new ArrayList<>(); for(int i=0; i<20; i++){ list.add("item="+i); } recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); recyclerView.setAdapter(new MyAdapter(list)); recyclerView.addItemDecoration(new MyDecoration()); return recyclerView; }
댓글 없음:
댓글 쓰기