android fragment getArguments returns null in oncreateView() - android

I have two fragments and FilterFragment and LocationListFragment. when I am switching to LocationListFragment.java I am getting values in getArguments() and from LocationListFragment.java to FilterFragment.java getting null values by calling getArgument(); here is the details
In FilterFargment.java code is here for set values:
LocationListFragment locationListFragment = new LocationListFragment();
bundle = new Bundle();
Log.e("",""+locationList.getLocationListFilter().size());
bundle.putParcelable(Constant.LOCATION_LIST_FILTER, locationList);
bundle.putString(Constant.FROM_DATE_FILTER, textView_time_from.getText().toString());
locationListFragment.setArguments(bundle);
((DashbordActivity) getActivity()).switchFragment(locationListFragment, true);
In LocationListFragment.java (getting values)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
if (args != null) {
locationList = args.getParcelable(Constant.LOCATION_LIST_FILTER);
getFromDate = args.getString(Constant.FROM_DATE_FILTER);}}
And here from LocationListFragment on button click send data to FilterFragment sending new values with bundle:
FilterFragment filterFragment =new FilterFragment();//.newInstance(getFromDate, getEndDate, getLocation, getCategories);
Bundle bundle = new Bundle();
bundle.putString(Constant.FROM_DATE_FILTER, getFromDate);
bundle.putString(Constant.WHERE_FILTER, getLocation);
filterFragment.setArguments(bundle);
((DashbordActivity) getActivity()).switchFragment(filterFragment, true);
and in FilterFragment.java while returning back getting null value for getArguments(); code is here:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_filter, container, false);
Log.e("FilterFragment", "oncreateview");
Bundle args = getArguments();
Log.e("getArguments", "" + getArguments());//getting null here
Also, I have used this method for switching fragment,
public void switchFragment(BaseFragment fragment, boolean keep) {
FragmentManager manager = getSupportFragmentManager();
boolean fragmentPopped = manager.popBackStackImmediate(fragment.getClass().getSimpleName(), 0);
if (!fragmentPopped && manager.findFragmentByTag(fragment.getClass().getSimpleName()) == null) { //fragment not in back stack, create it.
FragmentTransaction tr = manager.beginTransaction();
tr.replace(R.id.container, fragment, fragment.getClass().getSimpleName());
if (keep) {
tr.addToBackStack(fragment.getClass().getSimpleName());
Log.e("keep", "BaseAct:" + keep);
}
tr.commit();
}
}
Can you tell me what I am missing? Any help will be appreciated.

Related

putExtra from activity then getExtra in fragment

i tried to put and get extra from activity to fragment . but something is wrong! anybody have idea? my case is diffrent because i wanna do it in fragment
myActivity :
if(email.matches(users.user1)&&password.matches(users.pass1)){
Intent intent = new Intent(LoginActivity.this,MainActivity.class);
Intent i = new Intent(LoginActivity.this,ProfileFragment.class);
i.putExtra("pn", users.pn1);
i.putExtra("name", users.name1);
i.putExtra("family", users.family1);
i.putExtra("rank", users.rank1);
startActivity(intent);
finish();
}
myfragment
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_profile2, container, false);
final TextView pn =getActivity().findViewById(R.id.pn);
final TextView name =getActivity().findViewById(R.id.name);
final TextView family =getActivity().findViewById(R.id.family);
final TextView user =getActivity().findViewById(R.id.user);
final TextView rank =getActivity().findViewById(R.id.rank);
String pnget = getActivity().getIntent().getStringExtra("pn");
String nameget = getActivity().getIntent().getStringExtra("name");
String familyget = getActivity().getIntent().getStringExtra("family");
String userget = getActivity().getIntent().getStringExtra("user");
String rankget = getActivity().getIntent().getStringExtra("rank");
pn.setText(pnget);
name.setText(nameget);
family.setText(familyget);
user.setText(userget);
rank.setText(rankget);
}
Hi . i tried to put and get extra from activity to fragment . but something is wrong! anybody have idea?
You start an intent call intent. But the intent have data is i, and it have't started yet.
You can use setArgument and getArgument to send and receive data from activity to fragment or from fragment to fragment:
In YourReceiveFragment:
public static Fragment newInstance(String data1, String data2, ...) {
Fragment f = new YourReceiveFragment();
Bundle bundle = new Bundle();
bundle.putString(DATA_RECEIVE1, data1);
bundle.putString(DATA_RECEIVE2, data2);
f.setArguments(bundle);
return f;
}
In your activity: Just call it:
Fragment f = YourReceiveFragment.newInstance(yourString1, yourString2);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(R.id.main_container, f).commit();
Then in YourReceiveFragment:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null){
String dataReceive1 = getArguments().getString(DATA_RECEIVE1);
String dataReceive2 = getArguments().getString(DATA_RECEIVE2);
}
}
In case you want to send data from an activity to a fragment in another activity, use interface or an easier way is just pass the data to the activity which contains fragment and from that, send data to fragment.
You can't create a Fragment with startActivity. You need to create the fragment with bundle like this:
ProfileFragment fragment = new ProfileFragment();
Bundle args = new Bundle();
args.putString("name", users.name1);
args.putString("family", users.family1);
fragment.setArguments(args);
// then tell the FragmentManager to attach the fragment
// to the activity
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.your_placeholder, fragment);
ft.commit();
Then in your onCreateView get them with:
String name = getArguments().getString("name", "");
String family = getArguments().getString("family", "");
Please remember that you need to move the return code to the last of onCreateView method and change your code to something like this:
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_profile2, container, false);
TextView pn =view.findViewById(R.id.pn);
...
return view;
}
You can send data with the bundle, that is recommended
To Pass Data from Activity
fragment = new YourFragment();
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
Bundle bundle = new Bundle();
bundle.putString("key", "value");
fragment.setArguments(bundle);
fragmentManager.beginTransaction().replace(R.id.container, fragment).commit();
}
To receive data from Fragment
String var = getArguments().getString("value");

Pass data from Firebase from one fragment to another

I'm trying to pass a CategoryID from Firebase from one fragment to another
using an ImageView Click but my app crashes when an ImageView is clicked.
Here is my code;
MenuFragment.java
FirebaseRecyclerAdapter<Category, MenuViewHolder> adapter;
viewHolder.setItemClickListener(new ItemClickListener() {
#Override
public void onClick(View view, int position, boolean isLongClick) {
CarListFragment cfragment= new CarListFragment ();
Bundle bundle = new Bundle();
bundle.putString("CategoryID",adapter.getRef(position).getKey());
cfragment.setArguments(bundle);
getFragmentManager().beginTransaction()
.replace(R.id.frame_main, cfragment, cfragment.getTag())
.addToBackStack(null)
.commit();
}
});
CarListFragment.java
String CategoryID="";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v= inflater.inflate(R.layout.fragment_car_list, container, false);
Bundle bundle = this.getArguments();
if (bundle != null) {
CategoryID=getActivity().getIntent().getStringExtra("CategoryID");
}
if(!CategoryID.isEmpty()&& CategoryID!=null){
loadCarList(CategoryID);
}
return v;
}
Logcat
Use bundlebecause it has the data
Bundle bundle = this.getArguments();
if (bundle != null) {
CategoryID = bundle.getString("CategoryID");
// ^^^^^^
}
instead of
CategoryID=getActivity().getIntent().getStringExtra("CategoryID");
because getActivity().getIntent() will give you an Intent object which was previously used to start your activity
use this:
CarListFragment cfragment= new CarListFragment ();
Bundle bundle = new Bundle();
bundle.putString("CategoryID", adapter.getRef(position));
cfragment.setArguments(bundle);
getFragmentManager().beginTransaction()
.replace(R.id.frame_main, cfragment, cfragment.getTag())
.addToBackStack(null)
.commit();
get String:
String str = getArguments().getString("my_string");

Passing data by using bundle between tablayout

I am using Bundle to passing data from my First TabFragment but it prompts out with the NullPointerException. Error is occur when getArguments() in list_fragments2 in second tab
MainActivity Fragment
list_fragment2 fragment = new list_fragment2();
Bundle b = new Bundle();
b.putString("test","text");
fragment.setArguments(b);
Toast.makeText(this, "" + b, Toast.LENGTH_SHORT).show();
SecondActivity Fragment
public class list_fragment2 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View h = inflater.inflate(R.layout.tab2, container, false);
TextView textView = (TextView) h.findViewById(R.id.textView);
Bundle bundle=getArguments();
//your string
if(bundle != null) {
String test = bundle.getString("test");
textView.setText(test);
}
return h;
}
}
Do you actually load your second fragment?
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
list_fragment2 fragment = new list_fragment2();
Bundle b = new Bundle();
b.putString("test","text");
fragment.setArguments(b);
fragmentTransaction.replace(placeholder, fragment);
fragmentTransaction.commit();
I think you can create your instance of list_fragment2 code within list_fragment2. Maybe your codes recreated list_fragment2 many times.
public static list_fragment2 createInstance() {
list_fragment2 fragment = new list_fragment2();
Bundle bundle = new Bundle();
bundle .putString("test","text");
fragment.setArguments(bundle);
return fragment;
}

Android: Bundle NullPointerException

I'm working on an app I need to send some data from ListFragment to ItemFragment. I use bundle but I get nullpointerexception. I should mention that i'm a newbie and this is my first app. so let me know if what I did is wrong or confusing. Here are my codes
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)
---Added---
For some reason, I still get the same error when I tried the answers here except for nguyen's. From what I understand in nguyen's code, I use this
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;
}
I didn't get any error with these codes. The toast in ListFragment does shows the correct value but the toast in ItemFragment always returns 0. what am i missing here??
To put bundle in Fragment you should use a static funtion newInstance(Bundle bundle) in your ItemFragment:
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);
}
And use it you call:
Bundle bundle = new Bundle();
//put data in bundle
ItemFragment itemfrag = ItemFragment.newInstance(bundle);
In ItemFragment, you should write in this way
Bundle bundledData = this.getArguments();
if (getArguments() != null) {
selectedId = bundledData.getLong("selectedId");
}
And you may add Toast inside the if block to check whether the selectedId get displayed or not.
Edited
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();
}
Try edit your code in listFragment to this.
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;
The problem with your code is you passed in a new instance of ItemFragment to openFragment() function instead of the one you created and added with a bundle.
You are creating two instances of the same fragment, setting the arguments on the second one, and showing the first one which doesn't have any arguments. Hence, the NullPointerException when you try to extract argument in onCreateView.
...
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.
...
After hours messing around with the code, trial and error, tried different codes, nguyen's code and the code here https://stackoverflow.com/a/16036693/5563156 gives me the idea. these codes seems to get the job done
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;
}
In MainActivity's 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;
}
In ItemFragment's OnCreateView
Bundle args = getArguments();
if (args != null && args.containsKey("selectedId")) {
selId = args.getLong("selectedId");
}
Thanks to everyone who posted their codes! Appreciate the help.

Both If-else statement executing when checking Bundle arguments

In my Android app I'm replacing a Fragment passing an int as argument:
Bundle bundle = new Bundle();
MyFragment fragment = new MyFragment ();
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
bundle.putInt("id", myId);
fragment.setArguments(bundle);
ft.addToBackStack(null).replace(R.id.placeholder, fragment).commit();
Inside MyFragment, I'm checking if this Bundle is null:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_my, container, false);
Bundle args = this.getArguments();
if(args != null) {
Log.d(TAG, "args: "+args);
}
else {
Log.d(TAG, "no args: "+args);
}
return v;
}
My Logcat result:
args: Bundle[{id=1}]
no args: null
Why both if and else are executing?
Why both if and else are executing?
they are probably two different transactions. One that you committed programmatically, the other is probably declared in the layout of hosting activity

Categories

Resources