diff options
Diffstat (limited to 'app/src/main/java/com/wireguard/android/bindings/ObservableListAdapter.java')
-rw-r--r-- | app/src/main/java/com/wireguard/android/bindings/ObservableListAdapter.java | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/app/src/main/java/com/wireguard/android/bindings/ObservableListAdapter.java b/app/src/main/java/com/wireguard/android/bindings/ObservableListAdapter.java new file mode 100644 index 00000000..5b54ecaf --- /dev/null +++ b/app/src/main/java/com/wireguard/android/bindings/ObservableListAdapter.java @@ -0,0 +1,110 @@ +package com.wireguard.android.bindings; + +import android.content.Context; +import android.databinding.DataBindingUtil; +import android.databinding.ObservableList; +import android.databinding.ViewDataBinding; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ListAdapter; + +import com.wireguard.android.BR; + +import java.lang.ref.WeakReference; + +/** + * A generic ListAdapter backed by an ObservableList. + */ + +class ObservableListAdapter<T> extends BaseAdapter implements ListAdapter { + private final OnListChangedCallback<T> callback = new OnListChangedCallback<>(this); + private final int layoutId; + private final LayoutInflater layoutInflater; + private ObservableList<T> list; + + ObservableListAdapter(final Context context, final int layoutId, final ObservableList<T> list) { + this.layoutId = layoutId; + layoutInflater = LayoutInflater.from(context); + setList(list); + } + + @Override + public int getCount() { + return list != null ? list.size() : 0; + } + + @Override + public T getItem(final int position) { + return list != null ? list.get(position) : null; + } + + @Override + public long getItemId(final int position) { + return position; + } + + @Override + public View getView(final int position, final View convertView, final ViewGroup parent) { + ViewDataBinding binding = DataBindingUtil.getBinding(convertView); + if (binding == null) + binding = DataBindingUtil.inflate(layoutInflater, layoutId, parent, false); + binding.setVariable(BR.item, getItem(position)); + binding.executePendingBindings(); + return binding.getRoot(); + } + + public void setList(final ObservableList<T> newList) { + if (list != null) + list.removeOnListChangedCallback(callback); + list = newList; + if (list != null) { + list.addOnListChangedCallback(callback); + } + notifyDataSetChanged(); + } + + private static class OnListChangedCallback<U> + extends ObservableList.OnListChangedCallback<ObservableList<U>> { + + private final WeakReference<ObservableListAdapter<U>> weakAdapter; + + private OnListChangedCallback(final ObservableListAdapter<U> adapter) { + weakAdapter = new WeakReference<>(adapter); + } + + @Override + public void onChanged(final ObservableList<U> sender) { + final ObservableListAdapter<U> adapter = weakAdapter.get(); + if (adapter != null) + adapter.notifyDataSetChanged(); + else + sender.removeOnListChangedCallback(this); + } + + @Override + public void onItemRangeChanged(final ObservableList<U> sender, final int positionStart, + final int itemCount) { + onChanged(sender); + } + + @Override + public void onItemRangeInserted(final ObservableList<U> sender, final int positionStart, + final int itemCount) { + onChanged(sender); + } + + @Override + public void onItemRangeMoved(final ObservableList<U> sender, final int fromPosition, + final int toPosition, final int itemCount) { + onChanged(sender); + } + + @Override + public void onItemRangeRemoved(final ObservableList<U> sender, final int positionStart, + final int itemCount) { + onChanged(sender); + } + } +} |