所以我有一个活动。 Activity包含一个带有选项卡的ViewPager,每个选项卡中都包含一个Fragment。 Fragments本身各有一个RecyclerView。我需要将RecyclerView适配器的更改传达给活动。
目前,我正在使用侦听器模式并使用每个组件之间的接口进行通信。我在RecyclerView的适配器和包含它的Fragment之间有一个接口。然后是一个从Fragment到ViewPager的FragmentStatePagerAdapter的接口,它创建了所有的Fragments。 ViewPager的适配器和托管ViewPager的Activity之间还有一个接口。我觉得所有组件的界面太多了,因为它们的结构如何。
目前我没有遇到这样的问题,但我认为由于所有嵌套组件,监听器模式就像反模式一样。我认为层次结构将使得将来很难进行代码更改,而不是创建独立的组件。
我是正确地做了还是有更好的方法呢?这是一个我应该使用事件总线或观察者模式的情况(如果是的话,你可以指出一些例子,其中有人克服了使用它的类似问题)?
注意:如果重要,我需要它来维护活动中的全局对象,比如我可以添加或删除项目的购物车,这些项目存在于RecyclerView的适配器中,我可以将其添加到购物车并且还增加或减少特定项目的计数。 ViewPager和Tabs有助于将这些项目分成不同的类别。
编辑1:有些代码试用了@ LucaNicoletti的方法 - 我跳过了一个级别,即ViewPager的FragmentStatePagerAdapter级别。我想这应该不重要,并删除一些其他代码以保持小。
MainActivity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener, FoodAdapter.OnFoodItemCountChangeListener {
@Override
public void onFoodItemDecreased(FoodItemModel foodItemModel, int count) {
Log.d("Test", "Dec");
}
@Override
public void onFoodItemIncreased(FoodItemModel foodItemModel, int count) {
Log.d("Test", "Inc");
}
// Other methods here
}
托管适配器的片段:
public class FoodCategoryListFragment extends Fragment implements FoodAdapter.OnFoodItemCountChangeListener {
// Other boring variables like recyclerview and layout managers
FoodAdapter foodAdapter;
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Other boring intializations for recyclerview and stuff
// I set the click listener here directly on the adapter instance
// I don't have this adapter instance in my activity
foodAdapter.setOnFoodItemClickListener(this);
rvFoodList.setAdapter(foodAdapter);
}
}
最低级别的适配器类:
public class FoodAdapter extends RecyclerView.Adapter<FoodAdapter.FoodViewHolder> {
private OnFoodItemCountChangeListener onFoodItemCountChangeListener;
private List<FoodItemModel> foodItems;
// The interface
public interface OnFoodItemCountChangeListener {
void onFoodItemIncreased(FoodItemModel foodItemModel, int count);
void onFoodItemDecreased(FoodItemModel foodItemModel, int count);
}
// This is called from the fragment since I don't have the adapter instance
// in my activty
public void setOnFoodItemClickListener(OnFoodItemCountChangeListener onFoodItemCountChangeListener) {
this.onFoodItemCountChangeListener = onFoodItemCountChangeListener;
}
// Other boring adapter stuff here
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.bMinus:
onFoodItemCountChangeListener.onFoodItemDecreased(foodItems.get(getAdapterPosition()),
Integer.parseInt(etCounter.getText().toString()));
}
break;
case R.id.bPlus:
onFoodItemCountChangeListener.onFoodItemIncreased(foodItems.get(getAdapterPosition()),
Integer.parseInt(etCounter.getText().toString()));
}
break;
}
}
}
答案 0 :(得分:1)
我的评论是:
您应该/可以做什么?拥有一个全局数据仓库,用于保存购物车和与其相关的监听器。像单例一样,像ShoppingCart.getInstance()。addListener(this);和ShoppingCart.getInstance()。addItem(new Item(id));
和
是。这就是我所建议的。不要忘记,这个Singleton永远不会持有Context或Activity,因为你不想泄漏内存,所以总是调用removeListener。在我看来,它会降低依赖性,因为所有视图控制器只与数据模型交互
我会添加一些代码作为正确的答案。
下面是一个非常粗略的,按心脏代码输入,但它应该给出一个想法。所有UI元素仅与数据相关联,而不是彼此相关。
类似的东西可以通过为纯数据对象提供开箱即用的observable
模式的库来实现。
public class ShoppingCart {
private ShoppingCart single;
private static void init(){
.. init single if not null
}
private List<Item> items = new ArrayList<>();
public int numberOfItems;
public long totalPrice;
private static void addItem(Item item){
init()
single.items.add(item);
single.numberOfItems++;
single.totalPrice+=item.price;
dispatchChange();
}
private static void removeItem(Item item){
init();
single.numberOfItems--;
single.totalPrice-=item.price;
dispatchChange();
single.items.remove(item);
}
private void dispatchChange(){
// TODO: write real loop here
for(single.listeners) listener.onCartChanged(single.cart);
}
public interface Listener {
void onCartChanged(ShoppingCart cart);
}
private List<Listener> listeners = new ArrayList<>();
// TODO: addListener and removeListener code
public static class Item {
String id;
String name;
long price;
}
}
答案 1 :(得分:0)
要在组件(Activity
,Fragment
)之间进行通信,您必须使用事件总线。
在android中,您可以选择:
A blog来解释这一点。