Android:Bundle NullPointerException

时间:2016-01-22 04:18:21

标签: android nullpointerexception bundle

我正在开发一个应用程序,我需要将一些数据从ListFragment发送到ItemFragment。我使用bundle但是我得到了nullpointerexception。我应该提一下,我是一个新手,这是我的第一个应用程序。所以让我知道我所做的是错误还是令人困惑。这是我的代码

ListFragment.java

            if (child != null && mGestureDetector.onTouchEvent(motionEvent)) {
                int position = recyclerView.getChildLayoutPosition(child);
                selectedItem = mItems.get(position);
                itemId = mItems.get(position).getId();
                openFragment(new ItemFragment(), "MyApp");
                ItemFragment if = new ItemFragment();
                Bundle bundle = new Bundle();
                bundle.putLong("selectedId", itemId);
                if.setArguments(bundle);
}
            return false;
        }

ItemFragment.java

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


    Bundle bundledData = this.getArguments();
    selectedId = bundledData.getLong("selectedId");//here is the line 105 in logcat

    return mRootView;
}

logcat的

java.lang.NullPointerException
at me.myapp.fragments.ItemFragment.onCreateView(ItemFragment.java:105)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1962)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)

--- ---添加

出于某种原因,当我在这里尝试答案时,我仍然会遇到同样的错误,除了nguyen's。根据我在nguyen的代码中的理解,我使用了这个

ListFragment.java

private long itemId;

if (child != null && mGestureDetector.onTouchEvent(motionEvent)) {
                int position = recyclerView.getChildLayoutPosition(child);
                selectedItem = mItems.get(position);
                itemId = mItems.get(position).getId();
                Bundle bundle = new Bundle();
                bundle.putLong("selectedId", itemId);
                ItemFragment itemFrag = ItemFragment.newInstance(bundle);
                openFragment(new ItemFragment(), "Update Item");
                Toast.makeText(getActivity(), "id = " + itemId, Toast.LENGTH_SHORT).show();

ItemFragment.java

private long selId;

public static ItemFragment newInstance(Bundle bundle) {
    ItemFragment frag = new ItemFragment();
    frag.setArguments(bundle);
    return frag;
}

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

    if (getArguments() != null) {
         selId = getArguments().getLong("selectedId");
    }
    makeToast(""+selId);

return mRootView;
}

这些代码我没有收到任何错误。 ListFragment中的toast确实显示了正确的值,但ItemFragment中的toast总是返回0.我在这里缺少什么?

5 个答案:

答案 0 :(得分:1)

要将数据包放入Fragment,您应该在 ItemFragment 中使用静态功能 newInstance(捆绑包)

public static ItemFragment newInstance(Bundle bundle) {
    ItemFragment myFragment = new ItemFragment();

    myFragment.setArguments(bundle);

    return myFragment;
}


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

    Bundle bundle = getArguments();
    // DO SOMETHING

    return super.onCreateView(inflater, container, savedInstanceState);
}

使用它你打电话:

Bundle bundle = new Bundle();
//put data in bundle
ItemFragment  itemfrag = ItemFragment.newInstance(bundle);

答案 1 :(得分:1)

ItemFragment 中,你应该这样写

 Bundle bundledData = this.getArguments();
        if (getArguments() != null) {
          selectedId = bundledData.getLong("selectedId");
        }

您可以在Toast块中添加if以检查selectedId是否显示。

<强>被修改

<强> ItemFragment.java

 private long selId;


     @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View edit_details = inflater.inflate(R.layout.edit_staff_list, container, false);
            Bundle bundle = this.getArguments();
            if (getArguments() != null) {
               selId = bundle.getLong("selectedId");
                Toast.makeText(getActivity(), selId, Toast.LENGTH_LONG).show();

            }

答案 2 :(得分:0)

您正在创建同一片段的两个实例,在第二个片段上设置参数,并显示第一个没有任何参数的实例。因此,当您尝试在onCreateView中提取参数时,会出现NullPointerException。

...
openFragment(new ItemFragment(), "MyApp"); // Show first fragment
ItemFragment if = new ItemFragment(); // Instantiate second fragment
Bundle bundle = new Bundle();
bundle.putLong("selectedId", itemId);
if.setArguments(bundle); // arguments go to the second one | The one which is never even displayed to the user.
...

答案 3 :(得分:0)

尝试将listFragment中的代码编辑为此。

if (child != null && mGestureDetector.onTouchEvent(motionEvent)) {
    int position = recyclerView.getChildLayoutPosition(child);    
    selectedItem = mItems.get(position);        
    itemId = mItems.get(position).getId();

    ItemFragment itemFragment = new ItemFragment();
    Bundle bundle = new Bundle();
    bundle.putLong("selectedId", itemId);
    itemFragment.setArguments(bundle);

    openFragment(itemFragment, "MyApp");
}

return false;

您的代码的问题是您将ItemFragment的新实例传递给openFragment()函数,而不是您创建并添加了一个包。

答案 4 :(得分:0)

花了几个小时搞乱代码,反复试验,尝试了不同的代码,nguyen的代码和代码https://stackoverflow.com/a/16036693/5563156给了我这个想法。这些代码似乎完成了工作

<强> ListFragment.java

mRecyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
        @Override
        public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {
            View child = recyclerView.findChildViewUnder(motionEvent.getX(), motionEvent.getY());

            if (child != null && mGestureDetector.onTouchEvent(motionEvent)) {
                int position = recyclerView.getChildLayoutPosition(child);
                selectedItem = mItems.get(position);
                itemId = mItems.get(position).getId();
                //pass selected item's ID to Main Activity
                Intent i = new Intent(getActivity(), MainActivity.class);
                i.putExtra("selectedId", itemId);
                startActivity(i);
                Toast.makeText(getActivity(), "id = " + itemId, Toast.LENGTH_SHORT).show();

            }
            return false;
        }

MainActivity&#39; OnCreate

if(savedInstanceState == null){
        //receives selected item's ID passed from ListFragment
        Intent intent = getIntent();
        long selId = intent.getLongExtra("selectedId", 0);

         if (selId > 0) {
             //send the selected item ID to ItemFragment
             Bundle bundle = new Bundle();
             bundle.putLong("selectedId", 0);
             ItemFragment frag = new ItemFragment();
         openFragment(ItemFragment.newInstance(selId), "Update Item");
         frag.setArguments(bundle);
         }}

<强> ItemFragment.java

public static ItemFragment newInstance(long selId) {
    ItemFragment fragment = new ItemFragment();

    if (selId > 0) {
        Bundle bundle = new Bundle();
        bundle.putLong("selectedId", selId);
        fragment.setArguments(bundle);
    }
    return fragment;
}

ItemFragment的OnCreateView

Bundle args = getArguments();
    if (args != null && args.containsKey("selectedId")) {
        selId = args.getLong("selectedId");
    }

感谢所有发布代码的人!感谢帮助。