[Android] DataBinding - 3

HEETAE HEO·2022년 5월 18일
0

DataBinding

목록 보기
3/3
post-thumbnail

Android DataBinding : RecyclerView

RecyclerView에는 데이터를 UI에 바인딩하는 고유한 방법이 있습니다. RecyclerView에는 매우 중요한 메서드가 있는 Adapter가 있습니다.

RecyclerView

RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int ViewType)


void onBindingViewHolder(RecyclerView.ViewHolder holder,int position)

onCreateViewHolder에서 뷰가 생성되고 ViewHolder에 뷰에 대한 참조가 포함되어 데이터를 빠르게생성할 수 있습니다. 그런 다음 onBindView()에서 특정 데이터가 보기에 할당됩니다.

RecyclerView의 DataBinding

Android DataBinding은 ViewHolder 패턴처럼 처리될 수 있습니다. onCreateViewHolder()에서 생성된 Binding 클래스를 반환하지만 RecyclerView.ViewHolder는 확장하지 않습니다. 따라서 Binding 클래스는 ViewHolder에 포함되어야합니다.

MyViewHolder.kt

public class MyViewHolder extends RecyclerView.ViewHolder {
    private final ItemBinding binding;

    public MyViewHolder(ItemBinding binding) {
        super(binding.getRoot());
        this.binding = binding;
    }

    public void bind(Item item) {
        binding.setItem(item);
        binding.executePendingBindings();
    }
}

Adapter에서 DataBinding을 사용하여 생성하고 바인딩할 수 있습니다.
binding.executePendingBindings()는 바인딩이 다음 프레임까지 지연되지않고 즉시 실행할 수 있게 도와줍니다. RecyclerView는 onBindViewHolder 직후 뷰를 측정하는데 바인딩이 다음 프레임까지 대기 중이기 때문에 뷰에 잘못된 데이터가 있으면 부적절하게 측정되기 때문에 executePendingBindings()가 중요합니다.

Adapter.kt

public MyViewHolder onCreateViewHolder(ViewGroup parent,
                                       int viewType) {
    LayoutInflater layoutInflater =
        LayoutInflater.from(parent.getContext());
    ItemBinding itemBinding = 
        ItemBinding.inflate(layoutInflater, parent, false);
    return new MyViewHolder(itemBinding);
}

public void onBindViewHolder(MyViewHolder holder, int position) {
    Item item = getItemForPosition(position);
    holder.bind(item);
}

ViewHolder 재사용

일반적으로 RecyclerView를 사용하고 개수가 늘어날 수록 ViewHolder의 개수가 같이 증가하였습니다. DataBinding을 통해 이러한 문제를 해결할 수 있습니다.

바로 View Model 객체를 obj로 명명하여 단일 ViewHolder로 모든 RecyclerView에 적용하는 것입니다.

MyViewHolder.kt

public class MyViewHolder extends RecyclerView.ViewHolder {
    private final ViewDataBinding binding;

    public MyViewHolder(ViewDataBinding binding) {
        super(binding.getRoot());
        this.binding = binding;
    }

    public void bind(Object obj) {
        binding.setVariable(BR.obj, obj);
        binding.executePendingBindings();
    }
}

MyViewHolder에서는 특정 ItemBinding 대신 생성된 모든 바인딩의 기본 클래스인 ViewDataBinding읗 사용하고 있습니다. 이렇게 하면 ViewHolder에서 모든 레이아웃을 지원할 수 있습니다. 또한 setVariable을 통해 뷰 모델 개체 휴형을 할당할 수 있습니다. 중요한 부분은 setVariable에서 BR.obj를 키로 사용하기 때문에 변수 이름을 obj로 지정해야한다는 것입니다. 즉 다음과 같이 레이아웃 파일에 변수 태그가 있어야합니다.

그런 다음 RecyclerView Adapter에 사용할 수 있는 기본 클래스를 만들 수 있습니다.

public abstract class MyBaseAdapter
                extends RecyclerView.Adapter<MyViewHolder> {
    public MyViewHolder onCreateViewHolder(ViewGroup parent,
                                           int viewType) {
        LayoutInflater layoutInflater =
                LayoutInflater.from(parent.getContext());
        ViewDataBinding binding = DataBindingUtil.inflate(
                layoutInflater, viewType, parent, false);
        return new MyViewHolder(binding);
    }

    public void onBindViewHolder(MyViewHolder holder,
                                 int position) {
        Object obj = getObjForPosition(position);
        holder.bind(obj);
    }
    @Override
    public int getItemViewType(int position) {
        return getLayoutIdForPosition(position);
    }

    protected abstract Object getObjForPosition(int position);

    protected abstract int getLayoutIdForPosition(int position);

Adapter에서 레이아웃 ID를 보기 유형으로 사용하므로 올바른 바인디응ㄹ 더 쉽게 확장할 수 있습니다. 이렇게 하면 Adapter가 레이아웃을 얼마든지 처리할 수 있지만 가장 일반적인 사용법은 단일 레이아우승로 RecyclerView를 사용하는 것이므로 이에 대한 기본 클래스를 생성가능합니다.

public abstract class SingleLayoutAdapter extends MyBaseAdapter {
    private final int layoutId;
    
    public SingleLayoutAdapter(int layoutId) {
        this.layoutId = layoutId;
    }
    
    @Override
    protected int getLayoutIdForPosition(int position) {
        return layoutId;
    }
}

코드

자료를 찾고 공부한 코드가 JAVA로 되어있어 추후에 조금 더 공부한 후 오늘 올라와 있는 코드를 Kotlin으로 변환하여 글을 써보겠습니다.

profile
Android 개발 잘하고 싶어요!!!

0개의 댓글