안드로이드

[android] 모델 클래스에서 inner 클래스 데이터 바인딩 하기

wangkisa 2016. 12. 12. 17:52

일반적인 데이터 바인딩을 한다고 하면 


https://developer.android.com/topic/libraries/data-binding/index.html?hl=ko


여기에서 있는 과정을 따라가게 되면 정상적으로 data binding 을 할 수 있다.


build.gradle 파일에서


dataBinding {

        enabled = true

    }


추가


적용할 layout .xml 파일에서


<layout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    >


    <data>

        <import type="com.~~~.data.BookingListData" />

        <variable

            name="bookinglist"

            type="BookingListData"/>

    </data>


</layout>



사용될 부분

<TextView

    android:id="@+id/text_date"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:text="@{bookinglist.booking_datetime}"/>


이렇게 선언 후 

(예시 어댑터)

public class AppAdapter<T extends ViewModel> extends RecyclerView.Adapter<AppAdapter.ViewHolder> {


    private List<? extends T> list;


    public AppAdapter(List<? extends T> list) {

        this.list = list;

    }


    public static class ViewHolder<V extends ViewDataBinding> extends RecyclerView.ViewHolder {

        private V v;


        public ViewHolder(V v) {

            super(v.getRoot());

            this.v = v;

        }


        public V getBinding() {

            return v;

        }

    }


    @Override

    public int getItemViewType(int position) {

        return list.get(position).layoutId();

    }


    @Override

    public AppAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        ViewDataBinding bind = DataBindingUtil.bind(LayoutInflater.from(parent.getContext()).inflate(레이아웃 파일id, parent, false));

        return new ViewHolder<>(bind);

    }


    @Override

    public void onBindViewHolder(AppAdapter.ViewHolder holder, int position) {

        final T model = list.get(position);

        holder.getBinding().setVariable(BR.model, model);

        holder.getBinding().executePendingBindings();

    }


    @Override

    public int getItemCount() {

        return list.size();

    }


}


사용될 어댑터를 이처럼 만들어 줍니다.


이렇게 하면 클래스 안에 단일 변수들만 있으면 문제가 없지만,


public class BookingListData extends BaseObservable {


    private String type;

    private List<Rest_info> rest_info;

    ...

}


이런 형태처럼 안에 또 클래스가 있는 형태를 사용하려면 

 android:text="@{bookinglist.booking_datetime}" 형태를 사용할때 어떻게 접근해야될지 몰라 한참 헤맸었습니다.


서두가 좀 길긴 하지만

이에대한 해결책은!!


레이아웃 파일에서 <data> 부분에 

<data>

        <import type="com.~.data.BookingListData" />

        <import type="com.~.data.BookingListData.Rest_info"/>

        <variable

            name="bookinglist"

            type="BookingListData"/>

        <variable

            name="restinfo"

            type="Rest_info"/>

    </data>


형태처럼 불러올 이너클래스도 같이 선언을 해 준뒤

대상을 적용할

onBindViewHolder 에서


@Override

public void onBindViewHolder(ViewHolder holder, int position) {

    final BookingListData model = mBookingListArrays.get(position);

    holder.getBinding().setVariable(BR.bookinglist, model);


        final BookingListData.Rest_info restInfoModel = mBookingListArrays.get(position).getRest_info().get(0);

        if(restInfoModel != null) {

            holder.getBinding().setVariable(BR.restinfo, restInfoModel);

        }


    holder.getBinding().executePendingBindings();

}


bold 로 표시된 부분을 추가로 할당해서 적용하니 정상적으로 데이터가 나오는 것을 확인하였습니다. ^^