使用动态添加的元素进行数据绑定
我已经开始在我的新应用程序中实现Android数据绑定库。 但是,我在数据动态添加元素方面遇到了一些困难。 在我的POJO
它包含的映射。 这里,
String
是用户的id, Double
是金额。 我有一个用于显示单个条目的布局文件。 因此,如果map包含2个元素,它将如下所示:
以前,我通过在循环内部扩展布局并为地图的每个项目添加到LinearLayout
来完成此操作。 但是,现在我想用数据绑定做到这一点。
因为, Map
的元素数量可以是1到20之间的任何值,默认情况下我无法在布局文件中添加。 我必须根据地图中的条目进行充气。 我已成功实现了与POJO
数据绑定而没有Map
。 但是,无法理解如何通过数据绑定轻松完成此操作。
那么,有没有办法直接在数据绑定(在布局文件中)或在Java代码中尽可能少的代码执行此操作?
编辑:对于所有人,谁看到它是一个简单的RecyclerView
,它不是。 我同意当你有一个带有一些元素的列表并且滚动时, RecyclerView
是非常好的选择,这些视图将是性能优势。 这里我在这个列表的上方和下方有不同类型的多个元素。 我也使用了RecyclerView
和数据绑定,我知道它是如何工作的,但事实并非如此。 我只想使用数据绑定在布局(LinearLayout)内膨胀多行。
由于您希望自己动态创建布局,因此我建议采用以下方法。 目前它完全是理论上的,但我没有看到理由,为什么这不适合你。
考虑使用自定义属性设置Map
以进行绑定。
然后,您必须创建一个@BindingAdapter
来处理适配器将为您执行的操作。
@BindingAdapter({"inflateData"}) public static void inflateData(LinearLayout layout, Map data) { LayoutInflater inflater = LayoutInflater.from(layout.getContext()); for (Entry entry : data.entrySet()) { MyItem myItem = inflater.inflate(R.layout.my_item, layout, true); myItem.setKey(entry.getKey); myItem.setValue(entry.getValue); } }
在这里,您可以扩展项目的布局并将其添加到父布局。 您可以通过向布局和绑定适配器添加更多属性来进一步概括它。
这不是数据绑定的用途。 这些是将数据绑定到静态定义的布局。 创建或管理视图层次结构可能是可能的,但也比使用RecyclerView
及其适配器复杂得多。
如果您更喜欢从布局中设置数据,则可以为数据绑定库编写自定义设置器 ,并在此范围内创建适配器。
@BindingAdapter({"adapter"}) public static void bindAdapter(RecyclerView view, Map data) { RecyclerView.Adapter adapter = ...; view.setAdapter(adapter); }
要以动态方式添加/删除数据,您应该使用Adapter
而不是使用您的方式添加它。 正如谷歌建议的那样, RecycelerView
在UI和内存控制RecycelerView
有更好的表现。 我已经制作了一些可能适合你的简单代码。
适用于Adapter和绑定方法 。
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 { private Map mMap; private List keys; private List 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 pStringStringMap) { pRecyclerView.setLayoutManager(new LinearLayoutManager(pRecyclerView.getContext())); OwnAdapter lAdapter = new OwnAdapter(); for (Map.Entry lStringStringEntry : pStringStringMap.entrySet()) { lAdapter.add(lStringStringEntry.getKey(), lStringStringEntry.getValue()); } pRecyclerView.setAdapter(lAdapter); } }
如果您坚持使用Map而不是列表来存在一些问题,因为Map未编入索引,但适配器根据数据集的索引获取数据 。
https://www.mkyong.com/java8/java-8-convert-map-to-list/
如何在Java中将Map转换为List?
如何在Java中将HashMap转换为List?
在xml中,您可以将地图设置为recyclerview,并且可以在xml中设置数据集。
在您的活动代码中
Map lStringStringMap = new HashMap<>(); lStringStringMap.put("A", "A1"); lStringStringMap.put("B", "B1"); lStringStringMap.put("C", "C1"); mBinding.setMap(lStringStringMap);