getArguments返回null

时间:2015-07-22 20:22:28

标签: android android-fragments arraylist nullpointerexception

我需要将arraylist从一个片段转移到另一个片段。我看了几篇同样问题的文章,但没有一个选项无法解决我的问题.... 来自BakeFragment

OrderFragment orderFragment = new OrderFragment();
                   Bundle bundle = new Bundle();
                   bundle.putStringArrayList(ORDER_KEY, orderList);
                    orderFragment.setArguments(bundle);

我需要在OrderFragment中获得这个arraylist。我是怎么做的

第一版

Bundle mBundle = this.getArguments();
orderArrayList = mBundle.getStringArrayList(ORDER_KEY);

错误:

java.lang.NullPointerException
        at com.zhisheng.navdrawer.model.OrderFragment.onCreateView(OrderFragment.java:38)
        at android.app.Fragment.performCreateView(Fragment.java:1699)
        at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:885)
        at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1057)
        at android.app.BackStackRecord.run(BackStackRecord.java:682)
        at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1435)
        at android.app.FragmentManagerImpl$1.run(FragmentManager.java:441)
        at android.os.Handler.handleCallback(Handler.java:730)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:5137)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:525)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:756)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:572)
        at miui.dexspy.DexspyInstaller.main(DexspyInstaller.java:171)
        at dalvik.system.NativeStart.main(Native Method)

第二版

if(getArguments()!=null){
        orderArrayList = this.getArguments().getStringArrayList("key");
    }

不要收到错误,但没有任何反应。

public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;

// nav drawer title
private CharSequence mDrawerTitle;

// used to store app title
private CharSequence mTitle;

// slide menu items
private String[] navMenuTitles;
private TypedArray navMenuIcons;

private ArrayList<NavDrawerItem> navDrawerItems;
private NavDrawerListAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mTitle = mDrawerTitle = getTitle();

    // load slide menu items
    navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);

    // nav drawer icons from resources
    navMenuIcons = getResources()
            .obtainTypedArray(R.array.nav_drawer_icons);

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    mDrawerList = (ListView) findViewById(R.id.list_slidermenu);

    navDrawerItems = new ArrayList<NavDrawerItem>();



    // adding nav drawer items to array
    // Home
    navDrawerItems.add(new NavDrawerItem(navMenuTitles[0], navMenuIcons.getResourceId(0, -1)));
    // Find People
    navDrawerItems.add(new NavDrawerItem(navMenuTitles[1], navMenuIcons.getResourceId(1, -1)));
    // Photos
    navDrawerItems.add(new NavDrawerItem(navMenuTitles[2], navMenuIcons.getResourceId(2, -1)));
    // Communities, Will add a counter here
    navDrawerItems.add(new NavDrawerItem(navMenuTitles[3], navMenuIcons.getResourceId(3, -1)));
    // Pages
    navDrawerItems.add(new NavDrawerItem(navMenuTitles[4], navMenuIcons.getResourceId(4, -1)));
    // What's hot, We  will add a counter here
    navDrawerItems.add(new NavDrawerItem(navMenuTitles[5], navMenuIcons.getResourceId(5, -1)));

    navDrawerItems.add(new NavDrawerItem(navMenuTitles[6], navMenuIcons.getResourceId(6, -1)));

    navDrawerItems.add(new NavDrawerItem(navMenuTitles[7], navMenuIcons.getResourceId(7, -1)));
    // Find People
    navDrawerItems.add(new NavDrawerItem(navMenuTitles[8], navMenuIcons.getResourceId(8, -1)));
    // Photos
    navDrawerItems.add(new NavDrawerItem(navMenuTitles[9], navMenuIcons.getResourceId(9, -1)));
    // Communities, Will add a counter here
    navDrawerItems.add(new NavDrawerItem(navMenuTitles[10], navMenuIcons.getResourceId(10, -1)));

    navDrawerItems.add(new NavDrawerItem(navMenuTitles[11], navMenuIcons.getResourceId(11, -1)));


    // Recycle the typed array
    navMenuIcons.recycle();

    mDrawerList.setOnItemClickListener(new SlideMenuClickListener());

    // setting the nav drawer list adapter
    adapter = new NavDrawerListAdapter(getApplicationContext(),
            navDrawerItems);
    mDrawerList.setAdapter(adapter);

    // enabling action bar app icon and behaving it as toggle button
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setHomeButtonEnabled(true);

    mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.navigation_drawer_open, R.string.navigation_drawer_close) {
        public void onDrawerClosed(View view) {
            getSupportActionBar().setTitle(mTitle);
            // calling onPrepareOptionsMenu() to show action bar icons
            invalidateOptionsMenu();

        }

        public void onDrawerOpened(View drawerView) {
            getSupportActionBar().setTitle(mDrawerTitle);
            // calling onPrepareOptionsMenu() to hide action bar icons
            invalidateOptionsMenu();
        }
    };
    mDrawerLayout.setDrawerListener(mDrawerToggle);

    if (savedInstanceState == null) {


        displayView(11);
    }

}

/**
 * Slide menu item click listener
 */
private class SlideMenuClickListener implements
        ListView.OnItemClickListener {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
                            long id) {
        // display view for selected nav drawer item
        displayView(position);
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // toggle nav drawer on selecting action bar app icon/title
    if (mDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    // Handle action bar actions click
    switch (item.getItemId()) {
        case R.id.action_settings:
          return true;
        default:
          displayView(11);

            //Toast.makeText(getApplicationContext(), "RasRas", Toast.LENGTH_LONG).show();
            return true;
    }
}

/* *
 * Called when invalidateOptionsMenu() is triggered
 */
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    // if nav drawer is opened, hide the action items
    boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
    menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
    return super.onPrepareOptionsMenu(menu);
}

/**
 * Diplaying fragment view for selected nav drawer list item
 */
private void displayView(int position) {
    // update the main content by replacing fragments
    Fragment fragment = null;
    switch (position) {
        case 0:
            fragment = new BakeFragment();
            break;
        case 1:
            fragment = new GarnishFragment();
            break;
        case 2:
            fragment = new HotDishesFragment();
            break;
        case 3:
            fragment = new DesertsFragment();
            break;
        case 4:
            fragment = new HomeFragment();
            break;
        case 5:
            fragment = new SnacksFragment();
            break;
        case 6:
            fragment = new DrinkFragment();
            break;
        case 7:
            fragment = new PizzaFragment();
            break;
        case 8:
            fragment = new SaladFragment();
            break;
        case 9:
            fragment = new ConfectionFragment();
            break;
        case 10:
            fragment = new SoupFragment();
            break;
        case 11:
            fragment = new OrderFragment();
        default:
            break;
    }

    if (fragment != null) {
        FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.frame_container, fragment).commit();

        // update selected item and title, then close the drawer
        mDrawerList.setItemChecked(position, true);
        mDrawerList.setSelection(position);
        setTitle(navMenuTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
    } else {
        // error in creating fragment
        Log.e("MainActivity", "Error in creating fragment");
    }
}

@Override
public void setTitle(CharSequence title) {
    mTitle = title;
    getSupportActionBar().setTitle(mTitle);
}

/**
 * When using the ActionBarDrawerToggle, you must call it during
 * onPostCreate() and onConfigurationChanged()...
 */

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    // Sync the toggle state after onRestoreInstanceState has occurred.
    mDrawerToggle.syncState();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // Pass any configuration change to the drawer toggls
    mDrawerToggle.onConfigurationChanged(newConfig);
}

BakeFragment

public class BakeFragment extends Fragment {

final static String ORDER_KEY="key";

String myString;

ListView listView;
ArrayList<MenuItem> arrayList;
CustomAdapter customAdapter;
MenuItem menuItem;

ArrayList<String>  orderList;

View rootView = null;


Integer[] quantity = {
  1, 2, 3, 4, 5, 6, 7, 8, 9, 10
};

String[] bakeList = new String[]{
        "Булочка с кунжутом", "Ватрушка с творогом", "Качори с чечевицей", "Лепешка \"Пападам\"",
        "Лепешка \"Паратха\"", "Лепешка \"Чапати\"", "Лепешка с сыром", "Пирожное \"Корзиночка\"",
        "Пирожок с капустой", "Пирожок с картофелем", "Пряник кокосовый экадашный" , "Самоса с вишней",
        "Самоса с клубникой", "Самоса с малиной","Самоса с овощами и паниром", "Самоса с сухофруктами (печеная)",  "Самоса с творогом", "Самоса с черной смородиной",
        "Самоса с яблоком в карамели"
};


Integer[] imagesOfBakeList = new Integer[]{
        R.drawable.bake1, R.drawable.bake2, R.drawable.bake3, R.drawable.bake4, R.drawable.bake5,
        R.drawable.bake6, R.drawable.bake7, R.drawable.bake8, R.drawable.bake9, R.drawable.bake10,
        R.drawable.bake11, R.drawable.bake12, R.drawable.bake13, R.drawable.bake14, R.drawable.bake15,
        R.drawable.bake16, R.drawable.bake17, R.drawable.bake18, R.drawable.bake19


};

String[] priceOfBakeList = new String[]{
        "30", "60", "60", "30", "70", "30", "70", "90", "60", "60", "60", "60", "60", "60", "60", "60",
        "60", "60", "60"
};



@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

     rootView = inflater.inflate(R.layout.list_item, container, false);

    listView = (ListView)rootView.findViewById(R.id.list_of_menu_item);
    orderList = new ArrayList<String>();
    arrayList = new ArrayList<MenuItem>();
    for(int i = 0; i < bakeList.length; i++) {
        menuItem = new MenuItem(imagesOfBakeList[i], bakeList[i], priceOfBakeList[i]);
        arrayList.add(menuItem);
    }
    customAdapter = new CustomAdapter(getActivity().getApplicationContext(), arrayList);
    listView.setAdapter(customAdapter);

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        View v = null;


        @Override
        public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
            //Toast.makeText(getActivity().getApplicationContext(), "Вы заказали " + customAdapter.getItem(position), Toast.LENGTH_SHORT).show();
            LayoutInflater layoutInflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = layoutInflater.inflate(R.layout.view, null);
            String dishForOrderList;
            final int s = customAdapter.getPrice(position);
            final String dish = customAdapter.getItem(position).toString();
            final String allstr;
            Spinner spinner = (Spinner) v.findViewById(R.id.spinView);
            final TextView orderText = (TextView) v.findViewById(R.id.order_text);
            ArrayAdapter<CharSequence> spinnerAdapter = ArrayAdapter.createFromResource(getActivity(), R.array.option, android.R.layout.simple_spinner_item);
            spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            spinner.setAdapter(spinnerAdapter);
            spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                    String selected = parent.getSelectedItem().toString();
                    int t = Integer.parseInt(selected);
                    myString = dish + " x" + t + "     " + (s * t);
                    String abc = dish+" x"+t+"     !";
                    orderText.setText(myString);
                     Toast.makeText(getActivity(), myString, Toast.LENGTH_LONG).show();

                }

                @Override
                public void onNothingSelected(AdapterView<?> parent) {

                }
            });

            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());


            builder.setView(v);
            builder.setTitle("Сколько порций " + dish + " вы хотите заказать?");
            builder.setCancelable(false);

            builder.setNegativeButton("Заказать", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {

                    orderList.add(myString);

                  Toast.makeText(getActivity(), orderList+"", Toast.LENGTH_LONG).show();
                   OrderFragment orderFragment = new OrderFragment();
                   Bundle bundle = new Bundle();
                   bundle.putStringArrayList(ORDER_KEY, orderList);
                    orderFragment.setArguments(bundle);
                    dialog.cancel();
                }
            });
            builder.setPositiveButton("Отмена", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });
            AlertDialog alertDialog = builder.create();
            alertDialog.show();

        }
    });

    return rootView;

}

}

OrderFragment

public class OrderFragment extends Fragment {

View rootView = null;
ListView orderListView;
ArrayList<String> orderArrayList;
ArrayAdapter<String> stringArrayAdapter;

final static String ORDER_KEY="key";


@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    rootView = inflater.inflate(R.layout.order_list, container, false);
    orderArrayList = new ArrayList<String>();

   Bundle mBundle = this.getArguments();
   orderArrayList = mBundle.getStringArrayList(ORDER_KEY);

 /*   if(getArguments()!=null){
        orderArrayList = this.getArguments().getStringArrayList("key");
    }*/
   // orderArrayList = this.getArguments()!=null? getArguments().getStringArrayList("array") : null;
    //Toast.makeText(getActivity(), "d = "+orderArrayList, Toast.LENGTH_LONG).show();
//        orderArrayList = bundle.getStringArrayList("key");
  orderListView = (ListView)rootView.findViewById(R.id.order_list_view);
    stringArrayAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, orderArrayList);
    orderListView.setAdapter(stringArrayAdapter);

    return rootView;
}}

2 个答案:

答案 0 :(得分:1)

我认为您的问题可以追溯到这段代码:

public void onClick(DialogInterface dialog, int which) {

    orderList.add(myString);

    Toast.makeText(getActivity(), orderList+"", Toast.LENGTH_LONG).show();
    OrderFragment orderFragment = new OrderFragment();
    Bundle bundle = new Bundle();
    bundle.putStringArrayList(ORDER_KEY, orderList);
    orderFragment.setArguments(bundle);
    dialog.cancel();
}

您正在尝试创建一个OrderFragment,因为单击了对话框按钮。但是,由于您未将此实例附加到活动,因此永远不会设置参数。在displayView()方法中你有这个:

case 11:
    fragment = new OrderFragment();

基本上,你所拥有的片段没有设置任何参数 - 这就是你之后无法看到它们的原因。

为了解决这个问题,我建议你采取以下几个步骤:

  1. 实现适当的片段 - 片段通信。请记住,碎片不应该直接相互通信(除非它们是嵌套的,但这不是你的情况)。如果你通过活动组织它会更好--BakeFragment获取订单,将它们发送到活动,活动将它们设置为OrderFragment的参数。您可以在此处获得一个很好的示例和有关此方法的更多信息:http://developer.android.com/training/basics/fragments/communicating.html
  2. 重新组织displayView()方法。目前,每次调用此方法时,您都将强制创建所需片段的新实例。这可能会导致不良行为 - 性能不佳,后端堆栈的奇怪状态等。此外,在重新创建片段时,您无法从片段参数的自动保存中受益。我建议你使用标签,首先检查你想要显示的片段是否已经存在。

    FragmentManager fm = getSupportFragmentManager();
    Fragment fragment = fm.findByTag(THE_FRAGMENT_TAG);
    if (fragment == null) {
        // logic to create a fragment instance
    } 
    // logic to show the fragment
    

答案 1 :(得分:0)

我唯一一次看到在FragmentTransaction中使用的OrderFragment是在MainActivity displayView方法中创建的。在那里,它没有设置参数。

你的BakeFragment会创建一个OrderFragment并设置它的参数,但它永远不会通过FragmentTransaction添加,并且只要你的onClick(DialogInterface对话框,int which)方法执行完毕就会超出范围。因此,永远不会使用带参数集的OrderFragment。

您是不是要通过使用FragmentTransaction向用户显示此片段?如果是这样,您可以让BakeFragment使用一种方法定义一个接口,该方法向监听器指示用户决定创建订单或取消订单。让MainActivity实现此接口并将自己注册为BakeFragment上的侦听器。

PS:为什么你的逻辑似乎与你的AlertDialog负面和正面按钮点击处理程序相反?