drcarter의 DevLog

  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이 변경되어 있지 않다면 이전의 내용으로 보이게 될 것입니다.