Saving fragmentstate with savedInstanceState - java

saveInstanceState() doesn't work as expected.
I'm trying to read the data so I don't have to do the query again when a user reselects the tab. The fragment is a tab in a actionbar. Everything works properly, I just can't get savedInstanceState to be anything else then NULL, anyone has any idea?
This is my code:
public class SpecsFragment extends Fragment {
private String mText;
private ArrayList<HashMap> result;
private Converter c;
private View fragView;
public SpecsFragment() {
mText = "specs";
c = new Converter();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fragView = inflater.inflate(R.layout.product_info_fragment, container, false);
return fragView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if(savedInstanceState == null) {
Bundle args = getArguments();
int id = Integer.parseInt(args.getString("id"));
String query = "SELECT * FROM products WHERE id = " + id;
try {
ZoekQueryTask zoekQueryTask = new ZoekQueryTask(query);
result = zoekQueryTask.getResults();
}
catch (Exception e) {
Log.e("Afgevangen error", e.getMessage());
}
}
else {
result = new ArrayList();
result.add((c.BundleToHashMap(savedInstanceState)));
}
TextView text = (TextView) fragView.findViewById(R.id.textView1);
text.setText(mText);
text.append("\n\n");
text.append(result.get(0).get("ean").toString());
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState = c.HashmapToBundle(result.get(0));
}
}
Using
savedInstance.putAll(c.HashmapToBundle(result.get(0)));
Still does not work.
savedInstance.putBundle("results", c.HashmapToBundle(result.get(0)));
Doesn't work either, anyone have any idea?
I solved the problem by working around it, instead of trying to store savedInstanceState. I wrote functions to get and set a Bundle from the fragments parent activity, and then get the activity by using:
YourActivity parent = (YourActivity) this.getactivity();
And just call the function for getting and setting a bundle which you write yourself.

I solved the problem by working around it, instead of trying to store savedInstanceState. I wrote functions to get and set a Bundle from the fragments parent activity, and then get the activity by using:
YourActivity parent = (YourActivity) this.getactivity();
And just call the function for getting and setting a bundle which you write yourself

If your Fragment is defined in an XML layout, ensure that you have specified an android:id!

Related

Unable to send Strings from one Fragment to another via Bundles

I am trying to send two strings via a bundle to the next fragment but the app crashes even before I get to the first fragment.
I get this error in the second fragment:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.guessit, PID: 22360
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.os.Bundle.getString(java.lang.String)' on a null object reference
at com.example.android.guessit.GameFlow.FragmentAnswer1.onCreateView(FragmentAnswer1.java:125)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execSingleAction(FragmentManagerImpl.java:1696)
at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:299)
at androidx.fragment.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:259)
at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1244)
at androidx.viewpager.widget.ViewPager.setCurrentItemInternal(ViewPager.java:669)
at androidx.viewpager.widget.ViewPager.setCurrentItemInternal(ViewPager.java:631)
at androidx.viewpager.widget.ViewPager.setCurrentItem(ViewPager.java:612)
at com.example.android.guessit.GameFlow.GameActivity.setViewPager(GameActivity.java:152)
at com.example.android.guessit.GameFlow.FragmentOneCategory$6.onClick(FragmentOneCategory.java:190)
at android.view.View.performClick(View.java:7352)
at android.view.View.performClickInternal(View.java:7318)
at android.view.View.access$3200(View.java:846)
at android.view.View$PerformClick.run(View.java:27800)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7050)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
I know that this means that the string value that I am trying to receive in the second fragment means that there is no value for that string but I don't know where the problem here is because the strings I am trying to send are not null.
This is the code I am using for the bundle in the first fragment (using this in onCreatView):
FragmentAnswer1 frag1 = new FragmentAnswer1();
Bundle args = new Bundle();
args.putString("question_1", question);
args.putString("answer_1", answer);
frag1.setArguments(args);
getFragmentManager().beginTransaction().add(R.id.container, frag1).commit(); // there is a message that says that "beginTransaction" may produce a nullPointer
Here is the code to receive the strings in the second fragment (currently also in onCreateView)
question = getArguments().getString("question_1"); // error is in this line
answer = getArguments().getString("answer_1");
question1.setText(question);
rightAnswer.setText(answer);
I already tried to move the above code into the onStartmethod but I still get the same error. I also tried using this solution but its not working for me. I did not find any other solution or method on how to resolve the problem.
Please let me know if you need more informations. Any help is much appreciated!
I have now found the correct way to send data from one Fragment to another while having a ViewPager. We have to use a ViewModel.
First we have to create a ViewModel, in this case our goal is to send a String from Fragment 1 to Fragment 2. Here is the code for the ViewModel with Getter and Setter method for the String:
public class ViewModelString extends ViewModel {
private MutableLiveData<String> mString = new MutableLiveData<>();
public MutableLiveData<String> getmString() {
return mString;
}
public void setmString(MutableLiveData<String> mString) {
this.mString = mString;
}
}
Then in Fragment 1 from where we want to sent the string we need to first initialize the ViewModel in onCreate.
public class Fragment1 extends Fragment {
private ViewModelString viewModel;
public Fragment1() {
// Required empty public constructor
}
public static Fragment1 newInstance() {
return new Fragment1();
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// initialize ViewModel here
viewModel = ViewModelProviders.of(requireActivity()).get(ViewModelString.class);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
String hello = "hello";
viewModel.setmString(hello);
}
}
Then in the second Fragment we also have to first initialize the viewModel and then create an observer. Here we then take the String that is stored in the ViewModel and set a TextView to its value:
public class Fragment2 extends Fragment {
private ViewModelString viewModel;
public Fragment2() {
// Required empty public constructor
}
public static Fragment2 newInstance() {
return new Fragment2();
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// initialize ViewModel here
viewModel = ViewModelProviders.of(requireActivity()).get(ViewModelString.class);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
TextView textView = findViewById(R.id.yourTextViewId);
// Gets the string
viewModel.getmString().observe(requireActivity(), new Observer<String>() {
#Override
public void onChanged(#Nullable String s) {
textView.setText(s);
}
});
}
...
}
I hope this helps anyone! Please feel free to edit my post.
Use Bundle to send String:
//Put the value
Bundle args = new Bundle();
args.putString("YourKey", "YourValue");
YourFragmentName ldf = new YourFragmentName ();
ldf.setArguments(args);
//Inflate the fragment
getActivity().getSupportFragmentManager().beginTransaction().add(R.id.container, ldf).commit();
In onCreateView of the new Fragment:
//Retrieve the value
Bundle bundle = this.getArguments();
if (bundle != null) {
String value = bundle.getString("YourKey");
}
Use a Bundle. Here's an example:
Fragment fragment = new Fragment();
Bundle bundle = new Bundle();
bundle.putInt("Key", "value");
fragment.setArguments(bundle);
fragmentManager.beginTransaction().replace(R.id.container, frag1).commit()
Bundle has put methods for lots of data types. See this
Then in your Fragment, retrieve the data in onCreate() method like:
Bundle bundle = this.getArguments();
if (bundle != null) {
int myInt = bundle.getString(Key);
}
try this.
var fragment: MainFragment =MainFragment()
val args = Bundle()
args.putString("question_1", "My question")
args.putString("answer_1", "My answer")
fragment.setArguments(args)
fragmentManager.beginTransaction().add(R.id.fragment_content, fragment).commit()

Two way binding Android

Maybe I am missing something small here, but I cannot get my binding to work. I set it up as follow:
public class Toolbar extends Fragment {
//Interaction handlers
//interface for interaction with Activity
public interface ToolBarInteraction{
public void Search(String screenName);
}
private ToolbarBind modelData;
private ToolBarInteraction mListener;
public static Toolbar newInstance() {
return new Toolbar();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentToolbarBinding binding = DataBindingUtil.setContentView(getActivity(), R.layout.fragment_toolbar);
modelData = ToolbarBind.newInstance();
modelData.searchedText.set("Hello");
binding.setModelData(modelData);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
checkMListener();
View view = inflater.inflate(R.layout.fragment_toolbar, container, false);
//get button to set onClick event
Button button = (Button)view.findViewById(R.id.btnSearch);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String hello = modelData.searchedText.get();
}
});
return view;
}
public void OnSearchClicked(View view){
mListener.Search(modelData.searchedText.get());
}
private void checkMListener(){
try{
mListener = (ToolBarInteraction) getActivity();
} catch (ClassCastException ex) {
throw new ClassCastException(getActivity().toString()
+ " must implement the ToolBarInteraction Interface");
}
}
}
Here is the code for ToolbarBind:
public class ToolbarBind extends BaseObservable {
private String _searchText;
public final ObservableField<String> searchedText = new ObservableField<String>();
//factory method
public static ToolbarBind newInstance(){ return new ToolbarBind(); }
}
And in my fragment, I set the binding up as follow, all within the layout tag:
<data>
<variable
name="modelData"
type="Common.CommonObjects.ToolbarBind"/>
</data>
And for binding to property:
<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="Search"
android:text="#={modelData.searchedText}"/>
As can be seen, in the onCreate I set the text to "Hello", but even when the view displays on the phone, the EditText is not populated with this text. When I change the value, and click my button, the value I get back in the event is "Hello", not my new text entered while the app is running.
What am I missing?
The problem with your code is that you set the Activity's content view to something in onCreate(...) but you inflate and use something different in onCreateView(...) as your fragment's view, which gets the model data (not the other one you created in onCreate(...)). I don't know exactly what you try to achieve, but I'm gonna guess that you don't want to change the Activity's content view to something from the fragment, so I'm just gonna show you a variation of what could you use, however, you should change it to whatever pleases you.
Remove onCreate(...) completely then use only onCreateView(...) to inflate the fragment_toolbar layout using data binding:
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
checkMListener();
FragmentToolbarBinding binding = DataBindingUtil.inflate(inflater, R.layout.fragment_toolbar, container, false);
// FIXME you're losing data here; watch out: checking whether savedInstanceState == null is not enough because returning from backstack it will be null
modelData = ToolbarBind.newInstance();
// FIXME modify this so it sets the data from savedInstanceState when configuration changes
modelData.searchedText.set("Hello");
binding.setModelData(modelData);
//get button to set onClick event
binding.btnSearch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String hello = modelData.searchedText.get();
}
});
return binding.getRoot();
}
Watch out for the FIXME parts. You could move the modelData init to onCreate(...) which would save it from the backstack-return thing, however, configuration change will still call onCreate(...) unless you call setRetainInstance(true) on the fragment (do not).

Attempt to invoke virtual method on a null object reference

This is the error i get:
03-11 08:27:48.513: E/AndroidRuntime(23647): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.plan.yeahimin/com.plan.yeahimin.PlanDetailsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.Serializable android.os.Bundle.getSerializable(java.lang.String)' on a null object reference
I understand its due to a variable having a null value but I can't workout why. It looks like it's 'EXTRA_NEW_PLAN' in the getSerializable() method in the DetailsFragment but other than that I don't know. I'm new to Android so forgive me if it's obvious but any help would be greatly appreciated.
Here is my code for the ListFragment;
public class PlanListFragment extends ListFragment {
public final static String TAG = "com.plan.yeahimin.PlanListFragment";
public final static String EXTRA_NEW_PLAN = "com.plan.yeahimin.plan_id";
private Button mAddPlan;
private ArrayList<Plan> mPlansList;
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.empty_view_or_list_view, parent, false);
ListView view = (ListView) v.findViewById(android.R.id.list);
view.setEmptyView(v.findViewById(android.R.id.empty));
mAddPlan = (Button) v.findViewById(R.id.add_a_plan);
mAddPlan.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Log.d(TAG, "add plan clicked");
Plan plan = new Plan();
Log.d(TAG, "new plan created");
PlanArrayList.get(getActivity()).addPlans(plan);
Log.d(TAG, "plan added to mPlansList");
Intent i = new Intent(getActivity(), PlanDetailsActivity.class);
i.putExtra(PlanDetailsFragment.EXTRA_NEW_PLAN, plan.getId());
startActivity(i);
return;
}
});
return v;
}
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
mPlansList = PlanArrayList.get(getActivity()).getPlans();
//ArrayList<Plan> mPlansList = new ArrayList<Plan>();
PlanArrayAdapter paa = new PlanArrayAdapter(mPlansList);
setListAdapter(paa);
}
public class PlanArrayAdapter extends ArrayAdapter<Plan>{
public PlanArrayAdapter(ArrayList<Plan> planList){
super(getActivity(), 0, planList);
}
public View getView(int position, View convertView, ViewGroup parent){
// Get the plan item for this position
Plan plan = getItem(position);
//If layout doesnt exist, inflate one
if(convertView == null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.plan_list_fragment, parent, false);
}
TextView planTitle = (TextView) convertView.findViewById(R.id.plan_title);
planTitle.setText(plan.getTitle());
TextView planDate = (TextView) convertView.findViewById(R.id.plan_date);
planDate.setText(plan.getDate().toString());
return convertView;
}
}
}
and here is my code for the DetailsFragment which opens from add button;
public class PlanDetailsFragment extends Fragment {
private static final String TAG = "com.plan.yeahimin.PlanDetailsFragment";
public static final String EXTRA_NEW_PLAN = "com.plan.yeahimin.plan_id";
private EditText mTitleField;
private Button mDateButton;
private Button mTimeButton;
private EditText mLocationField;
private EditText mAttendeesField;
private EditText mDescriptionField;
private Plan mPlan;
private ArrayList<Plan> mPlansList;
public static PlanDetailsFragment newInstance(UUID planId){
Bundle args = new Bundle();
args.putSerializable(EXTRA_NEW_PLAN, planId);
PlanDetailsFragment f = new PlanDetailsFragment();
f.setArguments(args);
Log.d(TAG, "newInstance created");
return f;
}
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
UUID planId = (UUID)getArguments().getSerializable(EXTRA_NEW_PLAN);
mPlan = PlanArrayList.get(getActivity()).getPlan(planId);
}
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.plan_details_fragment, parent, false);
mTitleField = (EditText)v.findViewById(R.id.plan_title);
mLocationField = (EditText)v.findViewById(R.id.plan_location);
mAttendeesField = (EditText)v.findViewById(R.id.plan_attendees);
mDescriptionField = (EditText)v.findViewById(R.id.plan_description);
mDateButton = (Button)v.findViewById(R.id.plan_date);
mTimeButton = (Button)v.findViewById(R.id.plan_time);
return v;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
inflater.inflate(R.menu.main_to_do, menu);
}
public boolean onOptionsItemSelected(MenuItem item){
switch(item.getItemId()){
case R.id.save_button:
Log.d(TAG, "save button pressed");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
I think you cannot send any arguments to your Fragment with .newInstance(), because this method does not accept any parameters according to the documentation. So even if you have overloaded .newInstance(UUID), the system calls .newInstance() (if calls at all, I have some doubts). Also please be aware that you put the parameter to Intent with .putExtra(), but do not recall it from the Intent.
In fact the right way to send arguments to a Fragment is as follows:
In the caller (usually it is an Activity, but maybe with another Fragment, like in your example, it would also work, I cannot say for sure):
PlanDetailsFragment fragment = new PlanDetailsFragment();
Bundle args = new Bundle();
args.putSerializable(PlanDetailsFragment.TAG_NEW_PLAN, plan.getID());
fragment.setArguments(args);
getFragmentManager().beginTransaction().add(fragment, TAG_DETAILS_FRAGMENT).commit();
In the fragment:
Bundle args = getArguments();
UUID planID = (UUID) args.getSerializable(TAG_NEW_PLAN);
It is not a ready-to-use code, you should adapt it to your classes and variables names, to where your tags are places, etc. The calls of Activity methods may also require some change if you prefer to work from another fragment. It is just an overall description.
My answer applies to the situation when both fragments are inside one activity. Your using of Intents make me have doubts in this, but I do not fully understand it.
You sent the arguments to an Activity(PlanDetailsActivity).
You should send the arguments to a Fragment through newInstance() method.
In your PlainDetailsActivity, you should create the fragment instance like:
UUID uuid = getIntent().getSerializableExtra(PlanDetailsFragment.EXTRA_NEW_PLAN);
PlanDetailsFragment f = PlanDetailsFragment.newInstance(uuid);

Transferring multiple strings between Fragments of the same activity with tags

I am having trouble figuring out how to share data between my two fragments which are hosted on the same activity.
The objective:
I want to transfer string from the the selected position of a spinner and an image url string from a selected list view position from fragment A to fragment B.
The Attempt:
I read the fragments doc on this problem here http://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity
And went ahead an created the following Interface to use betweeen the Fragments and the Host Activity.
public interface OnSelectionListener {
public void OnSelectionListener(String img, String comments );
}
Then I proceeded to implement it in my fragment A's onCreateView method like so:
postList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
ListData link = data.get(position);
String permalink = link.getComments();
String largeImg = link.getImageUrl();
Fragment newFragment = new DetailsView();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
//pass data to host activity
selectionListener.OnSelectionListener(permalink,largeImg);
}
});
And also in the onAttach method
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
selectionListener = (OnSelectionListener)getActivity();
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement onSelectionListener");
}
}
In the Host activity I implemented the interface I wrote and overrided the method like so:
#Override
public void OnSelectionListener(String img, String comments) {
DetailsView detailsView = new DetailsView();
DetailsView dView = (DetailsView)getSupportFragmentManager().findFragmentByTag(detailsView.getCustomTag());
dView.setInformation(img, comments);
}
In Fragment B I set a "tag" the following way
private String tag;
public void setCustomTag(String tag)
{
this.tag = tag;
}
public String getCustomTag()
{
return tag;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setCustomTag("DETAILS_VIEW");
And my thinking is that that the information can be passed to Fragment B by calling this method from the host activity
void setInformation (String info, String img){
RedditDetailsTask detailsTask = new RedditDetailsTask(null,DetailsView.this);
detailsTask.execute(info);
setDrawable(img);
}
What I need:
I want to know how to properly use tags to get this to work, I dont have any fragment id's declared in my xml and rather opted to exchange fragments in a fragment_container.
I also am not sure if this is a good way to pass multiple strings between fragments. I am a newbie programmer so I know my logic probably looks pretty embarrassing but I am trying to do my best learn to do this right. I would appreciate it if you more senior developers can point me in the right direction for doing this.
You don't need to use tags. Take a look at this example. The Activity implements an interface that allows you to talk from Fragment1 back to the Activity, the Activity then relays the information into Fragment2.
I've left out all the android stuff about FragmentManager etc.
interface FragmentListener {
void onTalk(String s1);
}
public class MyActivity extends Activity implements FragmentListener {
Fragment2 fragment2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
// Find fragment2 and init
}
#Override
public void onTalk(String s1) {
fragment2.onListen(s1);
}
private static class Fragment1 extends Fragment {
private FragmentListener communication;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
communication = (FragmentListener) activity;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_one, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// or in an onClick listener
communication.onTalk("blah blah");
}
}
private static class Fragment2 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_two, container, false);
}
public void onListen(String s1) {
Log.d("TADA", s1);
}
}
}
My approach would be, when you get the callback in activity through the OnSelectionListener interface, I would create the Fragment B object and set arguments to it as follows:
#Override
public void OnSelectionListener(String img, String comments) {
DetailsView detailsView = new DetailsView();
Bundle args=new Bundle();
args.putString("img",img);
args.putString("comments",comments);
detailsView.setArguments(args);
//code here to replace the fragment A with fragment B
}
Then in Fragment B's onCreate method you can retrieve the values as follows:
#Override
public void onCreate(Bundle savedInstanceState) {
Bundle args=getArguments();
String img=args.getString("img");
String comments=args.getString("comments");
//do whatever you want to do with the varaibles
}
You could try to make two public static String's in your B fragment.
it Would look like something like this
public static String img;
public static String comment;
The you set the variables before making the transaction to fragment B
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
SecondFragment.img = new String("imgString"); //Making a new string so incase you change the string in bfragment, the values wont change in here
SecondFragment.comment = new String("comment");
// Commit the transaction
transaction.commit();
Then in the onStop(), or onDestroy() - depending on when you want the variables to be null, check this - you set the the static variables to null, so they dont take memory space
public void onDestroy(){
super.onDestroy();
img = null;
comment = null;
}

Android fragment onCreateView() never called

I've been searching for a while now, but I can't seem to find an answer to the following question:
Why does onCreateView never get triggered? This code is the code generated by Android Studio when creating a new MainActivity plus some of the code I wrote.
I want to use setTextConfig(...,...,...) to set the text in the text fields. But I can't seem to get them using findviewbyid(R.id....); because v is always null, even getView(); returns null.
public static class PlaceholderFragment extends Fragment {
private View v;
private EditText etCustomerName, etDeviceID;
private Spinner select;
public PlaceholderFragment() {
super();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
v = inflater.inflate(R.layout.fragment_main, container, false);
return v;
}
public void setTextConfig(String customerName, String selectedOption, int deviceID){
View vv = getView();
//init form controls
etCustomerName = (EditText)vv.findViewById(R.id.etCustomerName);
etDeviceID = (EditText)v.findViewById(R.id.etDeviceId);
select = (Spinner)v.findViewById(R.id.select);
etCustomerName.setText(customerName);
ArrayAdapter adapter = (ArrayAdapter)select.getAdapter();
int index = adapter.getPosition(selectedOption);
select.setSelection(index);
etDeviceID = (EditText)getView().findViewById(R.id.etDeviceId);
etDeviceID.setText(Integer.toString(deviceID), TextView.BufferType.EDITABLE);
}
}
If you need more detailed info, just ask :)

Categories