하나의 RecylerView에서 다양한 viewholder화면을 보여줄려면, 이전에는 하나의  adapter안에서 type들을 지정하고, 해당 position에 대해서 type에 맞는 viewholder들을 가져와서 보여줬습니다.

하지만, 여러 type들이 존재하거나 할 경우는 adapter안에는 다양한 type과 viewholder내용들이 존재하게 됩니다.

header,. 그리고 item들이 순차적으로 있다고 해도, adapter에 대한 position의 계산도 틀려집니다.

그래서 이번에 concatadapter를 볼려고 합니다.

developer.android.com/reference/androidx/recyclerview/widget/ConcatAdapter

 

ConcatAdapter  |  Android 개발자  |  Android Developers

ConcatAdapter public final class ConcatAdapter extends Adapter An RecyclerView.Adapter implementation that presents the contents of multiple adapters in sequence. MyAdapter adapter1 = ...; AnotherAdapter adapter2 = ...; ConcatAdapter concatenated = new Con

developer.android.com

다양한 adapter들을 결합에서 하나의 recyclerview에서 내용을 보여줄 수 있습니다.

header, item, footer 가 존재한다면,

headeradapter, itemadapter, footeradapter를 만들고, 그걸 concatadapter에 결합해서 사용하면 됩니다.

그리고 notify할 경우도, 각 adapter에서 따로 진행할 수도 있습니다.

간단하게 만든 sample은.

github.com/drcarter/ConcatAdapterTest

 

drcarter/ConcatAdapterTest

Contribute to drcarter/ConcatAdapterTest development by creating an account on GitHub.

github.com

으로 간단히 만들어 봤습니다.

 

  Android 의 ListView에서 하나의 Item이 변경이 되면 해당 Item에 대한 dataset을 변경 후 화면에 보이는 내용을 변경해 주어야만 합니다. 그리고 나서 보통 adapter에 있는 notifyDataSetChanged()라는 메소드를 호출하여 화면에 보이는 내용을 변경합니다. 

  하지만 이 방법에는 작은 단점이 있습니다. adapter에 있는 notifyDataSetChanged()메소드를 호출하게 되면 화면에 보이는 모든 ListView의 Item에 대하여 화며을 변경하게 됩니다. 즉 화면에 ListView의 Item이 5개가 있다면 5개 전부 다 다시 그려지게 됩니다. adapter에 있는 data중 하나만 변경되었지만 adapter에서는 어떤 item의 dataset이 변경되었는지 알 수 없으니까요.

  그럼 ListView의 single item에 대해서 변경된 내용을 적용하는 방법이 없을까요? 간단한 방법으로 해결 할 수 있습니다. 변경하고자 하는 View를 ListView의 메소드인 getChildAt(int index) 를 통해서 변경하고자 하는 View를 가지고 올 수 있습니다. 

public View getChildAt (int index)

Added in API level 1

Returns the view at the specified position in the group.

Parameters
indexthe position at which to get the view from
Returns
  • the view at the specified position or null if the position does not exist within the group

변경하고자 하는 index를 알지만 현재 화면에 보이는 ListView의 item에 대해서는 index를 어떻게 확인할까요?  AdapterView의 메소드 중 현재 화면에 보여지는 ListView의 첫번째 Item이 전체 몇번째 index인지를 알려주는 메소드가 있습니다. getFirstVisiblePosition()을 통해서 알 수 있습니다.

public int getFirstVisiblePosition ()

Added in API level 1

Returns the position within the adapter's data set for the first item displayed on screen.

Returns
  • The position within the adapter's data set


그럼 이 두 메소드를 통해서 간단하게 TextView의 내용을 변경해 보도록 하겠습니다.


private void updateSingleItemView(int position)
{
    int firstVisiblePosition = mListView.getFirstVisiblePosition();
    View view = mListView.getChildAt(position - firstVisiblePosition);
    TextView textTitle = (TextView)view.findViewById(R.id.text_title);
    textTitle.setText("Title Change");
}

이와 같은 방법으로 변경하고자 하는 하나의 아이템에 대해서 내용을 변경 할 수 있습니다.

하지만 이 방법은 지금 보이는 화면에View에 대한 변경된 내용이 지속도지 않습니다. 지속되게 할려면 이전에 먼저 꼭 dataset을 먼저 변경해 주시기 바랍니다. 그리고 난 뒤에 single item에 대해서 내용을 변경해야 합니다. 그 후 ListView를 scroll한다든지에 따라서 Adapter의 View getView (int position, View convertView, ViewGroup parent) 에 의해서 화면이 다시 그려질 때 dataset이 변경되어 있지 않다면 이전의 내용으로 보이게 될 것입니다.

+ Recent posts