1

我正在开发一个由多个选项卡组成的小型应用程序,其中每个选项卡仅包含一种产品(例如比萨饼产品),并且可以将此选项卡中的特定产品(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)创建了一个指定类的实例并将附加内容放入其中,但似乎这些附加内容并未包含在其中。(猜它是为了另一个目的)。我将不胜感激有关如何解决此问题的任何建议。如果您以完全不同的方式进行操作,我也将不胜感激。

订单片段:

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




}

用户界面的图片。(右侧的 ListView 出现在所有选项卡上,并包含订单中的所有产品): 在此处输入图像描述

4

1 回答 1

0

不要在构造函数中询问参数/附加内容!他们目前没有设置。它们稍后将可用。

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

然后在Constructor之后使用helper方法,即在onCreate()中。

于 2013-10-25T14:22:23.547 回答