2016-05-16 28 views
1

MainFragmentには、2つのフラグメント(ProductDisplayFragmentとPaymentFragment)が並んで通信します。 MainFragmentはNavigationActivityにあります。 ProductDisplayFragmentのGridViewから項目が選択されると、それはPaymentFragment ListViewに追加されます。フラグメント通信へのフラグメント

NavigationActivityは、ProductDisplayFragmentからPaymentFragmentにバンドル商品オブジェクトを「送信」する仲介者として機能します。これはNavigationActivityの別のフラグメントに切り替えるまで完全に正常に動作し、MainFragment(ProductDisplayFragmentとPaymentFragmentの両方を含む)に戻ります。

私はList<Product> productListで、私のPaymentFragmentにProductDisplayFragmentから追加された製品のリストを保存しています。アイテムが追加され、PaymentFragmentにおけるフラグメント対フラグメント通信中に使用されるこれらの方法でproductList.size() is > 0getProduct()updateProductInfo()

ただし、Iは再チェックproductList.size()は、2つの方法以外の方法で私はProductDisplayFragmentで項目をクリックして、PaymentFragmentに項目を追加しましたが、フラグメント間の通信には含まれていません(productList.size() = 0)。

これはなぜですか?この奇妙な行動を引き起こしたものは何ですか?

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

関連する問題