6

I have an activity which instantiates and populates a Fragment through a adopter class. I want to pass values/objects to this Fragment adopter class so that i can dictate layout etc.

I have tried passing bundles using the setArgument method but my code bombs out and not sure why. As i understand, i can collect the bundle at the onCreate method in the adopter class. I see the arguments are set correctly immediately after the commented code but alas it crashes after that and i don't understand why. If i remove the bundle code it doesnt crash. :(

Below is my code, does anybody know where i should put the bundle code, commented out?

public class LoginScreen extends ActionBarActivity {
    private final String ARG_SELECTED_LAYOUT_ID = "selectedLayoutId";
private final int DEFAULT_LAYOUT = R.layout.layout_list;

private int mSelectedLayoutId;

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

    ActionBar actionBar = getSupportActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    actionBar.setDisplayShowTitleEnabled(false);
    actionBar.setDisplayShowHomeEnabled(false);

    mSelectedLayoutId = DEFAULT_LAYOUT;
    if (savedInstanceState != null) {
        mSelectedLayoutId = savedInstanceState.getInt(ARG_SELECTED_LAYOUT_ID);
    }

    addLayoutTab(
            actionBar, R.layout.layout_list, R.drawable.ic_list, "list");
    addLayoutTab(
            actionBar, R.layout.layout_grid, R.drawable.ic_grid, "grid");
    addLayoutTab(
            actionBar, R.layout.layout_staggered_grid, R.drawable.ic_staggered, "staggered");
    addLayoutTab(
            actionBar, R.layout.layout_spannable_grid, R.drawable.ic_spannable, "spannable");
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt(ARG_SELECTED_LAYOUT_ID, mSelectedLayoutId);
}

private void addLayoutTab(ActionBar actionBar, int layoutId, int iconId, String tag) {
    ActionBar.Tab tab = actionBar.newTab()
            .setText("")
            .setIcon(iconId)
            .setTabListener(new TabListener(layoutId, tag));
    actionBar.addTab(tab, layoutId == mSelectedLayoutId);
}

public class TabListener implements ActionBar.TabListener {
    private LayoutFragment mFragment;
    private final int mLayoutId;
    private final String mTag;


    public TabListener(int layoutId, String tag) {
        mLayoutId = layoutId;
        mTag = tag;
    }

    @Override
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
        mFragment = (LayoutFragment) getSupportFragmentManager().findFragmentByTag(mTag);



        if (mFragment == null) {
            mFragment = (LayoutFragment) LayoutFragment.newInstance(mLayoutId);
            ft.add(R.id.content, mFragment, mTag);

        } else {
            ft.attach(mFragment);
        }


        /*
            Bundle bundle = new Bundle();
            bundle.putInt("noTiles", 4);
            mFragment.setArguments(bundle);           
        */

        mSelectedLayoutId = mFragment.getLayoutId();
    }

    @Override
    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
        if (mFragment != null) {
            ft.detach(mFragment);
        }
    }

    @Override
    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
    }
}

}

Logcat

03-03 11:56:53.675  32507-32507/weebuns.predictionking E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: weebuns.predictionking, PID: 32507
    java.lang.RuntimeException: Unable to start activity ComponentInfo{weebuns.predictionking/weebuns.predictionking.LoginScreen}: java.lang.NullPointerException: Attempt to invoke virtual method 'void weebuns.predictionking.LayoutFragment.setArguments(android.os.Bundle)' on a null object reference
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void weebuns.predictionking.LayoutFragment.setArguments(android.os.Bundle)' on a null object reference
Fearghal
  • 10,569
  • 17
  • 55
  • 97
  • 1
    what is the logcat error you are getting with uncommented code ? – Yash Sampat Mar 03 '15 at 10:35
  • send bundle when you are creating instance:mFragment = (LayoutFragment) LayoutFragment.newInstance(mLayoutId,YourBundle); – Wasim Ahmed Mar 03 '15 at 11:11
  • i get Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void weebuns.predictionking.LayoutFragment.setArguments(android.os.Bundle)' on a null object reference error – Fearghal Mar 03 '15 at 11:52

5 Answers5

5

To pass argument to your fragment, it's recommended to create a public static method to instanciate your fragment like :

public static MyFragment newInstance(String firstArg) {
        MyFragment f = new MyFragment ();
        Bundle args = new Bundle();
        args.putString("ARG1", firstArg);
        f.setArguments(args);
        return f;
    }

And then retrieve your args in onCreateView() method like :

String arg = getArguments().getString("ARG1");

Use the static method to instanciate a new fragment with your arguments in other fragment or activities like :

MyFragment f = MyFragment.newInstance(myArg);
Bubu
  • 1,533
  • 14
  • 14
4

It's hard to say without seeing the logcat, but surely you are missing to call the commit() method on the FragmentTransaction. Also remember to set the arguments to the fragment before calling ft.commit().

@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
    mFragment = (LayoutFragment) getSupportFragmentManager().findFragmentByTag(mTag);

    if (mFragment == null) {
        Bundle bundle = new Bundle();
        bundle.putInt("noTiles", 4);
        mFragment = (LayoutFragment) LayoutFragment.newInstance(mLayoutId);
        mFragment.setArguments(bundle);
        //ft.add(R.id.content, mFragment, mTag).commit();
        ft.add(R.id.content, mFragment, mTag);

    } else {
        ft.attach(mFragment);
    }

    mSelectedLayoutId = mFragment.getLayoutId();
}
Morry
  • 726
  • 4
  • 11
  • im getting error: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void weebuns.predictionking.LayoutFragment.setArguments(android.os.Bundle)' on a null object reference – Fearghal Mar 03 '15 at 11:49
  • Making progress.....New issue: Process: weebuns.predictionking, PID: 19902 java.lang.RuntimeException: Unable to start activity ComponentInfo{weebuns.predictionking/weebuns.predictionking.LoginScreen}: java.lang.IllegalStateException: commit already called. I cant see where it is committed tbh – Fearghal Mar 03 '15 at 12:12
  • So, it seems the `commit()` is called automatically by the Activity indeed, since is a parmeter of `onTabSelected()`. Try the new code I posted. – Morry Mar 03 '15 at 12:37
  • :( back to original issue.... ...AndroidRuntime﹕ FATAL EXCEPTION: main Process: weebuns.predictionking, PID: 26186 java.lang.RuntimeException: Unable to start activity ComponentInfo{....LoginScreen}: android.content.res.Resources$NotFoundException: Resource ID #0x0 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) Caused by: android.content.res.Resources$NotFoundException: Resource ID #0x0 – Fearghal Mar 03 '15 at 14:36
  • In this case the problem could be in the fragment. What do you do with the argument passed to it? – Morry Mar 03 '15 at 14:43
  • Nothing at the moment - i have not edited the Fragment code to 'getArguments' yet. I was waiting to get the setArg(bundle) code working - do you think this code needs to be implemented simultaneously? – Fearghal Mar 03 '15 at 14:51
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/72154/discussion-between-morry-and-fearghal). – Morry Mar 03 '15 at 14:57
1

In your activity

Bundle args = new Bundle();
args.putString("Menu", "Your String");
Fragment detail = new FragmeantOne();
detail.setArguments(args);
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, detail).commit();

In your Fragment.. in onCreateView()

String menu = getArguments().getString("Menu");
someTextView.setText(menu);
Umer Waqas
  • 1,794
  • 1
  • 12
  • 15
1

You can use Bundle to transfer data from activity to fragments or transfre data from fragment to fragment.

Bundle bundle = new Bundle();
DisplayDataList fragment = new DisplayDataList();
bundle.putString("listitem", "Buyer,Seller");
            fragment.setArguments(bundle);

            getFragmentManager().beginTransaction().replace(
                    R.id.frame_container, fragment).addToBackStack(null).commit();

Where you want to recieve that bundle i.w in DisplayDataList Fragment class. You have to use getArguments() method.

DisplayDataList

 Bundle bundle = getArguments();
            String getdata = bundle.getString("listitem");
            System.out.println("Data got-->>> " + getdata);

Hope this will help you.

Anuj Sharma
  • 4,294
  • 2
  • 37
  • 53
  • Thx but i have that code (or an attempt at it) in there and it breaks it, where should this code go? Is my bundle code correct? See my posted code for the commented out problem code. Can you put your code in the context of mine - class names etc so i can see better where it goes as afaics mine should at the very least not crash the app. – Fearghal Mar 03 '15 at 10:58
  • Use Bundle code before replacing or adding new fragment and make sure you are passing the bundle with fragment object in replace code.Try this LayoutFragment mFragment = new LayoutFragment(); Bundle bundle = new Bundle(); bundle.putInt("noTiles", 4); mFragment.setArguments(bundle); if (mFragment == null) { mFragment = (LayoutFragment) LayoutFragment.newInstance(mLayoutId); ft.add(R.id.content, mFragment, mTag); } else { ft.attach(mFragment); } – Anuj Sharma Mar 03 '15 at 11:05
  • I get the following error: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void weebuns.predictionking.LayoutFragment.setArguments(android.os.Bundle)' on a null object reference – Fearghal Mar 03 '15 at 11:57
0

You can use Bundle to transfer data between activity and fragment/Dialog fragment

Send data From Your Activity to Fragment() -> onClickBtn()

val f = PaymentBottomSheet()
            val bundle = Bundle()
            bundle.putString("coins", walletBinding.edCoins.text.toString())
            bundle.putString("method", getJsonData()[adapter.selected].method)
            bundle.putString("name", walletBinding.edNickName.text.toString())
            bundle.putString("acc", walletBinding.edAccountId.text.toString())
            f.arguments = bundle
            f.show(supportFragmentManager, f.tag)

Retrieved Data from Your Activity (Your fragment code look like this) onCreateView()

 val bundle = Bundle(arguments)
    coins = bundle.getString("coins")
    method = bundle.getString("method")
    name = bundle.getString("name")
    id = bundle.getString("acc")

    Timber.d("Coins $coins, Method $method, Name $name, ID $id")

Thank You

Kumar Santanu
  • 603
  • 1
  • 7
  • 14