Data-binding with dynamically added elements
我已经开始在我的新应用程序中实现Android数据绑定库。但是,我在数据动态添加元素方面遇到了一些困难。在我的
以前,我通过在循环内部扩展布局并为地图的每个项目添加
因为,
那么,有没有办法直接在数据绑定(在布局文件中)或在Java代码中尽可能少的代码执行此操作?
编辑:
对于所有人来说,谁看到它是一个简单的
由于您希望自己动态创建布局,我建议采用以下方法。目前这完全是理论上的,但我没有理由,为什么这不适合你。
考虑使用自定义属性设置
1 2 | <LinearLayout ... app:inflateData="@{dataMap}" /> |
然后,您必须创建一个
1 2 3 4 5 6 7 8 9 | @BindingAdapter({"inflateData"}) public static void inflateData(LinearLayout layout, Map<String, Double> data) { LayoutInflater inflater = LayoutInflater.from(layout.getContext()); for (Entry<String, Double> entry : data.entrySet()) { MyItem myItem = inflater.inflate(R.layout.my_item, layout, true); myItem.setKey(entry.getKey); myItem.setValue(entry.getValue); } } |
在这里,您可以扩展项目的布局并将其添加到父布局。您可以通过向布局和绑定适配器添加更多属性来进一步概括它。
这不是数据绑定的用途。这些是将数据绑定到静态定义的布局。创建或管理视图层次结构可能是可能的,但也比使用
如果您更喜欢从布局中设置数据,则可以为数据绑定库编写自定义设置器,并在此范围内创建适配器。
1 2 3 4 5 | @BindingAdapter({"adapter"}) public static void bindAdapter(RecyclerView view, Map<String, Double> data) { RecyclerView.Adapter adapter = ...; view.setAdapter(adapter); } |
要以动态方式添加/删除数据,您应该使用
对于Adapter和绑定方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | public class MyOwnBindingUtil { public static class Holder extends RecyclerView.ViewHolder { private ItemBinding mItemBinding; public Holder(ItemBinding itemView) { super(itemView.getRoot()); mItemBinding = itemView; } } public static class OwnAdapter extends RecyclerView.Adapter<Holder> { private Map<String, String> mMap; private List<String> keys; private List<Double> values; public OwnAdapter() { keys = new ArrayList<>(); values = new ArrayList<>(); } public void add(String key, Double value) { keys.add(key); values.add(value); } @Override public Holder onCreateViewHolder(ViewGroup parent, int viewType) { ItemBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.item, parent, false); return new MyOwnBindingUtil.Holder(binding); } @Override public void onBindViewHolder(Holder holder, int position) { holder.mItemBinding.setKey(keys.get(position)); holder.mItemBinding.setValue(String.valueOf(values.get(position))); } @Override public int getItemCount() { return keys.size(); } } @BindingAdapter("data:map") public static void bindMap(RecyclerView pRecyclerView, Map<String, Double> pStringStringMap) { pRecyclerView.setLayoutManager(new LinearLayoutManager(pRecyclerView.getContext())); OwnAdapter lAdapter = new OwnAdapter(); for (Map.Entry<String, Double> lStringStringEntry : pStringStringMap.entrySet()) { lAdapter.add(lStringStringEntry.getKey(), lStringStringEntry.getValue()); } pRecyclerView.setAdapter(lAdapter); } } |
如果您坚持使用Map而不是list来存储数据,则会出现一些问题,因为Map未编入索引但适配器会根据数据集的索引获取数据。
https://www.mkyong.com/java8/java-8-convert-map-to-list/
如何在Java中将Map转换为List?
如何在Java中将HashMap转换为List?
在xml中,您可以将地图设置为recyclerview,并且可以在xml中设置数据集。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:data="http://schemas.android.com/tools" > <data> <import type="java.lang.String"/> <import type="java.util.Map"/> <variable name="map" type="Map<String, String>"/> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" > <android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:layout_height="wrap_content" data:map="@{map}"/> </LinearLayout> </layout> |
在您的活动代码中
1 2 3 4 5 | Map<String, String> lStringStringMap = new HashMap<>(); lStringStringMap.put("A","A1"); lStringStringMap.put("B","B1"); lStringStringMap.put("C","C1"); mBinding.setMap(lStringStringMap); |