我正在开发一个由多个标签组成的小应用程序,其中每个标签只包含一种产品(例如披萨产品),并且可以将此标签中的特定产品(Margherita)添加到订单中。每个选项卡都包含布局,其中左侧有代表每个产品的按钮,当前添加到订单的项目列表(所有产品)+右侧的计算价格。这就是我目前在Tab
中添加TabHost
的方式:
Bundle extras = new Bundle();
extras.putString("productType", "pizza");
tabHost.addTab(tabHost.newTabSpec("pizza").setIndicator("Pizza"), OrderFragment.class, extras);
问题是,当我尝试在OrderFragment的构造函数中获取参数时,它会抛出异常:
E/AndroidRuntime(533): FATAL EXCEPTION: main
E/AndroidRuntime(533): java.lang.NullPointerException
我需要将一些数据传递给OrderFragment的原因是OrderFragment将成为任何类型产品(产品,面食等)的抽象类,因此它可以找出哪种类型的产品它是并加载适当的数据。我认为方法addTab(TabSpec, Class<T>, Bundle)
创建了一个指定类的实例并在其中添加了额外内容,但似乎这些附加内容没有用它打包。 (猜猜是出于另一个目的)。我将不胜感激如何解决这个问题。如果你以完全不同的方式做到这一点,我也很感激指出它。
OrderFragment:
public class OrderFragment extends Fragment implements IEditOrder{
private static final String TAG = "OrderFragment";
private Controller controller;
private ListView lst_order;
private TextView txt_order_total;
private Button btn_finishOrder;
private Button btn_cancelOrder;
private String productType;
private OrderAdapter orderAdapter;
private static final int DIALOG_EDIT_ORDER = 1;
public OrderFragment() {
Bundle extras = getArguments();
Log.d(TAG, "Extras: " + extras.toString());
this.productType = extras.getString("productType");
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//setRetainInstance(true);
controller = Controller.getInstance();
controller.loadProducts(getActivity().getApplicationContext());
//FillDatabase.loadDataToDatabase(getActivity());
}
@Override
public void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_pizza, container, false);
txt_order_total = (TextView)view.findViewById(R.id.txt_order_total);
btn_finishOrder = (Button)view.findViewById(R.id.btn_finishOrder);
btn_cancelOrder = (Button)view.findViewById(R.id.btn_cancelOrder);
btn_finishOrder.setOnClickListener(finishOrder);
btn_cancelOrder.setOnClickListener(cancelOrder);
final RelativeLayout layout = (RelativeLayout) view.findViewById(R.id.rl_order_pizza);
orderAdapter = new OrderAdapter(getActivity(), controller.getOrderMap());
lst_order = (ListView) view.findViewById(R.id.lst_order);
lst_order.addHeaderView(inflater.inflate(R.layout.order_list_header, null));
lst_order.setAdapter(orderAdapter);
lst_order.setOnItemClickListener(itemClickListener);
txt_order_total.setText("Total Price: " + controller.calculateTotalPrice());
layout.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener()
{
@Override
public void onGlobalLayout()
{
layout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
RelativeLayout.LayoutParams layoutParams;
int currentX = 20;
int currentY = 20;
for (Product product: controller.getProducts("pizza")){
layoutParams = new RelativeLayout.LayoutParams(UIConstnts.BUTTON_WIDTH, UIConstnts.BUTTON_HEIGHT);
Button tempButton = new Button(getActivity().getApplicationContext());
tempButton.setId((int)product.getId());
tempButton.setText(product.getName());
tempButton.setOnClickListener(clickListener);
layoutParams.setMargins(currentX, currentY, 0, 0);
tempButton.setLayoutParams(layoutParams);
layout.addView(tempButton);
if (layout.getWidth() < currentX + UIConstnts.MARGIN_LEFT + (2 * UIConstnts.BUTTON_WIDTH)){
currentX = 20;
currentY += UIConstnts.BUTTON_HEIGHT + UIConstnts.MARGIN_BOTTOM;
}
else{
currentX += UIConstnts.MARGIN_LEFT + UIConstnts.BUTTON_WIDTH;
}
}
layout.requestLayout();
}
});
return view;
}
private OnClickListener clickListener = new OnClickListener(){
@Override
public void onClick(View view) {
controller.addOrderItem(1, (long)view.getId());
updateQuantity();
txt_order_total.setText("Total Price: " + controller.calculateTotalPrice());
}
};
private OnItemClickListener itemClickListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
showDialog(id, Integer.valueOf(((TextView)view.findViewById(R.id.txt_lst_quantity)).getText().toString()));
}
};
private OnClickListener finishOrder = new OnClickListener(){
@Override
public void onClick(View v) {
controller.finishOrder(getActivity());
updateQuantity();
}
};
private OnClickListener cancelOrder = new OnClickListener(){
@Override
public void onClick(View v) {
controller.resetOrder();
updateQuantity();
}
};
private void showDialog(long productId, int quantity) {
DialogFragment newFragment = EditOrderDialog.newInstance(productId, quantity, "Change Quantity");
newFragment.setTargetFragment(this, DIALOG_EDIT_ORDER);
newFragment.show(getFragmentManager(), "dialog");
}
@Override
public void updateQuantity() {
orderAdapter.setOrderList(controller.getOrderMap());
orderAdapter.notifyDataSetChanged();
txt_order_total.setText("Total Price: " + controller.calculateTotalPrice());
}
}
UI的图片。 (右侧的ListView出现在所有选项卡上,并包含订单中的所有产品):
答案 0 :(得分:0)
不要在构造函数中询问参数/ extras!它们目前尚未确定。它们将在稍后推出。
//If you create your Fragments yourself, create them in a static factory method:
public static Fragment newInstance(String productType){
Bundle b = new Bundle();
b.putString(ARG_PRODUCT_TYPE, productType);
Fragment f = new OrderFragment();
f.setArguments(b);
return f;
}
//Write a helper method for your arguments
public String getProductType(){
if(getArguments().containsKey(ARG_PRODUCT_TYPE)){
return getArguments().getString(ARG_PRODUCT_TYPE);
}
return null;
}
然后在构造函数之后使用辅助方法,即在onCreate()中。