RecyclerView
안드로이드에서 보통 리스트를 구현할 때는 ListView를 이용하지만 웹에서의 대용량 데이터를 처리할 때에 ListView를 사용하게 되면 버벅이는 현상을 보게 될 것이다. RecyclerView는 List구성에 성능을 개선한 최적화된 안드로이드 support.widget의 View이다.
참고 page : https://developer.android.com/training/material/lists-cards.html
The RecyclerView
class simplifies the display and handling of large data sets by providing:
You also have the flexibility to define custom layout managers and animations for RecyclerView
widgets.
Figure 1. The RecyclerView
widget.
즉 LayoutManager를 이용하여 item을 위치시키고, item 삭제나 생성과 같은 operation에 animation 효과를 준다.
구현 방법
List에 붙일 커스텀 아답터를 만들기 위해서는 다음과 같은 절차가 필요하다.
1. RecyclerView.Adapter를 상속하여 커스텀 아답터를 정의 해 주어야 한다.
2. 리스트의 커스텀 레이아웃을 ViewHolder에 구성하여 onCreateViewHolder에서 view를 생성한다.
3. 커스텀 레이아웃에서 구성한 각 view를 ViewHolder를 이용하여 리스트를 구성한다.
4. getItemCount에 리스트가 몇개가 구성되는지 정의해 주어야 한다. (필자는 이 부분을 생략하여 리스트가 구성이 안되어 몇시간 삽질한 경험이 있음...)
5. 각 리스트 item클릭시 동작은 onBindViewHolder에서 객체에 리스너를 등록하여 정의할 수 있다.
예제 화면 : 아래와 같은 화면을 RecyclerView를 이용해 구현 해 보자.
ex 1) MyAdapter.java
public class MyAdapter extends RecyclerView.Adapter
{ private ArrayList mDataset; public MyAdapter(ArrayList searchDataSet, Activity activity) { mDataset = searchDataSet; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.search_view, parent, false); ViewHolder vh = new ViewHolder(v); return vh; } @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.mNumberView.setImageResource(mDataset.get(position).number_img); holder.mTextView.setText(mDataset.get(position).text); holder.mPrivateImage.setImageResource(mDataset.get(position).private_img); holder.mTextView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // click 시 필요한 동작 정의 } }); } @Override public int getItemCount() { return mDataset.size(); } public static class ViewHolder extends RecyclerView.ViewHolder { public ImageView mNumberView; public TextView mTextView; public ImageView mPrivateImage; public ViewHolder(View view) { super(view); mNumberView = (ImageView) view.findViewById(R.id.number_image); mTextView = (TextView) view.findViewById(R.id.search_text); mPrivateImage = (ImageView) view.findViewById(R.id.private_icon); } } }
ex 2) 데이터 MyData.java
public class MyData { public int number_img; public String text; public int private_img; public MyData(int number_img, String text, int private_img) { this.number_img = number_img; this.text = text; this.private_img = private_img; } }
ex 3) Fragment.java에서 사용하기
public class MyFragment extends Fragment { private RecyclerView mRecyclerView; private MyAdapter mAdapter; private RecyclerView.LayoutManager mLayoutManager; private ArrayListmMyData; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.crew_search_fragment, container, false); mRecyclerView = (RecyclerView) view.findViewById(R.id.search_recycler_view); mRecyclerView.setHasFixedSize(true); mLayoutManager = new LinearLayoutManager(getActivity()); mRecyclerView.setLayoutManager(mLayoutManager); mRecyclerView.scrollToPosition(0); mAdapter = new MyAdapter(mMyData); mRecyclerView.setAdapter(mAdapter); mRecyclerView.setItemAnimator(new DefaultItemAnimator()); return view; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); } @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); initDataset(); } private void initDataset() { //for Test mSearchData = new ArrayList<>(); mSearchData.add(new MyData(R.drawable.number1, "JOY MINI (48/50)", R.drawable.private_icon)); mSearchData.add(new MyData(R.drawable.number2, "RALLYIST (5/50)", R.drawable.public_icon)); mSearchData.add(new MyData(R.drawable.number3, "TEST (10/30)", R.drawable.private_icon)); } }