Working on an app that included 3 fragments. I want to retain data in the FragmentA when the user decides to switch back to FragmentA from FragmentB or FragmentC via BottomNavigationView.
My code works great with changing screen orientation, but for some reason it wont retain data on fragment change.
For testing, I've used only one EditText that should retain data from string.
MainActivity
public class MainActivity extends AppCompatActivity implements
BottomNavigationView.OnNavigationItemSelectedListener {
Fragment Frag = new Fragment();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView navigation = findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(this); // mOnNavigationItemSelectedListener
if (savedInstanceState != null)
{
Frag = getSupportFragmentManager().getFragment(savedInstanceState, "Frag");
}
else
loadFragment(new FragmentA());
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
Fragment fragment = null;
int i = menuItem.getItemId();
if (i == R.id.fragmentA) {
fragment = new FragmentA();
} else if (i == R.id.fragmentB) {
fragment = new FragmentB();
} else if (i == R.id.fragmentC) {
fragment = new FragmentC();
}
return loadFragment(fragment);
}
private boolean loadFragment(Fragment fragment)
{
if (fragment != null)
{
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, fragment).commit();
Frag = fragment;
return true;
}
return false;
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getSupportFragmentManager().putFragment(outState, "Frag", Frag);
}
}
FragmentA
public class FragmentA extends Fragment {
EditText editText;
String string;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null)
{
string = savedInstanceState.getString("Text", "");
}
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
// return super.onCreateView(inflater, container, savedInstanceState);
LayoutInflater layoutInflater = getActivity().getLayoutInflater();
View view = layoutInflater.inflate(R.layout.fragmentA, container, false);
editText = view.findViewById(R.id.centerText);
editText.setText(string);
return view;
}
#Override
public void onSaveInstanceState(#NonNull Bundle outState) {
super.onSaveInstanceState(outState);
string = editText.getText().toString();
outState.putString("Text", string);
}
}
I want that editText retains data when user switches back to FragmentA from FragmentB or FragmentC.
I've been struggling with this problem for some time now, trying different methods with no luck.
Either you can keep the references to your fragments, instead of creating new ones every time like you do here:
if (i == R.id.fragmentA) {
fragment = new FragmentA();
} else if (i == R.id.fragmentB) {
fragment = new FragmentB();
} else if (i == R.id.fragmentC) {
fragment = new FragmentC();
}
You could also use a ViewPager which allows you not only to swipe in-between the screens, but to set viewPager.setOffscreenPageLimit(i); which means that fragments will not be recreated unless they're too far off screen.
Here is your mistake
if (i == R.id.fragmentA) {
fragment = new FragmentA();
} else if (i == R.id.fragmentB) {
fragment = new FragmentB();
} else if (i == R.id.fragmentC) {
fragment = new FragmentC();
}
On click you create new fragment instance
Thank you for your replies.
This is what I changed. It is now working although I'm not sure if that's the elegant way to solve this problem. Data now retains in EditText while navigating back to FragmentA.
MainActivity
public class MainActivity extends AppCompatActivity implements
BottomNavigationView.OnNavigationItemSelectedListener {
Fragment Frag = new Fragment();
Fragment FragmentA;
Fragment FragmentB;
Fragment FragmentC;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView navigation = findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(this); // mOnNavigationItemSelectedListener
FragmentA = new FragmentA();
FragmentB = new FragmentB();
FragmentC = new FragmentC();
if (savedInstanceState != null)
{
Frag = getSupportFragmentManager().getFragment(savedInstanceState, "Frag");
}
else
loadFragment(FragmentA);
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
Fragment fragment = null;
int i = menuItem.getItemId();
if (i == R.id.fragmentA) {
fragment = FragmentA;
} else if (i == R.id.fragmentB) {
fragment = FragmentB;
} else if (i == R.id.fragmentC) {
fragment = FragmentC;
}
return loadFragment(fragment);
}
private boolean loadFragment(Fragment fragment)
{
if (fragment != null)
{
getSupportFragmentManager().beginTransaction().hide(FragmentA).commit();
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, fragment).commit();
getSupportFragmentManager().beginTransaction().show(fragment).commit();
Frag = fragment;
return true;
}
return false;
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getSupportFragmentManager().putFragment(outState, "Frag", Frag);
}
}
Related
After following a couple of Youtube tutorials (eg https://www.youtube.com/watch?v=tPV8xA7m-iw) I was able to build an Activity with a BottomNavigationView, that switches between three different fragments.
I'm not sure if this is the best method to achieve my goals. I need three screens, one of which (ReportFragment) will have user entered data that I wish to remaining place as the user switches between fragments.
The difficulty I am having is also retaining the Fragment data on an orientation change.
Here is one of the Fragment codes, I have implemented onSavedInstanceState to recall the data the user has entered and it seems to work okay:
public class ReportFragment extends Fragment {
EditText textCheck;
EditText textCheck2;
EditText textCheck3;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_report, null);
textCheck = view.findViewById(R.id.editName);
textCheck2 = view.findViewById(R.id.editHaz);
textCheck3 = view.findViewById(R.id.editNotes);
if (savedInstanceState != null) {
textCheck.setText(savedInstanceState.getString("name"));
textCheck2.setText(savedInstanceState.getString("haz"));
textCheck3.setText(savedInstanceState.getString("notes"));
}
return view;
}
#Override
public void onSaveInstanceState (Bundle outState)
{
super.onSaveInstanceState(outState);
outState.putString("name", textCheck.getText().toString());
outState.putString("haz", textCheck2.getText().toString());
outState.putString("notes", textCheck3.getText().toString());
}
}
Here is the Activity Code:
public class FeedActivity extends AppCompatActivity
implements BottomNavigationView.OnNavigationItemSelectedListener {
private HomeFragement frag1;
private ReportFragment frag2;
private MapFragement frag3;
BottomNavigationView navigation;
private static final String TAG = "FeedActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_feed);
navigation = findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(this);
if (savedInstanceState == null) {
frag1 = new HomeFragement();
frag2 = new ReportFragment();
frag3 = new MapFragement();
loadFragment(frag1);
}
}
private boolean loadFragment(Fragment fragment) {
if (fragment != null) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, fragment)
//.addToBackStack(null)
.commit();
return true;
}
return false;
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment fragment = null;
switch (item.getItemId()) {
case R.id.navigation_home:
fragment = frag1;
break;
case R.id.navigation_camera:
fragment = frag2;
break;
case R.id.navigation_map:
fragment = frag3;
break;
}
return loadFragment(fragment);
}
}
I have tried a couple of ways in an attempt to retain the original Fragment, one being onSavedInstanceState, as per other suggestions on Stack Overflow. However during execution I receive an error regarding a null reference to navigation:
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("opened_fragment", navigation.getSelectedItemId());
}
as well as using the following code up in the OnCreate Method in in the if(onSavedInstanceState == null) statement:
navigation.setSelectedItemId(savedInstanceState.getInt("opened_fragment"));
The app currently correctly switches between the three fragments and retains the data as it needs to, until an orientation change occurs. The displayed fragment reverts back to frag1, and can no longer switch between fragments (I'm guessing it is something to do with the setOnNavigationItemSelectedListener??).
I am new to Android development.
EDIT: Now using a ViewPager which handles the the issues above
I believe I have found a solution myself. It appears to work, and give the functionality I need. However I would love some feedback from any experts as to whether it is the right solution.
The solution uses the fragment 'tag' assigned when using getSupportFragmentManager().replace, and checks if there has been a previous version of the fragment loaded. I'm not confident my logic in onNavigationItemSelected() is great but would love any feedback/criticism
Updated FeedActivity.Java:
public class FeedActivity extends AppCompatActivity
implements BottomNavigationView.OnNavigationItemSelectedListener {
private ReportFragment frag2;
private MapFragement frag3;
private HomeFragement frag1;
BottomNavigationView navigation;
private static final String TAG = "FeedActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_feed);
navigation = findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(this);
if(savedInstanceState==null) {
frag1 = new HomeFragement();
frag2 = new ReportFragment();
frag3 = new MapFragement();
}
loadFragment(frag1, "home");
}
private boolean loadFragment(Fragment fragment, String tagID){
if(fragment != null){
getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left)
.replace(R.id.fragment_container, fragment, tagID)
.addToBackStack(null)
.commit();
return true;
}
return false;
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment fragment = null;
String tagID = null;
switch(item.getItemId()){
case R.id.navigation_home:
Fragment cachedFragment1 = getSupportFragmentManager().findFragmentByTag("home");
if (cachedFragment1 != null){
fragment = cachedFragment1;
}
else{
fragment = new HomeFragement();
}
tagID = "home";
break;
case R.id.navigation_camera:
Fragment cachedFragment2 = getSupportFragmentManager().findFragmentByTag("cam");
if (cachedFragment2 != null){
fragment = cachedFragment2;
}
else{
fragment = new ReportFragment();
}
tagID = "cam";
break;
case R.id.navigation_map:
Fragment cachedFragment3 = getSupportFragmentManager().findFragmentByTag("map");
if (cachedFragment3 != null){
fragment = cachedFragment3;
}
else{
fragment = new MapFragement();
}
tagID = "map";
break;
}
return loadFragment(fragment, tagID);
}}
In myfragment class witch extends Fragment I'm finding object reference in onCreateView method
private static final String TAG = "CloadLab";
private Cloud dCloud;
private EditText dNameText;
public String dNameHolder = "";
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
UUID dreamId = (UUID)getArguments().getSerializable(EXTRA_DREAM_ID);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getActivity().setTitle("Add new");
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup parent, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.fragment_add,parent,false);
dNameText = (EditText) v.findViewById(R.id.dream_name);
return v;
}
public void SaveDream (){
dNameHolder = dNameText.getText().toString();
if (dNameText != null) {
Log.e(TAG,"not null");
}else if (dNameText == null){
Log.e(TAG,"null");
}
}
}
which works fine if I use it within onCreateView method, but for example I want to use dNameText in this method which is in same class
public void SaveDream (){
dNameHolder = dNameText.getText().toString();
}
and now it has null object reference how can I fix that and how can I set references through whole class?
I'm calling this SaveDream() method from Activity which holds this Fragment
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_favorite:
AddFragment mActivity= new AddFragment();
mActivity.SaveDream();
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
Every Activity extends SingleFragmentActivity and has these methods in it
private AddFragment mFragment;
#Override
protected Fragment createFragment() {
UUID dreamId = (UUID)getIntent()
.getSerializableExtra(AddFragment.EXTRA_DREAM_ID);
return AddFragment.newInstance(dreamId);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
//setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.action_bar_menu,menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_favorite:
// AddFragment mActivity= new AddFragment();
// mActivity.SaveDream();
//finish();
mFragment = new AddFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(android.R.id.content, mFragment);
fragmentTransaction.commit();
mFragment.SaveDream();
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
SingleFragmentActivity
protected abstract Fragment createFragment();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragmentContainer);
// getSupportActionBar().setDisplayHomeAsUpEnabled(false);
if (fragment == null){
fragment = createFragment();
fm.beginTransaction()
.add(R.id.fragmentContainer, fragment)
.commit();
}
}
You are calling SaveDream method on a new instance of the fragment, not the one which is loaded right now at
AddFragment mActivity= new AddFragment();
mActivity.SaveDream();
Because the view is not created on the new instance (view is created while loading) and you are getting null for EditText. You should keep the loaded instance globally and call the method on that instance.
Follow these steps.
Step 1: Create a class level variable
private AddFragment mFragment;
Step 2: Load Fragment like this
mFragment = new AddFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(android.R.id.content, mFragment);
fragmentTransaction.commit();
Step 3: Call method like this
mFragment.SaveDream();
Update
Update method like this
#Override
protected Fragment createFragment() {
UUID dreamId = (UUID)getIntent()
.getSerializableExtra(AddFragment.EXTRA_DREAM_ID);
mFragment = AddFragment.newInstance(dreamId);
return mFragment;
}
and
case R.id.action_favorite:
mFragment.SaveDream();
return true;
I wrote android code using fragments (Im a newbe) and i want when fragments switched to put some text in the text view. my fragments are making the switch (like intent) but theange text doesn't change. here is the code:
public class Map_Frag extends Fragment {
---interface---
Communicator callback;
TextView tv;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.frag_map, container, false);
tv = (TextView)v.findViewById(R.id.textView);
return v;
}
#Override
public void onStart() {
super.onStart();
Bundle bundle = getArguments();
if (bundle != null) {
if (bundle.getBoolean("str1"))
changTextToWalla1("str1",bundle.getInt("x"));
}
}
public void changTextToWalla1(String str1, int x) {
switch (x){
case 1:
tv.setText("number one");
break;
case 2:
tv.setText("number two");
break;
}
}
}
/*
if (bundle != null) {
if (bundle.getBoolean("button1"))
changTextToWalla1("Selected", bundle.getInt("num"));
}
}
---control class--
public class Control_Frag extends Fragment {
Communicator callback;
private Button button1;
private Button button2;
#Nullable
#Override
public void onAttach(Context context){
super.onAttach(context);
callback= (Communicator) context;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.frag_control,container,false);
button1 = (Button)v.findViewById(R.id.button_1);
button2 = (Button)v.findViewById(R.id.button_2);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
callback.button1Clicked("button1", 1);
}
});
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
callback.button2clicked("button2", 2);
}
});
return v;
}
----communicator---
public interface Communicator {
//here i write the functions that im going to use in the project -
//all the functions that move from one fragmant to another
public void button1Clicked (String str1,int x);
public void button2clicked (String str2,int x);
}
-----main---
public class MainActivity extends FragmentActivity implements Communicator{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (findViewById(R.id.small_device) != null) {
Control_Frag cf = new Control_Frag();
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().add(R.id.small_device, cf , "cf").addToBackStack("cf").commit();
// In small device it will show only Control_Frag to begin with
}
}
#Override
public void button1Clicked(String str1, int x) {
//When button 1 is pressed - change text to walla 1
// Identifying Map_Frag in Fragment Manager
Map_Frag ma = (Map_Frag) getSupportFragmentManager().findFragmentById(R.id.frag_content);
// TABLET
if( ma != null){
ma.changTextToWalla1(str1 ,x);
}
else {
ma = new Map_Frag();
Bundle bundle = new Bundle();
bundle.putBoolean(str1, true);
bundle.putInt(str1 ,x);
ma.setArguments(bundle);
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().replace(R.id.small_device,ma,"sadf").addToBackStack("sadf").commit();
}
}
#Override
public void button2clicked(String str2, int x) {
Map_Frag ma = (Map_Frag)getSupportFragmentManager().findFragmentById(R.id.frag_content);
if (ma != null) {
ma.changTextToWalla1(str2, x);
}else{
ma = new Map_Frag();
Bundle bundle = new Bundle();
bundle.putBoolean(str2, true);
bundle.putInt(str2, x);
ma.setArguments(bundle);
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().replace(R.id.small_device,ma,"asd").addToBackStack("asd").commit();
}
}
}
I could use some help to get it done
Why don't you create a separate fragment xml with the design you want and just call the fragment when a user decides to switch between them.
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
fragment = new Fragment1();
break;
case 1:
fragment = new Fragment2();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, fragment).commit();
}
}
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.title_section1);
break;
case 2:
mTitle = getString(R.string.title_section2);
break;
case 3:
mTitle = getString(R.string.title_section3);
break;
}
}
I have a problem and the solutions I've found did not work for me (check for null etc.).
I have a simple activity which hosts 2 fragments in landscape mode and 1 framelayout in portrait mode. When I change the orientation of the device and then change it back, the click handler is not working (getActivity() in DetailFragment is null).
Here is my code so far:
//UserListActivity.java
public class UserListActivity extends AppCompatActivity implements UserListFragment.OnUserListSelectedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_list);
// Check whether the activity is using the layout version with
// the fragment_container FrameLayout. If so, we must add the first fragment
if (findViewById(R.id.fragment_container) != null) {
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
if (savedInstanceState != null) {
return;
}
UserListFragment fragment = new UserListFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.fragment_container, fragment, "");
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.commit();
}
}
#Override
public void onUserListSelected(User selectedUser) {
UserDetailFragment userDetailFragment = (UserDetailFragment) getSupportFragmentManager().findFragmentById(R.id.user_detail_fragment);
if (userDetailFragment != null) {
// If detail frag is available, we're in two-pane layout...
userDetailFragment.updateSelectedView(selectedUser);
} else {
// Otherwise, we're in the one-pane layout and must swap frags...
//create detailFragment
UserDetailFragment newFragment = new UserDetailFragment();
Bundle args = new Bundle();
args.putString(UserDetailFragment.ARG_SELECTED_USER, new Gson().toJson(selectedUser));
newFragment.setArguments(args);
//replace fragment
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, newFragment, "");
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
}
}
//UserListFragment.java
public class UserListFragment extends ListFragment implements AdapterView.OnItemClickListener {
private OnUserListSelectedListener mCallback;
private User[] users;
public interface OnUserListSelectedListener {
void onUserListSelected(User selectedUser);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.user_list_fragment, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (users == null) {
getAllUsers();
} else {
setAdapter();
}
getListView().setOnItemClickListener(this);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (OnUserListSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnUserListSelectedListener");
}
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mCallback.onUserListSelected(users[position]);
}
private void setAdapter() {
setListAdapter(new UserListAdapter(getActivity(), R.layout.user_list_row, users));
}
private void getAllUsers() {
try {
//...
//Async webCall using volley
//...
users = tmp.getUsers().toArray(new User[tmp.getUsers().size()]);
setAdapter();
//...
}
}
//UserDetailFragment.java
public class UserDetailFragment extends Fragment {
final public static String ARG_SELECTED_USER = "selectedUser";
private User mSelectedUser;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (savedInstanceState != null) {
mSelectedUser = new Gson().fromJson(savedInstanceState.getString(ARG_SELECTED_USER), User.class);
}
return inflater.inflate(R.layout.user_detail_fragment, container, false);
}
#Override
public void onStart() {
super.onStart();
Bundle args = getArguments();
if (args != null) {
updateSelectedView(new Gson().fromJson(args.getString(ARG_SELECTED_USER), User.class));
} else {
updateSelectedView(null);
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(ARG_SELECTED_USER, new Gson().toJson(mSelectedUser));
}
public void updateSelectedView(User selectedUser) {
//??? WHY IS GETACTIVITY() AFTER CHANGE OF ORIENTATION NULL ???
if (getActivity() != null) {
TextView textUserName = (TextView) getActivity().findViewById(R.id.textUserName);
TextView textUserEmail = (TextView) getActivity().findViewById(R.id.textUserEmail);
if (selectedUser != null) {
textUserName.setText(selectedUser.getName());
textUserEmail.setText(selectedUser.getEmail());
mSelectedUser = selectedUser;
} else {
textUserName.setText(null);
}
}
}
}
UserDetailFragment userDetailFragment = (UserDetailFragment) getSupportFragmentManager().findFragmentById(R.id.user_detail_fragment);
Creates a new instance of fragment.
if (findViewById(R.id.fragment_container) != null) {
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
if (savedInstanceState != null) {
return;
}
UserListFragment fragment = new UserListFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.fragment_container, fragment, "");
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.commit();
}
is reusing the old instance of fragment .
Therefore, use getFragmentByTag() and dont keep the tag empty string (""), while calling .add
I have a FragmentActivity in my android application.
I use a viewPager to insert tabs in the activity. So I have this code. It works.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_clienti);
Bundle extras = getIntent().getExtras();
if (extras != null) {
String datas= extras.getString("Cliente");
if (datas!= null) {
System.out.println("pippo");
}
}
TabAdapter = new DemoCollectionPagerAdapter(getSupportFragmentManager());
Tab = (ViewPager)findViewById(R.id.pager);
Tab.setOnPageChangeListener(
new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar = getActionBar();
actionBar.setSelectedNavigationItem(position); }
});
Tab.setAdapter(TabAdapter);
actionBar = getActionBar();
//Enable Tabs on Action Bar
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.TabListener tabListener = new ActionBar.TabListener(){
#Override
public void onTabReselected(android.app.ActionBar.Tab tab,
FragmentTransaction ft) {
// TODO Auto-generated method stub
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
Tab.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(android.app.ActionBar.Tab tab,
FragmentTransaction ft) {
// TODO Auto-generated method stub
}};
//Add New Tab
actionBar.addTab(actionBar.newTab().setText("Scheda Cliente").setTabListener(tabListener));
actionBar.addTab(actionBar.newTab().setText("Conto Cliente").setTabListener(tabListener));
apriConnessioneDB();
}
This is the class FragmentStatePagerAdapter
public class DemoCollectionPagerAdapter extends FragmentStatePagerAdapter {
public DemoCollectionPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
switch (i) {
case 0:
//Fragement for Android Tab
return new infoCliente();
case 1:
//Fragment for Ios Tab
return new infoCliente();
case 2:
//Fragment for Windows Tab
return new infoCliente();
}
return null;
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
return "OBJECT " + (position + 1);
}
}
This is the class Fragment:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.view_infocliente, container, false);
if(savedInstanceState!=null){
//String tmp = savedInstanceState.getString("myKey");
//TextView mTabHost = (TextView) findViewById(android.R.id.labelRagioneSociale);
System.out.println("PIPPPPPPPPPPPPPPPPPPPPPP");
}
TextView btn=(TextView) view.findViewById(R.id.labelRagioneSociale5);
btn.setText("pippo");
return view;
}
Now I want to know How I can pass a parameter to infoCliente class.
In the onCreate method of first class I have this:
String datas= extras.getString("Cliente");
I want pass this parameter to fragment class.
Bundle bundle = new Bundle();
bundle.putInt("battery", bat);
MyFragment fragment=new MyFragment();
fragment.setArguments(bundle);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(R.id.fragment_container,fragment);
ft.commit();
Then in onCreate() method of the fragment:
Bundle bundle=getArguments(); int mLabel = bundle.getInt("battery",0);
Define an interface in your Fragment, for example
public interface FragmentCallback {
onSomethingHappend(String param);
}
Implement the interface in your Activity.
Then, when you want to call the callback, do something like this:
FragmentCallback callback = (FragmentCallback) getActivity();
callback.onSomethingHappened(string);