diff options
| author | 2017-12-26 14:12:37 -0600 | |
|---|---|---|
| committer | 2018-01-06 04:08:01 -0600 | |
| commit | b7196e328a25a28078906d8afa50ba9636ae7bcb (patch) | |
| tree | b7fa6a415b72fad6eacc27abaa500880850e03ff /app/src/main/java/com/wireguard/android/databinding/ObservableMapAdapter.java | |
| parent | app: Enable Java 8 features (diff) | |
| download | wireguard-android-b7196e328a25a28078906d8afa50ba9636ae7bcb.tar.xz wireguard-android-b7196e328a25a28078906d8afa50ba9636ae7bcb.zip | |
Rename package bindings -> databinding
Signed-off-by: Samuel Holland <samuel@sholland.org>
Diffstat (limited to 'app/src/main/java/com/wireguard/android/databinding/ObservableMapAdapter.java')
| -rw-r--r-- | app/src/main/java/com/wireguard/android/databinding/ObservableMapAdapter.java | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/app/src/main/java/com/wireguard/android/databinding/ObservableMapAdapter.java b/app/src/main/java/com/wireguard/android/databinding/ObservableMapAdapter.java new file mode 100644 index 00000000..70180728 --- /dev/null +++ b/app/src/main/java/com/wireguard/android/databinding/ObservableMapAdapter.java @@ -0,0 +1,120 @@ +package com.wireguard.android.databinding; + +import android.content.Context; +import android.databinding.DataBindingUtil; +import android.databinding.ObservableMap; +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; +import java.util.ArrayList; +import java.util.Collections; + +/** + * A generic ListAdapter backed by a TreeMap that adds observability. + */ + +public class ObservableMapAdapter<K extends Comparable<K>, V> extends BaseAdapter + implements ListAdapter { + private final OnMapChangedCallback<K, V> callback = new OnMapChangedCallback<>(this); + private ArrayList<K> keys; + private final int layoutId; + private final LayoutInflater layoutInflater; + private ObservableSortedMap<K, V> map; + + ObservableMapAdapter(final Context context, final int layoutId, + final ObservableSortedMap<K, V> map) { + this.layoutId = layoutId; + layoutInflater = LayoutInflater.from(context); + setMap(map); + } + + @Override + public int getCount() { + return map != null ? map.size() : 0; + } + + @Override + public V getItem(final int position) { + if (map == null || position < 0 || position >= map.size()) + return null; + return map.get(getKey(position)); + } + + @Override + public long getItemId(final int position) { + if (map == null || position < 0 || position >= map.size()) + return -1; + return getItem(position).hashCode(); + } + + private K getKey(final int position) { + return getKeys().get(position); + } + + private ArrayList<K> getKeys() { + if (keys == null) + keys = new ArrayList<>(map.keySet()); + return keys; + } + + public int getPosition(final K key) { + if (map == null || key == null) + return -1; + return Collections.binarySearch(getKeys(), key); + } + + @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.key, getKey(position)); + binding.setVariable(BR.item, getItem(position)); + binding.executePendingBindings(); + return binding.getRoot(); + } + + @Override + public boolean hasStableIds() { + return true; + } + + void setMap(final ObservableSortedMap<K, V> newMap) { + if (map != null) + map.removeOnMapChangedCallback(callback); + keys = null; + map = newMap; + if (map != null) { + map.addOnMapChangedCallback(callback); + } + notifyDataSetChanged(); + } + + private static class OnMapChangedCallback<K extends Comparable<K>, V> + extends ObservableMap.OnMapChangedCallback<ObservableSortedMap<K, V>, K, V> { + + private final WeakReference<ObservableMapAdapter<K, V>> weakAdapter; + + private OnMapChangedCallback(final ObservableMapAdapter<K, V> adapter) { + weakAdapter = new WeakReference<>(adapter); + } + + @Override + public void onMapChanged(final ObservableSortedMap<K, V> sender, final K key) { + final ObservableMapAdapter<K, V> adapter = weakAdapter.get(); + if (adapter != null) { + adapter.keys = null; + adapter.notifyDataSetChanged(); + } else { + sender.removeOnMapChangedCallback(this); + } + } + } +} |
