I keep getting null pointer exception on my getArguments(); - android

From a list, the user can click and item and a fragment will inflate showing the data for the clicked item, where the user also can edit that data and click save to save the edited data.
But from the screen that contains the list is also an add button if the user wants to create a new object.
When the user clicks on an item from the list, a newInstance(..); is called
and in the Fragments onCreateView(); I initilize all variables for that clicked item in the different views. But that is not working well because I keep getting:
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.os.Bundle.getInt(java.lang.String, int)' on a null object reference
newInstance is called from the RecyclerView Adapter onClick():
public static CreateTrainingFragment newInstance(ItemModel itemModel) {
bundle = new Bundle();
bundle.putInt(SB_DURATION, itemModel.getDuration());
bundle.putInt(SB_DISTANCE, itemModel.getDistance());
CreateTrainingFragment createTrainingFragment = new CreateTrainingFragment();
createTrainingFragment.setArguments(bundle);
return createTrainingFragment;
}
Here I use getArguments(); and feed the arguments into Views:
Would the default 0 variable not automatically be inserted into my sbduration.setProgress(); if the argument dont exist?
private void initArgumentsData() {
sbduration.setProgress(getArguments().getInt(SB_DURATION, 0));
sbDistance.setProgress(getArguments().getInt(SB_DISTANCE, 0));
txtduration.setText(getArguments().getInt(SB_DURATION, 0) + " min");
txtDistance.setText(getArguments().getInt(SB_DISTANCE, 0) + " km");
}
Here is how my Views is created and where I use InitArgumentData();
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.createtraining_layout, container, false);
sbduration = (SeekBar) v.findViewById(R.id.seekbar_time);
sbDistance = (SeekBar) v.findViewById(R.id.seekbar_distance);
txtduration = (TextView) v.findViewById(R.id.time_value);
txtDistance = (TextView) v.findViewById(R.id.distance_value);
sbduration.setMax(100);
sbDistance.setMax(50);
initArgumentsData();
}
From RecyclerView I start a new fragment instance like this:
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ItemModel itemModel = realm.getDefaultInstance().where(ItemModel.class).equalTo("timestamp",list.get(getAdapterPosition()).getTimestamp()).findFirst();
CreateTrainingFragment createTrainingFragment = CreateTrainingFragment.newInstance(itemModel, true);
fragmentManager.beginTransaction().replace(R.id.navdrawer_maincontainer,createTrainingFragment).addToBackStack(null).commit();
}
});
From the add button the Fragment is started like this:
addbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getFragmentManager().beginTransaction().replace(R.id.navdrawer_maincontainer,new CreateTrainingFragment()).addToBackStack(null).commit();
}
});

getFragmentManager().beginTransaction().replace(R.id.navdrawer_maincontainer,new CreateTrainingFragment()).addToBackStack(null).commit();
Here, you're using new CreateTrainingFragment(). Hence, you're not getting the bundle since there is no bundle attach to it. You should call the newInstance method first to get the an object of CreateTrainingFragment and then put it on replace.
ItemModel itemModel = realm.getDefaultInstance().where(ItemModel.class).equalTo("timestamp",list.get(getAdapterPosition()).getTimestamp()).findFirst();
CreateTrainingFragment createTrainingFragment = CreateTrainingFragment.newInstance(itemModel, true);
getFragmentManager().beginTransaction().replace(R.id.navdrawer_maincontainer, createTrainingFragment).addToBackStack(null).commit();

How about you just check if the arguments exist?
private void initArgumentsData() {
Bundle args = getArguments();
int duration = 0;
int distance = 0;
if (args != null) {
duration = args.getInt(SB_DURATION, 0);
distance = args.getInt(SB_DISTANCE, 0);
}
sbduration.setProgress(duration);
sbDistance.setProgress(distance);
txtduration.setText(duration + " min");
txtDistance.setText(distance + " km");
}
Even if you did call newInstance on the Fragment, you still would need to provide a new ItemModel to that method.

Related

add new item on list view from two fragments

I am working on alarm app , and I am beginner in android development.
In my app I have 3 tabs "edit", "alarm" and "add alarm" .I have list view in "alarm" tab , and I want in "add alarm" tab add new item in that list , and show it in alarm with old items .
This is my code.
Alarm class
public class Alarm extends Fragment {
public ArrayList<Times> names = new ArrayList<>();
public Alarm() {
// Required empty public constructor
}
ListView list;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_alarm, container, false);;
list = v.findViewById(R.id.listview);
//this demo items .
names.add(new Times( "03:32" , "AM" , "Mon,Wed" , "-Gym Time"));
names.add(new Times( "07:09" , "AM" , "Wed , Mon" , "-Home Time"));
names.add(new Times( "12:00" , "AM" , "Tuh" , "-Gym Time"));
names.add(new Times( "03:36" , "AM" , "Sun,Tue,Wed" , "-Gym Time"));
names.add(new Times( "05:32" , "AM" , "Wed , Mon" , "-Home Time"));
names.add(new Times( "03:52" , "AM" , "Mon" , "-Gym Time"));
names.add(new Times( "08:42" , "AM" , "Sun,Tue,Wed" , "-Gym Time"));
names.add(new Times( "10:22" , "AM" , "Wed , Mon" , "-Gym Time"));
myAdapter adapter = new myAdapter(getContext(), R.layout.custom_list_alarm , names);
Log.e("hi", "onCreateView: " + getContext() );
list.setAdapter(adapter);
return v;
}
}
and here myAdapter.java
public class myAdapter extends BaseAdapter {
private Context c;
Fragment fr ;
private int res ;
private ArrayList<Times> time;
public myAdapter() {
}
public myAdapter(Context c , int res , ArrayList<Times> time)
{
this.c = c;
this.res = res;
this.time = time;
}
public void addAlarm(Times times)
{
this.time.add(times);
}
#Override
public int getCount() {
return time.size();
}
#Override
public Times getItem(int position) {
return time.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if(v == null)
{
v = LayoutInflater.from(c).inflate(res , null , false);
}
TextView tv_name = v.findViewById(R.id.textView);
TextView tv_name2 = v.findViewById(R.id.textView2);
TextView tv_name3 = v.findViewById(R.id.textView3);
TextView tv_name4 = v.findViewById(R.id.textView4);
Times t = getItem(position);
tv_name.setText(t.getTime());
tv_name3.setText(t.getDay());
tv_name2.setText(t.getDays());
tv_name4.setText(t.getSubject());
return v;
}
}
Add Alarm class
public class Add extends Fragment {
public Add() {
// Required empty public constructor
}
private TimePicker timePicker ;
private TextView tv ;
private Button add ;
private EditText label;
private String format = "";
public String subject = "";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_add, container, false);
tv = (TextView) v.findViewById(R.id.textView5);
timePicker = (TimePicker) v.findViewById(R.id.datePicker1);
label = (EditText) v.findViewById(R.id.subject) ;
add = (Button) v.findViewById(R.id.addAlarm);
Log.e("hi2", "addNewAlarm: " + subject );
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addNewAlarm();
}
});
return v;
}
public void addNewAlarm()
{
subject = label.getText().toString();
int hour = timePicker.getHour();
//int minute = timePicker.getCurrentMinute();
if (hour == 0) {
hour += 12;
format = "AM";
} else if (hour == 12) {
format = "PM";
} else if (hour > 12) {
hour -= 12;
format = "PM";
} else {
format = "AM";
}
Times alarm = new Times(String.valueOf(hour), String.valueOf(format), "Test", String.valueOf(subject));
myAdapter test = new myAdapter();
test.addAlarm(alarm);
//tv.setText(String.valueOf(hour + subject )+ subject ) ;
}
}
You will need to do 2 things. The first one is the one you are directly answering, and the second one is the one you have already been suggested (storing them).
For storing, if you are doing something really simple, you could do so with SharedPreferences. So you store (alarm_1_time, "00:00) (alarm_1_name, "my name") for each alarm. Check this and this. Otherwise you can try more complex methods (maybe 'Room', which I have not tried out, but some fellow user is suggesting).
For adding to the list view, you need to:
Firstly, pass from one fragment to another one: as stated here. You basically need to do it through an activity.
Often you will want one Fragment to communicate with another, for
example to change the content based on a user event. All
Fragment-to-Fragment communication is done through the associated
Activity. Two Fragments should never communicate directly.
Source here
Then, to do so:
step 1. Send the data from the new alarm
In add fragment:
Intent intent = new Intent(getActivity().getBaseContext(), YourActivity.class); // activity that hosts the fragments
intent.putExtra("name", alarm_name);
// you can pass as many as you want (labels, names, times, colours, repeating, active, etc.)
// for example:
// intent.putExtra("time", alarm_time);
getActivity().startActivity(intent);
step 2. Receive the data from the new alarm in the activity
In the activity that hosts the fragments:
Intent intent = getIntent();
String my_alarm_name = intent.getStringExtra("name");
Step 3. now from activity, we send it to the fragment:
Bundle bundle = new Bundle();
bundle.putString("alarm", my_alarm_name);
// do the same for all other info (such as time, repetition, etc.) similarly
// now set Fragmentclass Arguments
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);
Step 4. receive in fragment in Fragment onCreateView method:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String strtext=getArguments().getString("message");
return inflater.inflate(R.layout.fragment, container, false);
}
Here you have an example of this method with all the code. An alternative way is through interfaces, as stated here; here you have a question regarding this.
On second place, add new element to list view in the alarms fragment. Here you have a question with more information regarding this, and here a post with a more detailed explanation.
names.add(new_alarm) // append the new alarm to the list you have
adapter.notifyDataSetChanged(); //notify your custom adapter so that it "refreshes"

Listview not showing updated value

I have four fragments in a tab layout. In one of the fragments, I am displaying 10 notes in a listview. In addition to that, I am giving the user the option to add new notes using a dialog box. So, on adding a new note, the listview gets refreshed to show the new note as well but when I switch to another tab and then get back to my original tab, the new note is not displayed in the listview. How to solve this problem?
This is my java code:
public class NoteFragment extends Fragment {
ListView lv_notes;
Button btn_newNote;
ArrayList<NotesModel> notesModelArrayList;
private static NotesAdapter notesAdapter;
NotesModel newNote;
public NoteFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_note, container, false);
lv_notes = (ListView)rootView.findViewById(R.id.lv_notes);
btn_newNote = (Button)rootView.findViewById(R.id.btn_newNote);
notesModelArrayList = new ArrayList<>();
for (int i = 1; i <= 10; i++){
notesModelArrayList.add(new NotesModel("Note " + i,"24/05/2017"));
}
notesAdapter = new NotesAdapter(notesModelArrayList, getContext());
lv_notes.setAdapter(notesAdapter);
btn_newNote.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LayoutInflater newNoteInflater = LayoutInflater.from(getContext());
View newNoteView = newNoteInflater.inflate(R.layout.noteprompt,null);
final AlertDialog.Builder noteDialogBuilder = new AlertDialog.Builder(getContext());
noteDialogBuilder.setView(newNoteView);
final EditText et_newNote = (EditText)newNoteView.findViewById(R.id.et_newNote);
noteDialogBuilder.setCancelable(false).setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
newNote = new NotesModel(et_newNote.getText().toString(),LogFragment.day_d + "/" + (LogFragment.month_d + 1) + "/" + LogFragment.year_d);
notesModelArrayList.add(newNote);
notesAdapter = new NotesAdapter(notesModelArrayList, getContext());
lv_notes.setAdapter(notesAdapter);
}
}).setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
AlertDialog newNoteDialog = noteDialogBuilder.create();
newNoteDialog.show();
}
});
return rootView;
}
}
Your problem is caused by the fragment lifecycle. In case that it is destroyed, the new instance of the fragment will not keep the updated list, but the original one. To fix this, you have to save the array:
Save the data when fragment is about to be destroyed:
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArrayList("notesList", notesModelArrayList);
}
And retrieve/create the data when fragment is created:
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
notesModelArrayList = savedInstanceState.getParcelableArrayList("notesList");
} else {
for (int i = 1; i <= 10; i++){
notesModelArrayList.add(new NotesModel("Note " + i,"24/05/2017"));
}
}
}
Beside this, I have 2 things to mention: you should implement Parcelable in the NotesModel class to be able to save them and, this will only work if you don't close the app. If you want a persistent solution, please consider using SharedPreferences.
EDIT - forgot to mention that you should remove the following lines from onCreateView:
notesModelArrayList = new ArrayList<>();
for (int i = 1; i <= 10; i++){
notesModelArrayList.add(new NotesModel("Note " + i,"24/05/2017"));
}
Instead of these 2 lines
notesAdapter = new NotesAdapter(notesModelArrayList, getContext());
lv_notes.setAdapter(notesAdapter);
try calling notesAdapter.notifyDatasetChanged(); inside setPositiveButton onclick.

Refresh fragment listview on Activity back button press

I have a fragment which contains a listview of some items. On click of an item in the list view an Activity is started to view the details about the list view. There is a back button on the Activity which brings us back to the fragment page. Once the back button is pressed and the activity page closes I want the data to be refreshed in the fragment list view. I have tried onResume() method but it does not refresh the data.
Can someone please help me how to achieve this am pretty new at this.
public class FavCommittee extends Fragment {
public ArrayList<Committee> favCommitteeData = new ArrayList<>();
#Nullable
#Override
public void onResume(){
super.onResume();
final SharedPreferences pref = getContext().getSharedPreferences("MyFav", 0);
final SharedPreferences.Editor editor = pref.edit();
View rootView =getView();
Map<String,?> entries = pref.getAll();
final Set<String> keys = entries.keySet();
int count=0;
for (String key:keys) {
String val = pref.getString(key, null);
String[] store = val.split(":");
if (store[0].equals("committee"))
count=count+1;
}
for (int i=0;i<keys.size();i++) {
String val = pref.getString(Integer.toString(i), null);
if (val != null) {
String[] store = val.split(":");
if (store[0].equals("committee")) {
count = count - 1;
new GetAllCommittees(getContext(), rootView).execute(store[1], Integer.toString(count));
}
}
} final ListView yourListView = (ListView) rootView.findViewById(R.id.house_listview);
yourListView.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
Committee obj = (Committee)yourListView.getItemAtPosition(position);
Intent intent = new Intent(FavCommittee.this.getActivity(), committee_info.class);
intent.putExtra("Committee",obj.getCommittee_id());
startActivity(intent);
}
});
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.house, container, false);
return rootView;
}
When you are transitioning between Fragments, call addToBackStack() as part of your FragmentTransaction:
FragmentTransaction tx = fragmentManager.beginTransation();
tx.replace( R.id.fragment, new MyFragment() ).addToBackStack( "tag").commit();
If you require more detailed control (i.e. when some Fragments are visible, you want to suppress the back key) you can set an OnKeyListener on the parent view of your fragment:
//You need to add the following line for this solution to work,
fragment.getView().setFocusableInTouchMode(true);
fragment.getView().requestFocus();
fragment.getView().setOnKeyListener( new OnKeyListener()
{
#Override
public boolean onKey( View v, int keyCode, KeyEvent event )
{
if( keyCode == KeyEvent.KEYCODE_BACK )
{
return true;
}
return false;
}
} );
getSupportFragmentManager().beginTransaction().add(R.id.fragContainer, new FavCommittee (), FavCommittee .class.getName()).commit();
Try this code.
Put the code where u add your Fragment in Activity

Wrong ListView item is passed by the intent

I am using BackendLess backend service, but my prob is (i guess) more to android/java. So even if u are not familiar with BackendLess, i guess u can help, if u know of course :)
I have there a Fragment that calls and opens a DialogFragment with a ListView.
Using there an iterator to retrieve the data. It brings each column from the data table as an Array.
I set an onClickedItemListener that when item is clicked, it send the value to a TextView in the Fragment it was called from.
The data comes in the wrong order - didnt get how to do a sortBy, that connects to the bigger prob i have there -
There is a column there named "PropertyTypes". It holds 4 strings, which are coming out in the opposite order that i need. I want the "A" first, and get:
"D"
"C"
"B"
"A"
ok, so far no big deal, i guess can be sorted out with a sortBy that i just dont know how to do.
But... what happens is that it sends the wrong value to the TextView, meaning, for example, when i press "C" it set "A" on the TextView and so on, and, when i press the last one, in this case "A", the app is crashing...
What the hell is going on there?? :))
Here is the code -
The DialogFragment code:
public class OptionDialogFragment extends DialogFragment implements
AdapterView.OnItemClickListener {
ListView mylist;
TextView chosenProperty;
TextView presentListItem;
ArrayAdapter adapter;
#Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//mylist.addHeaderView(inflater.inflate(R.layout.option_dialog_header, null, false));
View view = inflater.inflate(R.layout.option_dialog_content, null, false);
mylist = (ListView) view.findViewById(R.id.list);
View headerView = inflater.inflate(R.layout.option_dialog_header, mylist, false);
headerView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dismiss();
}
});
mylist.addHeaderView(headerView);
View footerView = inflater.inflate(R.layout.option_dialog_footer, mylist, false);
footerView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dismiss();
}
});
mylist.addFooterView(footerView);
chosenProperty = (TextView) view.findViewById(R.id.chosenProperty);
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final ArrayList<String> propertyTypes = new ArrayList<String>();
final ArrayList<Integer> numOfRoomies = new ArrayList<Integer>();
Backendless.Data.of(DialogOptions.class).find(new AsyncCallback<BackendlessCollection<DialogOptions>>() {
#Override
public void handleResponse(final BackendlessCollection<DialogOptions> dialogOptions) {
final Iterator<DialogOptions> iterator = dialogOptions.getCurrentPage().iterator();
while (iterator.hasNext()) {
DialogOptions dialogOptionsObject = iterator.next();
propertyTypes.add(dialogOptionsObject.getPropertyTypes());
// numOfRoomies.add( dialogOptionsObject.getNumOfRoomies() );
}
adapter = new ArrayAdapter<String>(getActivity(), R.layout.dialog_option_list_item, R.id.presentListItem, propertyTypes);
mylist.setAdapter(adapter);
mylist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String chosenItem = propertyTypes.get(position);
Intent intent = new Intent();
intent.putExtra("chosenItem", chosenItem);
getTargetFragment().onActivityResult(
getTargetRequestCode(), Activity.RESULT_OK, intent);
dismiss();
}
});
}
#Override
public void handleFault(BackendlessFault fault) {
// TODO: make sure to log the exception, just in case
}
});
}
}
This is the Relevant code in the Fragment that calls the DialogFragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.find_a_place, container, false);
chosenProperty = (TextView) view.findViewById(R.id.chosenProperty);
return view;
}
#Override
public void onViewCreated(final View view, Bundle savedInstanceState) {
final LinearLayout propertTypes = (LinearLayout)view.findViewById(R.id.propertyTypes);
propertTypes.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showDialog(getActivity(), "OptionDialog");
}
});
}
private void showDialog(FragmentActivity activity, String optionDialog) {
android.support.v4.app.FragmentManager manager = getFragmentManager();
DialogFragment dialog = new OptionDialogFragment();
dialog.setTargetFragment(this, 0);
dialog.show(manager, "OptionDialog");
dialog.setCancelable(true);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(requestCode) {
case 0:
if (resultCode == Activity.RESULT_OK) {
if(data!=null){
// set value to your TextView
chosenProperty.setText(data.getStringExtra("chosenItem"));
}
}
break;
}
}
Thanks a lot in advance for any answer!!
Reference :-
https://backendless.com/feature-47-loading-data-objects-from-server-with-sorting/
To Sort while retrieving Object use :-
QueryOptions queryOptions = new QueryOptions();
queryOptions.addSortByOption( "created ASC" );
dataQuery.setQueryOptions( queryOptions );
Use Query as below:-
// fetch restaurants
Backendless.Data.of( Restaurant.class ).find( dataQuery, new AsyncCallback<BackendlessCollection<Restaurant>>(){

Loading order of viewpager in android

Imagine there is a viewpager with 4 page, the 1st and 2nd page are storing the edittext, and the third one need to display the inputed data from 1st and 2nd page.
The problem is , viewpager pre-load the pervious page and next page , if I create the custom adapter like that:
Custom adapter
#Override
public Object instantiateItem(ViewGroup container, int position) {
rootView = (LinearLayout) LayoutInflater.from(ctx).inflate(pages[position], null);
if (position == 0) {
form1(rootView);
} else {
form2(rootView);
}
((ViewPager)container).addView(rootView);
return rootView;
}
Example function form2
private void form2(View rootView){
TextView previous_page = (TextView) rootView.findViewById(R.id.previous_page);
TextView next_page = (TextView) rootView.findViewById(R.id.next_page);
final EditText type = (EditText) rootView.findViewById(R.id.edit_type);
final EditText amount = (EditText) rootView.findViewById(R.id.edit_amount);
final Spinner period = (Spinner) rootView.findViewById(R.id.edit_period);
final EditText name = (EditText) rootView.findViewById(R.id.edit_name);
final EditText phone_no = (EditText) rootView.findViewById(R.id.edit_phone_no);
final EditText email = (EditText) rootView.findViewById(R.id.edit_email);
previous_page.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
viewPager.setCurrentItem(0, true);
top_bar.setImageResource(R.drawable.form_1_header);
}
});
next_page.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String[] input_list = {amount.getText().toString(),name.getText().toString(),phone_no.getText().toString(),email.getText().toString()};
String invalid_msg = check_valid(input_list);
if (invalid_msg.equals("")) {
new FormHandler(ctx,formListener).execute(type.getText().toString(),amount.getText().toString(),period.getSelectedItem().toString(),name.getText().toString(),phone_no.getText().toString(),email.getText().toString());
} else {
Toast.makeText(ctx, invalid_msg ,Toast.LENGTH_LONG).show();
}
}
});
}
Then , for example if I enter the 1st page, it call the instantiateItem 2 times, the position are 0 and 1 , and it called the form1() and the form2(), which I expect only when I enter that page , it call the function of that page . e.g. At 1st page , run form1(), At 2nd page , run form2(). How to fix that? thanks.
Update (1):
It caused a problem, when I enter 2nd tab , it preload the 3rd tab, which call the form3(), so after I input the data in those edittext at 2nd tab, and go to the 3rd tab, it does not call form3() again, so the 3rd tab does not display enter data from 2nd tab (The view was preload and instantiate already)
Update (2):
The page is not a fragment , it is a layout and inflate at the adapter(named "rootview" and the pages array is:)
int[] pages = {R.layout.form_1,R.layout.form_2,R.layout.form_3,R.layout.form_4};
Update (3):
My whole viewpager
private class ViewPageAdapter extends PagerAdapter {
// Declare Variables
public int[] pages;
private LinearLayout rootView;
public ViewPageAdapter(int[] _pages) {
pages = _pages;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == (LinearLayout) object;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
rootView = (LinearLayout) LayoutInflater.from(ctx).inflate(
pages[position], null);
if (position == 0) {
form1(rootView);
} else if (position == 1) {
form2(rootView);
} else if (position == 2) {
form3(rootView);
} else if (position == 3) {
form4(rootView);
}
((ViewPager) container).addView(rootView);
return rootView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((LinearLayout) object);
}
#Override
public int getCount() {
return pages.length;
}
}
You can override the setPrimaryItem method in adapter. this method will give the current displaying object. This may help you.
#Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
if (mobject != object) {
mObject=objet; //mObject is global variable in adapter
//You can update your based on your logic like below
View view == (LinearLayout) object;
form4(view);
}
super.setPrimaryItem(container, position, object);
}
Then , for example if I enter the 1st page, it call the instantiateItem 2 times, the position are 0 and 1 , and it called the form1() and the form2(), which I expect only when I enter that page , it call the function of that page . e.g. At 1st page , run form1(), At 2nd page , run form2(). How to fix that? thanks.
you can not fix that, because of giving better UX to user setOffscreenPageLimit(0); dose not work and the default value is always 1 which means it always preloads your next and previous page.
so after I input the data in those edittext at 2nd tab, and go to the
3rd tab, it does not call form3() again, so the 3rd tab does not
display enter data from 2nd tab (The view was preload and instantiate
already)
you can save your data in SharedPreferaces and read them in onResume method of tab3. in this way you will get correct data from tab2 and tab1.

Categories

Resources