I have a scenario where I am clicking on a ListFragment and spinning up a new Activity like below:
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Intent intent = new Intent(getActivity(), VenueBeerActivity.class);
Parcelable wrapped = Parcels.wrap(mAdapter.getItem(position));
intent.putExtra("venue", wrapped);
startActivity(intent);
}
This works fine and displays the new activity.
I've modified this activities manifest so it points back to its parent activity (in this case main activity)
However the problem I have is when the back button is pressed, it reloads the entire parent. The parent is a list and I don't want it to reload the users position. How can I prevent this?
As a note. The parent houses a Page Tab Strip.
I'm sure this is a relatively simple fix...
What do you mean by "back button"? Is it the up button in the toolbar? If that's the case, edit the onOptionsItemSelected in your VenueBeerActivity to:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case android.R.id.home:
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
So when user press the Up button it will get the behavior of the back button in the navigation bar.
In the parent activity, set the android:launchMode attribute to singleTop. This would prevent the system from creating a new instance of parent when up button is pressed.
Related
I am using a ToolBar Spinner to switch among the 6 activities of my App. The opening activity, which I call MainView, has only the spinner [plus a help link on the ToolBar action menu]. The user selects from the spinner which of the other 5 activities he wishes to run and when finished uses the ToolBar back button of that activity to return to MainView.
It all works fine except, after returning to MainView from any of the other activities, the name of that activity remains displayed in the Spinner, not MainView as i had expected. Plus, if user wants to return to that same activity he must select any of the others first.
I had thought that when the App returns to MainView using the ToolBar back button it would do so by calling the MainView OnCreate, and the MainView spinner would be recreated thus displaying MainView. But this appears to be not the case.
I have tried a few things including setSelection(0) in onCreate, re-initializing the spinner in onStart and onResume - but none has made a difference. Hope you can help.
xml for spinner ...
<Spinner
android:id="#+id/spinner_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
initialization code for spinner
String[] mainview_names = new String[]
{"MainView", "WebView", "JsoupView", "CodeView", "Connectivity", "FtpView"};
Spinner mainSpinner = (Spinner) findViewById(R.id.spinner_main);
ArrayAdapter<String> adapter = new ArrayAdapter<>
(this,android.R.layout.simple_spinner_dropdown_item, mainview_names);
mainSpinner.setAdapter(adapter);
mainSpinner.setOnItemSelectedListener(new CustomOnItemSelectedListener());
// mainSpinner.setSelection(0);
The Listener ...
public class CustomOnItemSelectedListener implements AdapterView.OnItemSelectedListener {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
switch (pos){
case 0: // Main View
break;
case 1: // Web View
BrowseWWW();
break;
case 2: // Jsoup View
LoadHTMLJsoup();
break;
case 3: // Code View
LoadHTMLCode();
break;
case 4: // Connectivity
GetHTMLConn();
break;
case 5: // Ftp View
GetHTMLFtp();
break;
}
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
}
}
EDIT: Additional information:
The 5 activities each respond to the back button with code structured like this.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
help.setVisibility(View.GONE);
switch (item.getItemId()){
case android.R.id.home: // up navigation
finish();
return true;
case R.id.load:
// ....
}
return true;
case R.id.Clear
// ...
return true;
}
return false;
}
#Override
public void finish() {
Intent i = new Intent();
i.putExtra("urlKey", url.getText().toString());
i.putExtra("tokenKey", token.getText().toString());
i.putExtra("redirectsKey", HttpURLConnection.getFollowRedirects());
setResult(RESULT_OK, i);
super.finish();
}
Ok the spinner state issue:
Without digging into more of your code, here's my theory:
You're in activity A. You select something in the spinner, say B. Now you're in activity B and activity A is paused retaining state it had -- i.e. it has the item corresponding to B selected in the spinner. When you go back from B, activity A is resumed in that exact state and, of course, still has the B item in the spinner. You can't go to B again right away, because if you re-select B, your select handler will not be called (since there's no change).
The fact that Activity is not destroyed every time is probably what tricked you, that's why you should take a look at google guide on Activities -- it will probably save you a lot of guessing time :)
So, to fix your issue with spinners, you should override the onResume() method of each activity and use it to set the spinner to the state corresponding to that activity -- that's the short version.
Long version is, you're probably going somewhat against the flow using toolbar spinner to navigate between activities.
Navigation can be faster and more intuitive you implement your Web, Jsoup, Code and other top-level views as Fragments (also, this) inside a single Activity, that's exactly what they're for. It'll probably be more user-friendly to use Tabs instead of Spinner.
I have an application where onItemClick() activity determines which item in the drawer is clicked and the corresponding activity is started. However, when if I am already at the 'Settings' screen and I open the drawer and click on 'Settings' again, it starts a new settings activity. How can I optimize my code here to just detect that user was already on the Settings screen and therefore the drawer should just slide close?
Here's my code:
//#Override
public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
Drawer.closeDrawers();
Intent i = new Intent(DrawerActivity.this, SignUpActivity.class);
switch(position){
case 7:
i = new Intent(DrawerActivity.this, UserSettingActivity.class);
break;
}
startActivity(i);
For that you can store that last clicked number in one variable.
Then next time do check whether current clicked position is not equal to last store position
If it's not equal launch new screen and updated last clicked position else don't do nothing
I have an ActionBarActivity "B" whose parent is ActionBarActivity "A" (also defined in manifest). A is in "singleTask" launch mode. I have an animation when starting B from A as follows:
public void onItemClick(...) {
Intent mIntent = new Intent(getActivity(), B.class);
startActivity(mIntent);
getActivity().overridePendingTransition(R.anim.B_in, R.anim.A_out);
}
On B, I have the following onOptionsItemSelected and onBackPressed:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
getSupportFragmentManager().popBackStackImmediate();
//onBackPressed();
//finish();
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
super.onBackPressed();
overridePendingTransition(R.anim.A_in, R.anim.B_out);
}
Here is the problem: When I press back button, the animation at onBackPressed is taking place as expected. However, when I click on icon at top left in the actionbar, popBackStackImmediate is called and Android's default animation is played which is different. So:
How can I manage to get same animation as in onBackPressed?
Should I use onBackPressed() instead of popBackStackImmediate()? Will it give the same result as popBackStackImmediate do?
Any suggestions and best practices are welcome...
You could use .popBackStack() instead of popBackStackImmediate() then overrride the pendingTransition, that might work. Since these are both activities though, my inclination would be to call finish(); then overridePendingTransition().
Activity A starts Activity B. In Activity B, I have this method:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
NavUtils.navigateUpTo(this, new Intent(this,
ArticleListActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
When I press that home button, it takes me to Activity A as it should. However, onCreate is being called again. I do not want this behavior.
I'm guessing its because this implementation uses new Intent to previous item in the navigation stack. This is just code I got from Eclipse when creating the double pane project though. I looked around on stack overflow, and though it seems that using an Intent to go back is causing this behavior, I do not understand why Google would provide this in a default template.
How should I make this call differently so that onCreate is not called again when going back to Activity A?
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
just finish current activity it will take you on previous activity
if your previous activity is activity A then just use finish(); method instead of creating object of intent
As pointed out by #Rajesh you need to call onBackPressed().
Your code detects the home button press and creates a new ArticleListActivity class.However, you don't want to create a new class you only want to go back to your already created class/activity. so use onBackPressed() instead.
You can try to set the launch mode in the manifest, because the parent activity can be popped off the stack.
android:launchMode="singleTop"
In this way, the onCreate() is not called again.
#Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
I asked this question previously and thought it was working and deleted the question, but since have found this isn't working. I have a ViewPager in my app, with each Fragment of the ViewPager holding a ListView. When an item in the ListView is selected, I am starting a new activity in onListItemClick:
#Override
public void onListItemClick(ListView l, View v, int position, long id)
{
super.onListItemClick(l, v, position, id);
final Intent browser = new Intent(activity, Browser.class);
startActivity(browser);
}
The problem is that when I press either the back button, or the Home button in the Actionbar, the ViewPager has reset itself to show the first fragment.
This is the code I'm using for the Home button:
#Override
public boolean onOptionsItemSelected(final MenuItem item)
{
if (item.getItemId() == android.R.id.home) {
Intent intent = new Intent(this, Main.class);
startActivity(intent);
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
It was recommended, in my original question, to set the launch mode in the Android Manifest to singleTop, which I did for the startup activity as well as the activity launched from the ListView, but that didn't seem to fix it.
I thought about passing the ViewPager's position to the new activity, then retrieving it in onResume of the original activity and manually setting the ViewPager's position, but that seems really brute force to me.