How to refresh a fragment from an activity in android? - java

I have a floating button in one of my fragments.On click of which an
activity pops up.Now the problem is when I go back from the activity
to the fragment the fragment does not auto refresh.Also I want it to
refresh on back pressed.
Within the fragment I have a refresh button in the action bar on
pressed of which I call a refreshFragment() method.Is there a way in
android that I can call a method from a fragment from within an
activity.
This is my refreshFragment() method code.
public void refreshFragment()
{
Fragment fragment = new BillingFragment();
android.support.v4.app.FragmentManager fragmentMg = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTrans = fragmentMg.beginTransaction();
fragmentTrans.replace(R.id.container_body, fragment, "TABBILLING");
fragmentTrans.addToBackStack(null);
fragmentTrans.commit();
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle("Billing");
//adapter.notifyDataSetChanged();
}
And I call it inside my on create view method as follows :-
((MainActivity)getActivity()).setFragmentRefreshListener(new MainActivity.FragmentRefreshListener()
{
#Override
public void onRefresh() {
refreshFragment();
}
});
I even tried calling displayView() method of my main activity from
another activity by creating an object of MainActivity as follows:-
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
super.onBackPressed();
MainActivity main = new MainActivity();
main.displayView(1);
count = 0;
return true;
But it gave me a null pointer exception.This is my displayView() method.
public void onDrawerItemSelected(View view, int position) {
displayView(position);
}
public void displayView(int position) {
Fragment fragment = null;
String title = getString(R.string.app_name);
switch (position) {
case 0:
fragment = new HomeFragment();
title = getString(R.string.title_home);
break;
case 1:
fragment = new BillingFragment();
title =getString(R.string.title_billing);
break;
case 2:
fragment = new StockViewFragment();
title =getString(R.string.title_stockview);
break;
case 3:
fragment = new BhishiManagementFragment();
title= getString(R.string.title_bhishiview);
break;
case 4:
fragment = new ReportingFragment();
title=getString(R.string.title_reporting);
break;
case 5:
fragment = new VendorManagementFragment();
title=getString(R.string.title_vendormanagement);
break;
case 6:
fragment = new CustomerMgmt();
title = getString(R.string.title_custmgmt);
break;
default:
break;
}
Any help is appreciated.Thank you :)

I assume you are trying to refresh fragment when coming back from an activity (that activity does not hosting the fragment which needs to be refreshed), if my assumption is correct please try the below approach, incase not please clarify the question with more info.
Try : Have a boolean variable in fragment and update its value true or false based on fragment visible state using its lifecycle methods.
public class SampleFragment extends Fragment {
private boolean shouldRefreshOnResume = false;
public static SampleFragment newInstance() {
SampleFragment fragment = new SampleFragment();
return fragment;
}
public SampleFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_blank,
container, false);
}
#Override
public void onResume() {
super.onResume();
// Check should we need to refresh the fragment
if(shouldRefreshOnResume){
// refresh fragment
}
}
#Override
public void onStop() {
super.onStop();
shouldRefreshOnResume = true;
}
}

Related

How save the state of the item on my fragment?

I'm getting a ArrayList from an Url with AsyncTask, and inserting into an ListView on my Fragmentbut everytime I change fragments I have to get json data from the Url again so I tried to use onSaveInstanceState() to save my ArrayList as a String and transform to my ArrayList using JsonObject and Gson Library but I can't save the data.
OnSave method
#Override
public void onSaveInstanceState(#NonNull Bundle outState) {
outState.putString("cursos", this.cursosString);
super.onSaveInstanceState(outState);
}
OnCreateView method
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view = inflater.inflate(R.layout.fragment_cursos, container, false);
final ListView lvCursos = view.findViewById(R.id.lvCursos);
if(savedInstanceState != null){
Type arrayListCurso = new TypeToken<ArrayList<Curso>>(){}.getType();
ArrayList<Curso> cursos = new Gson().fromJson(savedInstanceState.getString("cursos"), arrayListCurso);
ListaCursosAdapter adapter = new ListaCursosAdapter(cursos, getActivity());
lvCursos.setAdapter(adapter);
} else {
...
Change Fragments method
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
switch (menuItem.getItemId()){
case R.id.navigation_profile:
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.nav_fragment, perfilFragment)
.commit();
return true;
Here is the solution, you just left to decide how to implement getTagForFragmentId() and getFragmentForFragmentTag(fragmentTag), which should be simple.
The idea of the code below is that you .hide() previous fragment presented and then you either .add(fragment) a new fragment, if it was not previously presented or .show() fragment if it is already inside the backstack.
String lastPresentedFragmentTag = "";
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
switch (menuItem.getItemId()){
case R.id.navigation_profile:
// getTagForFragmentId() can be just a switch case function
// or you can hardcode value instead
String fragmentTag = getTagForFragmentId(R.id.navigation_profile);
presentFragment(fragmentTag);
return true;
//...
public void presentFragment(String fragmentTag) {
if (lastPresentedFragmentTag == fragmentTag) {
return;
}
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
// Hide previous fragment
if (lastPresentedFragmentTag != null) {
Fragment lastFragmenter code hereent = getSupportFragmentManager().findFragmentByTag(lastPresentedFragmentTag);
ft.hide(lastFragment);
}
Fragment currentFragment = getSupportFragmentManager().findFragmentByTag(fragmentTag);
if (currentFragment == null) {
// Implement getFragmentForFragmentTag(fragmentTag) it will be another switch case function that will return you fragment
val fragment = getFragmentForFragmentTag(fragmentTag);
transaction.add(R.id.fragmentContainer, fragment, tag);
} else {
transaction.show(currentFragment);
}
}
transaction.commitNow();
}

How can I retain Fragments and their data on both orientation change using BottomNavigationView

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);
}}

Want to Update the existing listView in fragment by clicking menuitems

I am creating an app for finding nearby blood donors. In this app I am using three fragments for swipe navigation. Inn one fragment, the available donor list is shown, but I want to change the list from a menu list by on a clicking particular blood group The 1st list is but when I click the items it shows nothing.
Java code:
public class DonorsFragment extends Fragment {
SwipeMenuListView listView;
FirebaseListAdapter adapter;
TextView fullName,bloodGroup,gender,age,address;
Query query;
View rootView;
FirebaseListOptions<DonorAdapterClass> options;
public DonorsFragment() {
// Required empty public constructor
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView =inflater.inflate(R.layout.fragment_donors, container, false);
listView = rootView.findViewById(R.id.listview);
Toast.makeText(getActivity(),"oncreateview",Toast.LENGTH_SHORT).show();
query =FirebaseDatabase.getInstance().getReference().child("Users");
setQuery(query);
SwipeMenuCreator creator = new SwipeMenuCreator() {
#Override
public void create(SwipeMenu menu) {
// create "delete" item
SwipeMenuItem deleteItem = new SwipeMenuItem(getActivity());
// set item background
deleteItem.setBackground(new ColorDrawable(Color.rgb(0xF9,
0x3F, 0x25)));
// set item width
deleteItem.setWidth(170);
// set a icon
deleteItem.setIcon(R.drawable.ic_phone);
// add to menu
menu.addMenuItem(deleteItem);
}
};
listView.setMenuCreator(creator);
listView.setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(int position, SwipeMenu menu, int index) {
switch (index) {
case 0:
// open
Toast.makeText(getActivity(),"Item Clicked",Toast.LENGTH_SHORT).show();
break;
}
// false : close the menu; true : not close the menu
return false;
}
});
// Inflate the layout for this fragment
return rootView;
}
#Override
public void onStart() {
super.onStart();
adapter.startListening();
}
#Override
public void onStop() {
super.onStop();
adapter.stopListening();
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.blood_group_menu,menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.a_pos: {
Toast.makeText(getActivity(),"A+",Toast.LENGTH_SHORT).show();
query=FirebaseDatabase.getInstance().getReference().child("Users").orderByChild("canGive_A_Pos").equalTo("yes");
setQuery(query);
break;
}
case R.id.a_neg: {
Toast.makeText(getActivity(),"A-",Toast.LENGTH_SHORT).show();
query=FirebaseDatabase.getInstance().getReference().child("Users").orderByChild("canGive_A_Neg").equalTo("yes");
setQuery(query);
break;
}
case R.id.b_pos: {
Toast.makeText(getActivity(),"B+",Toast.LENGTH_SHORT).show();
query=FirebaseDatabase.getInstance().getReference().child("Users").orderByChild("canGive_B_Pos").equalTo("yes");
setQuery(query);
break;
}
case R.id.b_neg: {
Toast.makeText(getActivity(),"B-",Toast.LENGTH_SHORT).show();
query=FirebaseDatabase.getInstance().getReference().child("Users").orderByChild("canGive_B_Neg").equalTo("yes");
setQuery(query);
break;
}
case R.id.ab_pos: {
Toast.makeText(getActivity(),"AB+",Toast.LENGTH_SHORT).show();
query=FirebaseDatabase.getInstance().getReference().child("Users").orderByChild("canGive_A_Pos").equalTo("yes");
setQuery(query);
break;
}
case R.id.ab_neg: {
Toast.makeText(getActivity(),"AB-",Toast.LENGTH_SHORT).show();
query=FirebaseDatabase.getInstance().getReference().child("Users");
setQuery(query);
break;
}
case R.id.o_pos: {
Toast.makeText(getActivity(),"O+",Toast.LENGTH_SHORT).show();
query=FirebaseDatabase.getInstance().getReference().child("Users").orderByChild("canGive_O_Pos").equalTo("yes");
setQuery(query);
break;
}
case R.id.o_neg: {
Toast.makeText(getActivity(),"O-",Toast.LENGTH_SHORT).show();
query=FirebaseDatabase.getInstance().getReference().child("Users").orderByChild("canGive_O_Neg").equalTo("yes");
setQuery(query);
break;
}
case R.id.list_all: {
Toast.makeText(getActivity(),"All",Toast.LENGTH_SHORT).show();
query=FirebaseDatabase.getInstance().getReference().child("Users");
setQuery(query);
break;
}
}
return super.onOptionsItemSelected(item);
}
public void setQuery(Query query){
listView = rootView.findViewById(R.id.listview);
options = new FirebaseListOptions.Builder<DonorAdapterClass>()
.setLayout(R.layout.donor_list)
.setQuery(query,DonorAdapterClass.class)
.build();
adapter = new FirebaseListAdapter(options) {
#Override
protected void populateView(#NonNull View v, #NonNull Object model, int position) {
DonorAdapterClass donors = (DonorAdapterClass) model;
if(donors.getIsDonor().toString().equals("yes")){
fullName = v.findViewById(R.id.fullName_list);
bloodGroup = v.findViewById(R.id.bloodGroup_list);
gender = v.findViewById(R.id.gender_lis);
address = v.findViewById(R.id.address_list);
age = v.findViewById(R.id.age_list);
fullName.setText(donors.getFullName().toString());
bloodGroup.setText(donors.getBloodGroup().toString());
gender.setText(donors.getGender().toString());
address.setText(donors.getAddress().toString());
age.setText(donors.getAge().toString());
}
}
};
listView.setAdapter(adapter);
}
}
all firebase query and adapter is set in setQuery() method..when it is called from onCreateView() it is working...but when it is called from switch case in onOptionsItemSelected it shows nothing and previous list view also hides
Thanks in Advance :)
This is my first answer in centuries so please bear with me. This is not an answer but just pointer to the path towards solution.
Put a break-point at the following points
onOptionsItemSelected
case R.id.a_pos
setQuery()
setQuery::listView inittialization statement
setQuery::populateView::donor initialization statement
Run the app. Attach the process with debugger. Now when you click "A+" from options, does it get a response from the server or does it throw an exception?

call the activity interface method onDrawerItemSelected(view,position) in fragment page

I need to call the activity interface method onDrawerItemSelected(view,position) in fragment page.is it possible.anyone can help me with this.So that I can do a custom drawer in fragment page.
MainActivity.java:
public class MainActivity extends AppCompatActivity implements FragmentDrawer.FragmentDrawerListener {
#Override
public void onDrawerItemSelected(View view, int position) {
displayView(position);
}
private void displayView(int position) {
Fragment fragment = null;
String title = getString(R.string.app_name);
switch (position) {
case 0:
fragment = new UserProfileFragment();
title = getString(R.string.title_discovery);
break;
case 1:
fragment = new SettingsActivity();
title = getString(R.string.title_messages);
break;
case 2:
fragment = new InboxRequestActivity();
title = getString(R.string.title_discovery);
break;
case 3:
break;
default:
break;
}
}
CustomFragment.java:
public class CustomFragment extends Fragment implements FragmentDrawer.FragmentDrawerListener
menu_btn_click.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mDrawerLayout.openDrawer(GravityCompat.START);
}
});
on clicking the menu_btn_click, I need to call the activity interface method onDrawerItemSelected(view,position) in fragment page.
You need to override the onDrawerItemSelected(View view, int position) method in your fragment and call it on your activity:
#Override
public void onDrawerItemSelected(View view, int position) {
listener.onDrawerItemSelected(view, position);
}
therefor you will need to pass the activity as FragmentDrawer.FragmentDrawerListener to the fragment (e.g. by an appropiate setter).
setListener(FragmentDrawer.FragmentDrawerListener listener){
this.listener = listener;
}

Modify Fragment's views from MainActivity

I am trying to implement swipe views with android. I am using a ViewPager with two tabs containing fragments. In my onCreate() method, I am trying to read from a sharedPrefferences and according to what i am getting, i want to change text and visibility to some child views of the parent view of the first fragment. Unfortunately i am always getting NullPointerException when i am trying to access fragments views.
My sample code from the one of the two fragments is given below. Could you please help me ? Is there a better way to do so?
MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
actionBar = getActionBar();
context = getApplicationContext();
myTabPagerAdapter = new TabPagerAdapter(getSupportFragmentManager());
myViewPager = (ViewPager) findViewById(R.id.pager);
myViewPager.setAdapter(myTabPagerAdapter);
myViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
Toast.makeText(MainActivity.this, "Selected page position: " + position, Toast.LENGTH_SHORT).show();
getActionBar().setSelectedNavigationItem(position);
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
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) {
myViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(android.app.ActionBar.Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
};
actionBar.addTab(actionBar.newTab().setText("Spot Position").setTabListener(tabListener));
actionBar.addTab(actionBar.newTab().setText("Track Vehicle").setTabListener(tabListener));
//Get saved latitude and longitude from sharedPreferences
sharedPref = context.getSharedPreferences("net.ddns.drimou.bachelorthesis", Context.MODE_PRIVATE);
editor = sharedPref.edit();
}
#Override
protected void onStart() {
super.onStart();
getSharedPreferencesOnStart();
}
public void getSharedPreferencesOnStart() {
String s = myTabPagerAdapter.makeFragmentName(myViewPager.getId(),myViewPager.getCurrentItem());
SpotPosition sp = (SpotPosition) myTabPagerAdapter.getItem(0);
sp.setSettings();//In this call i am getting null pointer
...}
Fragment A
public class SpotPosition extends Fragment {
TextView locationTextView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View spotPosition = inflater.inflate(R.layout.spot_position, container, false);
return spotPosition;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
public void setSettings(){
locationTextView = (TextView) myView.findViewById(R.id.mainTextView);//NullPointerException here
locationTextView.setVisibility(View.VISIBLE);
locationTextView.setText("Hello");
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onDestroyView() {
super.onDestroyView();
}
TabPagerAdapter
public class TabPagerAdapter extends FragmentPagerAdapter {
SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
private View mCurrentView;
private SpotPosition sp = null;
private static int NUM_ITEMS = 2;
public TabPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
switch (i) {
case 0:
//Fragment for SpotPosition myViewPager
return new SpotPosition();
case 1:
//Fragment for TrackVehicle myViewPager
return new TrackVehicle();
}
return null;
}
#Override
public int getCount() {
return NUM_ITEMS; //Number of Tabs
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
#Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
sp = (SpotPosition)object;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
#Override
public CharSequence getPageTitle(int position) {
switch(position) {
case 0:
return "Spot Position";
case 1:
return "Track Vehicle";
default:
return null;
}
}
public String makeFragmentName(int viewId, int index) {
return "android:switcher:" + viewId + ":" + index;
}
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
public View getCurrentView(){
return this.mCurrentView;
}
public SpotPosition getCurrentSpotPosition(){
return this.sp;
}
Feel free to ask if something is not understood. Thank you
As far as I understand you call setSettings from you activity, to change views in you fragment. You did not provide stacktrace and i assume you problem - attempt to change view after onPause was called in offcreen fragment. There are several ways to deal with it.
First of all dont call to views dirrectly.
On activity
public void getSharedPreferencesOnStart() {
String s = myTabPagerAdapter.makeFragmentName(myViewPager.getId(),myViewPager.getCurrentItem());
SpotPosition sp = (SpotPosition) myTabPagerAdapter.getItem(0);
// sp.setSettings();//In this call i am getting null pointer
SharedPreferences prefs = getSharedPreferences("message",MODE_PRIVATE);
Editor editor = prefs.edit();
editor.putBoolean("say_hello",true")
editor.commit();
...}
in fragments
#Override
public void onResume(){
super.onResume();
SharedPreferences prefs =
getActivity().getSharedPreferences("message", Context.MODE_PRIVATE);
{
//this block is used for offsreen fragment, it will get update, when it go to forescreen
boolean sayHello = prefs.getBoolean("say_hello", false);
if(sayHello){
locationTextView =
(TextView) myView.findViewById(R.id.mainTextView);//NullPointerException here
locationTextView.setVisibility(View.VISIBLE);
locationTextView.setText("Hello");
}else{
// say something elese
}
}
{
//this listener is for forescreen fragment, as soon as shared preferences will be updated,
// listerner willbe called and you can update your view depending on changed parameters
prefs.registerOnSharedPreferenceChangeListener(
new OnSharedPreferenceChangeListener(){
#Override
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences, String key
){
if(key.equals("say_hello")){
boolean sayHello = sharedPreferences.getBoolean("say_hello", false);
if(sayHello){
locationTextView =
(TextView) myView.findViewById(R.id.mainTextView);//NullPointerException here
locationTextView.setVisibility(View.VISIBLE);
locationTextView.setText("Hello");
}else{
// say something elese
}
}
}
}
);
}
}
You also can use Otto bus it is still unsutable for activity to fragment communication, as fragment can be in !isResumed state, but it is usefull fro fragment -activity comunication.
If you need some complex state tracking for each fragment and activity separatly, I'd recomment to use sqlDatabase and CursorLoaders. It will give you good controll over states and instan comunication.
Edit:
Its not that you cannot pass view from fragment to activity with getters.
Problem - you cannot garanty, that you completly aware of state of the fragment and a view. You try to update views on onStart of activity, which is call earlier, then fragmentsonStart, because fragment have to be generated by adapter and go through attachement process. (to find yout if fragment is attached to activity, you have to set listener in activity and call it ononActivityAttached` of fragment. See android studio activity with fragment template). Thus, when you call to change views, fragment and views probably did not exist.
Futhermore you should read about fragment and activity lifecycle and read about context ( espesialy why strong referencing views in unrelated context holder lead to sever memmory leaks and lificle errors

Categories

Resources