How to refresh fragment UI when come back to it - android

I am new to android and learning things with fragments and have made a demo for it,in that i am having a fragment from which we can go to another activity at there some calculation is performing and after that we come back to frgament at that time i want to dislay that calculation value to my fragment's textview,So which life cycle method should i use to do so?i already used onresume which is not working...
public void onResume () {
super.onResume();
//tvFollowings.setText((sharedConnect.getCurrentUser().userFollowingCount)
// + " Following");
System.out.print("------user count is-------" + String.valueOf(sharedConnect.getCurrentUser().userFollowingCount));
Toast.makeText(getActivity(), "------user count is-------" + String.valueOf(sharedConnect.getCurrentUser().userFollowingCount), Toast.LENGTH_SHORT).show();
}

Yout have to use startActivityForResult(...) when calling your activity, then you can get any information you need in your fragments onActivityResult().

The best approach which works, toggle between onPause and onResume. No need to even bother the parent activity
private boolean allowRefresh = false;
#Override
public void onResume() {
super.onResume();
//Initialize();
if(allowRefresh){
allowRefresh=false;
//call your initialization code here
}
}
#Override
public void onPause() {
super.onPause();
if (!allowRefresh)
allowRefresh = true;
}
onResume will always be called when your fragment gets loaded, so initial state of allowRefresh should be false so the fragment does not get loaded twice
Once you open new activity whilst the fragment is active, onPause is called, here set allowRefresh to true only if allowRefresh is false.
When the fragment regains focus, check if allowRefresh is true and redo your initialization. A good code practice is put all your initialization code in one function.

You can use Bundle to do the same in Android
Create the intent:
Intent i = new Intent(this, ActivityTwo.class);
AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.autocomplete);
String getrec=textView.getText().toString();
//Create the bundle
Bundle bundle = new Bundle();
//Add your data to bundle
bundle.putString(“stuff”, getrec);
//Add the bundle to the intent
i.putExtras(bundle);
//Fire that second activity
startActivity(i);
Now in your second activity retrieve your data from the bundle:
//Get the bundle
Bundle bundle = getIntent().getExtras();
//Extract the data…
String stuff = bundle.getString(“stuff”);
You can refer here for more.POST

You can use the onResume() method of the Fragment
public class Fragment_ABC extends Fragment {
View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_abc, container, false);
return view;
}
#Override
public void onResume() {
super.onResume();
// PERFORM YOUR OPERATION OVER HERE
}
}
Let me know if this works for you ! :)

In your fragment write below code and overide onActivityResult(int requestCode, int resultCode, Intent data) method
Intent intent = new Intent(getApplicationContext(),TrendingQuestions.class);
intent.putExtra("categoryId", Integer.parseInt(categoryId));
startActivityForResult(intent, 101);
In your next activity after you got the result just set result
Intent result = new Intent();
setResult(Activity.RESULT_OK, result);
finish();
If onActivityResult is not getting called please check this link

Then do one thing .. use the Activities onResume Method in which you are showing the Fragment and then from within this Activity's OnResume call the Fragment' Function where you want to refresh the Fragment.
For example.
You have a Activity_A in which you have defined the fragment, let it be Fragemtn_A. Now you are navigating to Activity_B from within this Fragment_A.
Now when you are leaving Activity_B, then the onResume() method of the Activity_A will be called for sure, and from the onResume() of Activity_A you can call the function of Fragment_A and perform your operations that you want.
For calling any fragment's function from withing the Activity you can follow this link :
Calling a Fragment method from a parent Activity
Let me know if this works for you! :)

Related

How do I recreate the activity only once after opening the application?

How do I recreate the activity only once after opening the application?
I tried to do this, but it didn't work. Endlessly recreate()
refreshLang() in onCreate
private fun refreshLang() {
PreferenceManager.getDefaultSharedPreferences(this).apply {
val checkRun = getString("FIRSTRUN", "DEFAULT")
if (checkRun == "YES") {
PreferenceManager.getDefaultSharedPreferences(this#MainActivity).edit().putString("FIRSTRUN", "NO").apply()
recreate()
}
}
}
and SharPref.putString("FIRSTRUN", "YES").apply() in onDestroy to make it work again the next time you run it.
Please refer: Activity class
recreate()
It create new instance and initiates fresh activity lifecycle.
So when you call recreate() it will call onCreate() and will go in endless loop.
You have add some condition to avoid this overflow.
Edit:
Use .equals instead of ==
if ("YES".equals(checkRun)) {
PreferenceManager.getDefaultSharedPreferences(this#MainActivity).edit().putString("FIRSTRUN", "NO").apply()
recreate()
}
I suggest you not to use recreate(). It will call onCreate and onDestory().
Refer below code.
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
boolean recreateRequested = true;
Intent currentIntent = getIntent();
if (currentIntent.hasExtra("recreateRequested")){
recreateRequested = currentIntent.getBooleanExtra("recreateRequested", true);
}
if (recreateRequested) {
Intent intent = new Intent(this, MyActivity.class);
intent.putExtra("recreateRequested", false);
startActivity(intent);
finish();
}
}
you can't compare two Strings like this in your if condition
checkRun == "YES"
these are two separated instances of String, so they never be equal in the this meaning (== - same object)
use this instead
"YES".equals(checkRun)
equals will compare "content" of compared objects, in String case it will compare text
use onResume Method
#Override
public void onResume() {
super.onResume(); // Always call the superclass method first
}

Call a method from an activity to a fragment of another activity. What is the proper way?

This might have already answered but I am still troubling with a function like this. Let's say I have activity A and activity B. B holds a viewpager with several fragments in it. I would like to call a function in the fragment held by activity B from activity A.
I used callbacks many times to communicate between activites and fragments but every single time it was only the fragment and its holder activity. I do not want to make a static method (the callback listener cannot be static anyway) so it causes a headache for me. The simple static solution to make a static method in the fragment and have it called from the other actually works very well, but I am not sure if it was a good idea as I need to change several things static.
So communicating between Activity B and its fragments is ok, but I cannot call this method in Activity A.
Activity B:
public class ActivityB extends FragmentActivity implements Fragment1.OnWhateverListener
{
...
#Override
public void onWhateverSelected(int position) {
//stuff, here I can call any function in Fragment 1
}
}
The following code snippet is a wrong solution (doesnt even work) but makes a better picture what I would like to do.
Activity A:
ActivityB ab = new ActivityB ();
ab.onWhateverSelected(number);
So how can I do this?
Thank you!
EDIT
Activity A: the method I call
Bundle args = new Bundle();
args.putString("ID", id); // the data to send
Intent frag_args = new Intent(Intent.ACTION_VIEW);
frag_args.setClass(this, MainActivity.class);
frag_args.putExtra("args", args);
startActivity(frag_args);
Activity B:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
...
processIntent(getIntent()); //last line of onCreate, always gets called here
}
#Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
processIntent(intent); // this never gets called here only in OnCreate
}
private void processIntent(Intent intent) {
Bundle args = intent.getBundleExtra("args");
if (args != null) { // check if ActivityB is started to pass data to fragments
String id = args.getString("ID");
Log.i("ID_FROM", "id: " + id); //works well
if (id != null) {
List<Fragment> fragments = new ArrayList<Fragment>();
fragments = getSupportFragmentManager().getFragments();
//NULLPOINTER for the following line
FragmentMainDiscover fr = (FragmentMainDiscover) fragments.get(0);
fr.RefreshHoverView(id);
}
}
}
You are right to stay away from statics. Way too risky, for visual objects that may or may not be on screen.
I would recommend going through activity B, since it is the parent of your target fragment. Create an Intent that starts activity B, and include an intent extra that tells activity B what it should do to the target fragment. Then activity B can make sure that the fragment is showing, and pass the information on to it.
One other idea to pass the info to the fragment is to use setArguments, rather than direct calls. This is a nice approach because Android will restore the arguments automatically if the activity and its fragments are removed from memory.
Does this make sense? Do you want the code?
EDIT
To use arguments, you still need to have activity A go through activity B. This is because activity A doesn't know if activity B, and all its fragments, is running unless it sends it an Intent. But you can include data targeted for the fragments, by putting them inside the intent. Like this:
public class ActivityA extends Activity {
public static final String KEY_FRAG = "frag"; // tells activity which fragment gets the args
public static final String KEY_ARGS = "args";
public static final String KEY_MY_PROPERTY = "myProperty";
public void foo() {
Bundle args = new Bundle();
args.putString(KEY_FRAG, "frag1Tag"); // which fragment gets the data
args.putCharSequence(KEY_MY_PROPERTY, "someValue"); // the data to send
// Send data via an Intent, to make sure ActivityB is running
Intent frag_args = new Intent(Intent.ACTION_VIEW);
frag_args.setClass(this, ActivityB.class);
frag_args.putExtra(KEY_ARGS, args);
startActivity(frag_args);
}
}
public class ActivityB extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//TODO configure activity including fragments
processIntent(getIntent()); // this call is in case ActivityB was not yet running
}
#Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
processIntent(intent); // this call is in case ActivityB was already running
}
private void processIntent(Intent intent) {
Bundle args = intent.getBundleExtra(ActivityA.KEY_ARGS);
if (args != null) { // check if ActivityB is started to pass data to fragments
String fragTag = args.getString(ActivityA.KEY_FRAG);
if (fragTag != null) {
Fragment frag = getSupportFragmentManager().findFragmentByTag(fragTag);
frag.setArguments(args);
//TODO either show the fragment, or call a method on it to let it know it has new arguments
}
}
}
}
public class Fragment1 extends Fragment {
public static final String TAG = "frag1Tag";
#Override
public void onResume() {
super.onResume();
Bundle args = getArguments();
String value = args.getString(ActivityA.KEY_MY_PROPERTY);
...
}
}

How do I persist an attribute in an activity that I'm navigating back up to?

I have some activities basically set up as shown below (clicks on are ListViews).
Parent class method to go to MyChild1
public void onItemClick(int pos){
Intent i = new Intent(this, MyChild1.class);
i.putExtra("KEY1", myAdapter.getItem(pos).getId());
startActivity(i);
}
MyChild1 class method to go to MyChild2
public void onItemClick(int pos){
Intent i = new Intent(this, MyChild2.class);
i.putExtra("KEY2", myAdapter2.getItem(pos).getId());
startActivity(i);
}
So you see that I have a parent, a child, and a grandchild activity. The child inflates based on the id provided by the parent and the grandchild inflates based on the id of the child. This works fine. However, when I use up navigation from the grandchild back to the child, it no longer has the id it needs from the parent to properly inflate. I need to support up navigation because the child can change based on actions in the grandchild.
I could pass the parent's id all the way down to the grandchild activity, but I don't know how to pass it back up. How can I handle this?
Edit: More code for context.
Here is my activity's onCreate.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_course);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new CourseActivityFragment()).commit();
Intent intent = getIntent();
courseId = intent.getIntExtra(MainFragment.COURSE_ID, 0);
System.out.println("the saved state was null");
// The above prints, so I know it enters this if statement
} else {
courseId = savedInstanceState.getInt(COURSE_ID);
}
}
And here is my onSaveInstanceState
#Override
public void onSaveInstanceState(Bundle savedInstanceState){
// Save current CourseId
savedInstanceState.putInt(COURSE_ID, courseId);
// Call superclass to save view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
Instead of startActivity, use startActivityForResult:
Intent intent = new Intent(ParentClass.this, ChildClass.class);
startActivityForResult(intent, RequestCode);
In child class, set some parameter in intent to identify in Parent class.
Intent intent = getIntent();
intent.putExtra(<Key>, <Value>);
In parent class, override the onActivityResult method, and check your Value for that Key
#Override
public void onActivityResult(int requestCode, int resultCode, Intent intent)
{
if (requestCode == RequestCode)
{
//Do something
}
}
I don't quite follow what you need so I hope this will help. Save it in your Activity class as member variable. Activity's object is not destroyed right after user leave this activity. If that still occur and Android will kill your activity, you can use onSaveInstanceState() and restoreInstanceState() methods to restore this id.

Get Activity after startActivity(Intent i)

In one method i start a new activity
public void start(){
Intent i = new Intent(mContext, Screen.class);
mContext.startActivity(i);
//Here i want to get the new activity
Activity a = ...
//Do something with new activity
}
After calling starActivity() i need to get that new Activity and doing something with it.
Is it possible??
EDIT:
Well i have these methods on my Screen class:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loadedScreen = false;
}
public void loadScreen(String folderResources, String nameXml, String nameScren){
//Do something
}
loadScreen read an XML file and create by code all user interface, instead of doing in onCreate
In another class I call foo():
public void goToScreen(String nameScreen){
Class screen = Screen.class;
Intent i = new Intent(mContext, screen);
mContext.startActivity(i);
//Here in screen.getMethod... i need use a instance of Screen, which i think it have to be created in `startActivity()`
Method loadUrl = screen.getMethod("loadScreen", String.class, String.class, String.class);
loadUrl.invoke(screen, "folder-s","screen1","screen1.xml");
}
I need call to loadScreen after startActivitybecause this method load all views. I use reflection for doing this. So i need get that new Activity
After calling starActivity() i need to get that new Activity and doing something with it.
Once you call startActivity(), the other activity does not yet exist -- it will not exist for some time.
I need call to loadScreen after startActivitybecause this method load all views.
Call loadScreen() from onCreate() of the Screen activity.
If you wish to pass the values of folderResources, nameXml, and nameScren to Screen, do so by calling putExtra() on the Intent you use with startActivity(). Then, Screen can call getIntent().getStringExtra() in onCreate() to retrieve those values, in order to pass them to loadScreen().

startActivityForResult doesn't seem to call onActivityResult

When The user Click on the button it want to call the dialog- that dialog contain list of product in ListView.After user slect the product it should come to previuous activity.
I have done using startActivityForResult ().
There aresome issue.My calling activity is in normal tab activity that normal tab activty in Tab Activity Group.
Actualy i want to do in drrop down(Spinner).In my scanerio i couldn't get context.It awalys give Android Spinner Error : android.view.WindowManager$BadTokenException: Unable to add window
So I have change to my design like this: When User click buttion it load the list of product in ListView.After pick the product, it come back to previous activity.
This is my previous question : link
Here calling activity:
//Click Product button
l_prod.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent showContent = new Intent(LineDiscountActivity.this,ListProductActivity.class);
Bundle bundle = new Bundle();
bundle.putString("Activity", "LineDiscountActivity");
bundle.putString("RetailerName", retailerName);
bundle.putString("RetailerCode", retailerCode);
showContent.putExtra("discountProduct", discountList);
showContent.putExtras(bundle);
getParent().startActivityForResult(showContent, 5);
}
});
And my receiver activity :
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Object o = this.getListAdapter().getItem(position);
String book = o.toString();
Intent i = new Intent();
Bundle bundle = new Bundle();
bundle.putString("Activity", "ListProductActivity");
bundle.putString("RetailerName", retailerName);
bundle.putString("RetailerCode", retailerCode);
bundle.putString("seletcedProductCode", products.get(position).getProductCode());
bundle.putString("seletcedProductName", products.get(position).getDescription());
bundle.putDouble("seletcedProductQty", products.get(position).getAvailableQuantity());
i.putExtra("discountProduct", discountList);
i.putExtras(bundle);
if (getParent() == null) {
setResult(Activity.RESULT_OK, i);
} else {
getParent().setResult(Activity.RESULT_OK, i);
}
ListProductActivity.this.finish();
}
And calling activity
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// super.onActivityResult(requestCode, resultCode, data);
Log.i("-requestCode from LineDisocunt--" ,"" + requestCode);
}
I have written this code(onActivityResult) in calling activity & Tab main Activty also.
I didn't go anywhere..
onActivityResult mehtod.But it didn't go it.
What is wrong in my code.
Please let me know if anybody know this...
Thanks in advance
I have same issue when I was using startActivityForResult() with activity group.
your activity result will go to your activity group.You will not get activity result in your first activity
So you can solve this issue by taking one public static object in your first activity and when you call second activity you have to assign your first activity object from second activity.and then finish second activity so that your first activity will resume and you can update your ui by overriding onResume() method in first activity.You have to check validation weather your object is assigned or not.
For example
You have one static object product in your first activity
First Activity
public static Product product;
start second activity
startactivity(this, SecondActivity.class);
don't finish First Activity
You have to override onResume() method and then you can use product object which is assigned by second activity
second activity
FirstActivity.product.setName(name);
FirstActivity.product.setPrice(price);
After assign the product object you have to finish second activity
like
finish()
EDIT
I got the solution for your issue of badTokenException
Here is the solution
CLICK HERE

Categories

Resources