Fragment to Fragment communication

时间:2016-05-16 06:50:40

标签: java android android-fragments

MainFragment中有两个片段(ProductDisplayFragment和PaymentFragment)并排相互通信。 MainFragment位于NavigationActivity中。从ProductDisplayFragment的GridView中选择一个项目时,它将被添加到PaymentFragment ListView中。

NavigationActivity充当中间人,将捆绑产品对象从ProductDisplayFragment“发送”到PaymentFragment。它完全正常,直到我切换到另一个NavigationActivity片段,然后切换回MainFragment(包含ProductDisplayFragment和PaymentFragment)。

我有List<Product> productList来存储从我的PaymentFragment中的ProductDisplayFragment添加的产品列表。添加项目时,productList.size() is > 0在PaymentFragment中用于片段到片段通信的那些方法中getProduct()updateProductInfo()productList.size() = 0

但是,当我重新检查除上述两种方法之外的其他方法中的productList.size(),这些方法不参与片段到片段的通信,public class ProductDisplayFragment extends Fragment { private GridView gridView; private ProductGridAdapter productAdapter; private OnProductSelectedListener sendProduct; public ProductDisplayFragment() { // Required empty public constructor } public interface OnProductSelectedListener { void onProductSelected(Product product); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View rootView = inflater.inflate(R.layout.fragment_product_display, container, false); gridView = (GridView) rootView.findViewById(R.id.gridview); productAdapter = new ProductGridAdapter(getActivity(), R.layout.fragment_product_display, getProductList()); gridView.setAdapter(productAdapter); return rootView; } @Override public void onAttach(Activity activity) { super.onAttach(activity); try { sendProduct = (OnProductSelectedListener) activity; } catch (ClassCastException e) { throw new ClassCastException(MESSAGE_ERROR_IMPLEMENTATION); } } } 永远虽然我点击了ProductDisplayFragment中的项目来添加项目进入Pay​​mentFragment!

为什么会这样?是什么导致了这种奇怪的行为?

ProductDisplayFragment.java

public class PaymentFragment extends Fragment {

    public PaymentFragment() {

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View rootView = inflater.inflate(R.layout.fragment_payment, container, false);

        listView = (ListView) rootView.findViewById(R.id.productList);
        paymentAdapter = new PaymentListAdapter(getActivity(), R.layout.fragment_payment, productList);
        listView.setAdapter(paymentAdapter);

        voidButton = (LinearLayout) rootView.findViewById(R.id.button_void);
        saveButton = (LinearLayout) rootView.findViewById(R.id.button_save);
        noteButton = (LinearLayout) rootView.findViewById(R.id.button_note);
        discountButton = (LinearLayout) rootView.findViewById(R.id.button_discount);
        payButton = (LinearLayout) rootView.findViewById(R.id.button_pay);
        amountSubtotal = (TextView) rootView.findViewById(R.id.amount_subtotal);
        amountDiscount = (TextView) rootView.findViewById(R.id.amount_discount);
        amountTotal = (TextView) rootView.findViewById(R.id.amount_total);

        setDefaultAmount();
        getFirstProduct();
        buttonsOnClick();

        return rootView;
    }

    /*
     * This method retrieves product from fragment and refresh the listview every time a new product is added into listview
     */
    public void getProduct(Product product) {
        updateProductInfo(product);
        updateListView();
    }

    private void updateProductInfo(Product product) {
        // Only add product if it does not exist in hashset, else increment quantity number
        if(productHash.contains(product.getBarcode())) {
            int productIndex = productList.indexOf(product);
            product.setQuantity(product.getQuantity() + 1);
            if(productIndex != -1) {
                productList.set(productIndex, product);
            }
        } else {
            product.setQuantity(1);
            productList.add(0, product);
            productHash.add(product.getBarcode());
        }
    }

    private void getFirstProduct() {
        Bundle arguments = getArguments();
        if (arguments != null) {
            Product product = (Product) arguments.getSerializable(KEY_PRODUCT);
            getProduct(product);
            if(product != null) {
                Log.d(TAG, "Received subsequent product" + product.getName());
            }
        }
    }
}

PaymentFragment.java

public class NavigationActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener,
        ProductDisplayFragment.OnProductSelectedListener {

@Override
    public void onProductSelected(Product product) {
        PaymentFragment paymentFragment = (PaymentFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_payment_list);
        if(paymentFragment != null) {
            paymentFragment.getProduct(product);
        } else {
            paymentFragment = new PaymentFragment();
            Bundle args = new Bundle();
            args.putSerializable(KEY_PRODUCT, product);
            paymentFragment.setArguments(args);

            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            transaction.replace(R.id.fragment_payment_list, paymentFragment);
            transaction.addToBackStack(null);
            transaction.commit();
            //productQueue.add(product);
            //paymentFragment.getProduct(product);
        }
    }
}

NavigationActivity.java

@media (min-width: 615px) {
  .class
  {
  .myclass:value; 
  }
}

1 个答案:

答案 0 :(得分:2)

根据我的经验,传递大量自定义对象,尤其是片段/活动之间的自定义对象的ArrayList通常会导致奇怪的错误。这就是为什么我建议您存储您的List<Product> productList以及用于在单独的单件类中管理产品的所有逻辑,而不是将其移动到您的片段中。像这样:

public class ProductsManager{
   private static ProductsManager productManager;
   private List<Product> productList;

   private ProductsManager(){
     this.productList = new ArrayList<>();
     //Or init your productList here
   }

   public static getInstance(){
     if(productManager == null){
       productManager = new ProductsManager();
     }
   }

   public List<Product> getProductsList(){
     return productList;
   }

   public Product getProduct(){
     //Some logic
   }

   public Product updateProductInfo(Product product){
     //Some logic
   }

   //Any other method to work with your products
}

这样,您管理的所有产品和所有产品逻辑都将放在一个位置,您不需要在片段或活动中传递重物。您也将始终100%确定所有片段使用相同的数据。不要忘记在ProductsManager中创建方法,当你不再需要它时将删除该对象。

你可以像这样使用这个单身:

ProductsManager.getInstance().getProductsList();