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中的项目来添加项目进入PaymentFragment!
为什么会这样?是什么导致了这种奇怪的行为?
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;
}
}
答案 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();