How to refresh Activity - android

Actually in my app i have a button on an listView..now on click of that button i have done some changes..so when i move to previous activity after than this changes should appear on that activity..but in my case the changes occur but not appears after i exit from the activity where my listView Button is present..so how can i do that so that my changes occur immediately after i exit from my first activity..code i have wrritten:
code for ListView Button Onclick:
public boolean stopCycleStage(View v)
{
Button butStop=(Button) findViewById(R.id.butStop);
TextView setStopTxtViewTitle =(TextView)findViewById(R.id.setStopTxtViewTitle);
Date currentDate=new Date();
int iStopStartCount = CycleManager.getSingletonObject().getStopStartCount();
Date dtStopDate = currentDate;
CycleManager.getSingletonObject().setStopStartDate(dtStopDate, iStopStartCount);
Date dtStart = CycleManager.getSingletonObject().getStartDate();
if (dtStopDate.getTime() == dtStart.getTime())
CycleManager.getSingletonObject().removeHistoryDate(dtStart);
butStop.setBackgroundResource(R.drawable.settings_but_disabled);
setStopTxtViewTitle.setTextColor(Color.parseColor("#808080"));
return true;
}

In your first activity, you should refresh the view in the onResume function rather than just in the onStart or onCreate.
Refer to the activity documentation to see the lifecycle of an activity
PS: this is just a guess because you have not given enough code to show how you load the data in your 1st acitvity.

Id use onActivityResult() in the waiting activity, and in there I would redraw the elements that should have changed when you clicked your button in the child activity. In any case, onActivityResult() is the correct way to go unless you are not waiting for any data from child activity, then I'd use onResume().
See http://developer.android.com/reference/android/app/Activity.html#StartingActivities for information on what you should use in your particular situation (you didn't exactly give much information :))

Related

Opening Instance of Activity

I have an app that hold post information in an activity. in this activity related posts listed in bottom of post. User by clicking on related post can go to post activity and see that post info and related posts too.
As you can see in image, I have Activity A that holds post and it's related posts. When user Click on post I send user to Activity A with new post id and fill activity by new data.
But I think this is not Right way!
should I used Fragment instead of Activity?
Opening another Instance of an Activity on top of another is simplest way of navigating a content graph. User can simply press back, and go to previously opened content, until user reaches back to starting Activity, then the application closes. Though pretty straight forward, this particular approach has two issues:
It may happen that a lot of Instances of same activity are on the stack, utilising a large amount of device resources like memory.
You don't have a fine grained control over Activity Stack. You can only launch more activities, finish some, or have to resort to intent flags like FLAG_CLEAR_TOP etc.
There is another approach, that re-uses the same Activity instance, loads new content in it while also remembering the history of content that was loaded. Much like a web browser does with web page urls.
The Idea is to keep a Stack of content viewed so far. Loading new content pushes more data to stack, while going back pops the top content from stack, until it is empty. The Activity UI always displays the content from top of the stack.
Rough Example:
public class PostActivity extends AppCompatActivity {
// keep history of viewed posts, with current post at top
private final Stack<Post> navStack = new Stack<>();
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// get starting link from intent extras and call loadPost(link)
}
private void loadPost(String link){
// Load post data in background and then call onPostLoaded(post)
// this is also called when user clicks on a related post link
}
private void onPostLoaded(Post post){
// add new post to stack
navStack.push(post);
// refresh UI
updateDisplay();
}
private void updateDisplay(){
// take the top Post, without removing it from stack
final Post post = navStack.peek();
// Display this post data in UI
}
#Override
public void onBackPressed() {
// pop the top item
navStack.pop();
if(navStack.isEmpty()) {
// no more items in history, should finish
super.onBackPressed();
}else {
// refresh UI with the item that is now on top of stack
updateDisplay();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
// cancel any background post load, release resources
}
}
I would choose:
activity/fragment depends on complexity with:
horizontal recyclerview with custom expanded card view
and inside this expanded card view second vertical recyclerview :)
Here's what you can try.
Create a PostActivity which is a shell for fragments. Inside this activity you can just replace fragments using FragmentTransaction.
Your PostActivity can now have a PostFragment which will hold post and related posts. Now on click of post you can replace PostFragment with PostDetailFragment with postID being sent to the new fragment as a bundle. The PostDetailFragment will now display details according to id.
Check here: http://www.vogella.com/tutorials/Android/article.html#components_fragments
By seeing the picture the way i would implement is i would have create an activity with a bottom listview for your items and on top there would be a framelayout for holding fragments . when user click on any list item i would load the respective fragment in the activity
It all depends on what you are trying to achieve. What would you expect to happen when the user touches the back button after going down a couple of levels? If you want to the application to exit, no matter how deep in the sequence they have gone, then the best solution in my opinion is to simply reload the same activity with the new data and invaliding the affected views. If you need the back button to take the user back to the previous data, then the next question would be if you are keeping track of the past data breadcrumb. If so, then just intercept the back button and load the previous data for as long as there is data in your stack, or exit if you get to the top. If you don't want to keep track of the previous data chain, then instead of loading one activity with the new data, you can start a new activity of the same class, but with the new data. Android with keep the track of activities and each back button touch would close the running activity and take the user to the previous activity. Choice of activity versus fragment is just yours. You can use fragments that hold the data that you want to change after each user touch, create new ones when needed, disconnect the previous ones, and connect the new ones. You will need to do some extra work to make sure the back button works correctly (depending on you want the back button to behave). Based on what I can tell, it is simpler to just have one activity and load new data when needed and keep a trail of data changes, if you need to be able to go back.
It can be achieved using activity alone. Though I preferred moving all related UI to fragment.
You can use Navigator class.
Here the steps:
1. Add Navigator Class
public class Navigator {
private static Navigator instance;
public synchronized static Navigator getInstance() {
if (instance == null) {
instance = new Navigator();
}
return instance;
}
public void navigateToActivityA(Context context) {
Intent activity= AActivity.getCallingIntent(context);
context.startActivity(activity);
}
}
2. Add the calling method to your Activity class.
public static Intent getCallingIntent(Context context) {
return new Intent(context, AActivity.class);
}
3. Call the activity with the following code in your caller activity.
Navigator.getInstance().navigateToActivityA(this);
I suggest that you read about AndroidCleanArchitecture
For this task...
0) Starting new activity
I read again about question, and understood that you need advice for starting activity. So, starting new activity it's Ok, your main problem will be with another things (see below).
But lets talk about starting another data. Using Fragment instead doesn't resolve your task, fragments helps with different screen work. Using for example just data refreshing as a variant. You may use just single activity and refresh only data, it will look much better, if you also add animation, but not better than starting activity.
Using Fragment helps your with different screen actions. And maybe, answering on your question - it will be most suitable solution. You just use single acitivity - PostActivity, and several fragments - FragmentMainPost, FragmentRelated - which will be replaced, each other, by selecting from related post.
1) Issues with returning back
Lets imagine, that users clicks to new one activity and we loaded new data. It's Ok, and when Users clicks over 100 activities and receiving a lot of information. It's Ok, too. But main question here it's returning back (also another about caching, but lets leave it, for now).
So everyone know, it's bad idea to save a lot of activities in stack. So for my every application, with similar behavior we override onBackPressed in this activity. But how, lets see the flow below:
//Activities most have some unique ID for saving, for ex, post number.
//Users clicks to 100 new activities, just start as new activity, and
//finish previous, via method, or setting parameter for activity in AndroidManifest
<activity
noHistory=true>
</activity>
....
//When activity loaded, save it's activity data, for ex, number of post
//in some special place, for example to our Application. So as a result
//we load new activity and save information about it to list
....
// User now want return back. We don't save all stack this activities,
// so all is Ok. When User pressing back, we start action for loading
//activities, saved on our list..
.....
onBackPressed () {
//Getting unique list
LinkedTreeSet<PostID> postList =
getMyApplication().getListOfHistory();
//Getting previous Post ID based on current
PostID previousPostID = postList.get(getCurrentPost());
//Start new activity with parameter (just for ex)
startActivity(new Intent().putExtra(previousPostID));
}
RESULT
I found this as the best solution for this tasks. Because in every time - we work only with single activity!

Fragment refreshing on backpress

I have an activity MainActivity there are three fragments associated with this activity.
Now one of my fragment Timeline has a listview. Which I populate from a Database in the backend. I use an AsyncTask to fetch values from the DB and process them to the List. I trigger this AsyncTask in the onCreate of the Fragment Timeline.
Now from Timeline on click of any list item I navigate to a different Activity called as DetailActivity
The problem is whenever I press back from the DetailActivity the onCreate of my MainActivity is called and my list refreshes again - the whole DB operation is called again and my list does not retain its state.
I am calculating the visible items of my List before I navigate away from the Fragment but I am forced to use static values for these variables so that I retain the position. How to avoid this?
Below are the snippets of my onPause and onResume as laid down in the fragment Timeline
static int index;
static int top;
#Override
public void onPause(){
System.out.println("onPause");
index = lv.getFirstVisiblePosition();
View v = lv.getChildAt(0);
top = (v == null) ? 0 : v.getTop();
super.onPause();
uiHelper.onPause();
}
#Override
public void onResume(){
super.onResume();
//dbHelper.open();
System.out.println("onResumr");
lv.setSelectionFromTop(index, top);
ActionBar actionBar = getActivity().getActionBar();
actionBar.setTitle("Timeline");
uiHelper.onResume();
AppEventsLogger.activateApp(getActivity());
updateUI();
}
This also forces my AsyncTask to run again and again, which is an overhead.
Edit:
The root of this problem - After struggling for so many days I borrowed a friends phone to test and all was sorted on this new phone. I found out that I had turned on the Do not keep Activities option in my Developer Settings. The Dumb me!!
This is, unfortunately, the default behavior of the Fragment class. A Fragment is destroyed whenever the containing Activity is paused, and recreated whenever the containing Activity is resumed. If you use an Activity instead of a Fragment for the list, you would not experience the same behavior. With an Activity:
AsyncTasks and/or web services would not be called again.
The list would show the previously scrolled position.
If you want the same behavior with a Fragment, you need to override the onSaveInstanceState() method. And while interesting, it is not a small amount of work.
EDIT:
Make sure the Do not keep Activities option is unselected in your phone's Developer Settings. This, though, does not change the essential behavior of the Fragment class that I have outlined above.
You can call setRetainInstance(true) on your fragment. The lifecycle will be slightly different though.
A nice view of a fragment's lifecycle is available here
http://corner.squareup.com/2014/10/advocating-against-android-fragments.html

Make Button in Android to repeat process inside activity until counter reaches certain number

I currently have Button in my main view which checks if users answer is correct.
Button CheckButton= (Button) this.findViewById(R.id.CheckButton);
CheckButton.setOnClickListener(new OnClickListener()
{
public void onClick(View v) {
// some action, setting text
}
});
If button is pressed once it checks if answer is correct, and if button is pressed second time I want it to repeat activity e.g. present user with another question.
OnClickListener is inside onCreate method and question is generated using switch and unique id (for game difficulty).
What would be the best way to set this repeat activity until it's been repeated 4 times. Thanks
switch (difficulty_level)
{
case DIFFICULTY_HARD:
// do this
case DIFFICULTY_EASY:
// do this
}
To me, this doesn't sound like logic belonging in the OnClickListener at all. The listener should simply register the click and then call a function in your activity "handleButtonClicked" that have access to fields that keep track of the number of clicks for the question, if the answer is correct and what the appropiate action is.
The fact that the OnClickListener is set in the onCreate only says that it is ready to be used after OnCreate. It doesn't require the OnCreate to be run again.
Instead of an anonymous inner implementation of OnClickListener, define it as a private class.
That way you can pass the parameter of how many iterations you want in its constructor / setter
Each time the application is launched, increase a counter; when such counter is bigger or equal than the said parameters, ignore the following clicks
You need a global state variable that you set when the click has occured twice, or you could just count and every even number you change the question by loading another activity.

How to make the back function and set the last contentView

I hawe many view's in my application and now the problem is how to go back from one view to another.
What I could do it by set back Buttons in every view but i would like to use the android back hard button.
I have tried something like this:
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if(keyCode==KeyEvent.KEYCODE_BACK)
{
finish();
}
return false;
}
But the problem is that this will close my application.
Could you please guide me for a proper solution, for example to memorize the last view was set and then to come back to this view or something like this.
Here is the code with which I am changing the view (it's a method in my main activity):
public void CheckIfUserIsLogedIn ()
{
int userPresence = localDatabase.CheckUserPresence();
if (userPresence == 0)
{
setContentView(R.layout.main);
}
else
{
setContentView(R.layout.userlogedon);
}
}
Thank you.
Look!
You are doing this wrong way..
An Activity class should only have on content View. (because it is recommended way and easy to use and implement).
And if you want to go to next View, show it under another separate Activity.
when you will finish it, you will be automatically redirected to previous Activity.
(and you don't need to memorize the Previous View :) )
See here, how to work with Activity Stacks.
I am not sure to understand your problem correctly because Android do all that for you automatically. Once a view is opened when you switch to another view it is paused (on screen but has not focus) or stopped (has no focus)
http://developer.android.com/reference/android/app/Activity.html
If the current view (activity) has been launched by the previous view (activity), pressing the back button will make you "close" the current view and go back to the previous one automatically.
Now two things :
Perhaps your are simply opening all views wihtin the same activity by showing on or off components which is a bad way of doing and is not recommended by android. What you should do is 1 view = 1 activity.
You are thinking like "iPhone/iPad" where you have to implements back buttons in the "views". In android you don't need to do so. Putting the "finish" command in your code at that point seem to close the application which make me think you have programmed as explained in point 1.
Hope it helps
EDIT:
To start a new activity do it like this
startActivity(new Intent(this, MyOtherActivity.class));
you put this in your code where you want to load the new view (activity)
Now if you want to transfer some information between activities you must do something like this :
Intent myIntent; //intent declaration
int aNumber = 10; // info to send to other activity
String aString = "abcd"; // info to send to other activity
// link Intent to the other activity
myIntent = new Intent(view.getContext(), MyOtherActivity.class)
//put the extra info
myIntent.putExtra("myNumber", aNumber);
myIntent.putExtra("myString", aString);
//start the new view/activity
startActivity(myIntent);
and in the new opened activity you retrieve the infos like this (in the oncreate usually)
int aNumber;
String aString;
#Override
public void onCreate(Bundle savedInstanceState) {
aNumber= getIntent().getExtras().getInt("myNumber");
aString= getIntent().getExtras().getString("myString");
}
Actually i m not sure that understand exactly but..
take a map or a shared preference and at the back button set last View on map or Shared preference .
At the calling or at start activity fetch the data which have stored you.
this will helps you.

Android Launching the current activity with different Intent Action

[Update Solution]
Referring to the post in the link
ViewPager PagerAdapter not updating the View
public void onSomeButtonClicked(View view) { // registered to Button's android:onClick in the layout xml file
Log.w(TAG,"Some button clicked !!");
getIntent().setAction(IntentManager.Intents.ACTION_SPAWN_LIST_BY_SOMETHING);
mViewPager.getAdapter().notifyDataSetChanged();
}
// And inside my PagerAdapter
#Override
public int getItemPosition(Object object) {
return 0;
}
Fixed all my problems, i just used Intent.setAction().
[Update to below Post]
My problem is i have a ViewPager PagerAdapter in my Main Activity. On clicking one of the 3 buttons., any specific intent will be fired (i used intent, i could have gone with just State variable as well, just that i pass some Uri with the intent). What happens is., i do
public void onSomeButtonClicked(View view) { // registered to Button's android:onClick in the layout xml file
Log.w(TAG,"Some button clicked !!");
getIntent().setAction(IntentManager.Intents.ACTION_SPAWN_LIST_BY_SOMETHING);
mViewPager.getAdapter().notifyDataSetChanged();
}
This is why i was guessing maybe i should just do startActivity again, with the new Intent Action on the same Activity.
Spawning a new Activity, i would have to redraw every other view in the layout which is basically the same code, for the most part in the current activity.
Any suggestions here? Please help
[Original Post]
I have a PagerAdapter and 3 Buttons in the my Main Activity. This activity is enter from Main Launcher.
When i press any one of the buttons, the Intent Action is changed.
My question:
The changed Intent action reflects some changed view in the ViewPager and does_not spawn a new Activity as such, only the view is updated.
What approach should i take to get this task?
Can i start the currentActivity using startActivity() and different Intent actions on button click?
or is there any other efficient way in android to do this?
[No need code, just explanation of logic / method would suffice]
Thanks in advance
If you are saying that you are trying to use startActivity to bring up the same activity again, and its not working, it could be because you set something like singleTop in your Android manifest.
If you are asking whether or not you should use an intent to change the state of your Activity, then the answer is "it depends". If the user would expect the back button to return your app to its previous state (instead of going back to the home screen), then it might be a good choice for you. If that is the case, however, I would ask why not just make 2 different Activities? Otherwise, just do as Dan S suggested and update the state of your Activity as the user interacts with it.
You can always use the onNewIntent() hook. Do something like this in your activity:
protected void onNewIntent(Intent intent){
//change your activity based on the new intent
}
Make sure to set the activity to singleTop in your manifest. Now whenever startActivity is called the onNewIntent() will be executed. Also, note that per the documentation:
Note that getIntent() still returns the original Intent. You can use setIntent(Intent) to update it to this new Intent.

Categories

Resources