2016-05-16 82 views
1

MainFragment中有兩個片段(ProductDisplayFragment和PaymentFragment)並排通信。 MainFragment在NavigationActivity中。當從ProductDisplayFragment的GridView中選擇一個項目時,它將被添加到PaymentFragment ListView中。片段通信

NavigationActivity充當中間人將ProductDisplayFragment中的捆綁產品對象「發送」爲PaymentFragment。它工作得很好,直到我切換到另一個NavigationActivity片段,然後切換回MainFragment(包含ProductDisplayFragment和PaymentFragment)。

我有List<Product> productList來存儲ProductDisplayFragment添加到我的PaymentFragment中的產品列表。當添加的項目,productList.size() is > 0在被用於在PaymentFragment片段至片段通信的那些方法:getProduct()updateProductInfo()

然而,當我在比兩個方法之外的其它方法重新檢查productList.size()上面沒有涉及片段到片段的通信,productList.size() = 0永遠,雖然我點擊ProductDisplayFragment項目添加項目到PaymentFragment!

這是爲什麼?什麼是造成這種奇怪行爲的原因?

ProductDisplayFragment.java

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); 
     } 
    } 
} 

PaymentFragment.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()); 
      } 
     } 
    } 
} 

NavigationActivity.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); 
     } 
    } 
} 
+0

太多細節 – Haroon

回答

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(); 
+0

謝謝,我管理這個解決方案來解決這個問題:) – stackyyflow