Add event when back arrow(getSupportActionBar().setDisplayHomeAsUpEnabled(true)) is clicked - java

My problem is almost the same as this Stop AsyncTask in Fragments when Back Button is pressed
But I want to stop my AsyncTask when the back arrow is clicked. I have a code in stoping asynctask and it works when I implemented it in another way. I tried what I researched so far but I still got errors. Please help me with this.
I tried this code
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id=item.getItemId();
if(id==android.R.id.home)
{
Intent returnIntent = new Intent();
returnIntent.putExtra("flag",userid);
setResult(Activity.RESULT_OK,returnIntent);
finish();
return true;
}}
UPDATED:
I am using this code to go to another fragment.
Fragment2 fragmentChild = new Fragment2 ();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.add(R.id.content, fragmentChild);
transaction.addToBackStack(null);
transaction.commit();
I have no problem in my backtrack when I go to another fragment. Then I'm using this code (getSupportActionBar().setDisplayHomeAsUpEnabled(true)) in my (Drawer.java) to show the back arrow. Now I want to add event when I clicked back arrow.
EDIT: (Drawer.java)
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
final ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
final View.OnClickListener originalToolbarListener = toggle.getToolbarNavigationClickListener();
getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
toggle.setDrawerIndicatorEnabled(false);
toggle.setToolbarNavigationClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getSupportFragmentManager().popBackStack();
}
});
} else {
toggle.setDrawerIndicatorEnabled(true);
toggle.setToolbarNavigationClickListener(originalToolbarListener);
}
}
});

If you properly setup the action bar, then you should be able to achive that with the following:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// Add the code to stop the task
break;
}
return super.onOptionsItemSelected(item);
}
EDIT: After you are able to handle the back button event, you can add the code to close the tasks in fragments. First of all, I created an interface that is implement by all fragments that should be able to close this tasks.
public interface TaskCancelFragment {
void cancelTask();
}
The implementation in fragments should look something like this:
#Override
public void cancelTask() {
//Add the code to cancel the task
Toast.makeText(getContext(), "The task is canceled", Toast.LENGTH_SHORT).show();
}
The final step is to send the event from activity to fragment. Here I will assume some things since I don't have access to your code to see how you add/find the fragments, but fortunately this doesn't matter so much and is easy to change. In addition to the initial answer, I created a new method in activity to find the current fragment and close the task.
private void cancelTasks() {
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.placeholder);
if (fragment instanceof TaskCancelFragment) {
((TaskCancelFragment) fragment).cancelTask();
}
}
And in the end, the case android.R.id.home looks like this:
case android.R.id.home:
cancelTasks();
onBackPressed(); // I think that you want to close the activity too
break;

Related

From second activity when press home back button do not came back same fragment in a activity

In my project 2 activity given - MainActivity & Second Activity.
in my main activity, I have four fragments, In the 3rd fragment, A button uses to go to the second activity.
I will implement the below code to go back
This code came back to me on MainActivity at home Fragment. but I went through the third fragment.so I want to come back to my third fragment. Please coders help me to solve this.
Also, help me when I go from fragment to fragment and want to come back to the same fragment.
In Manifest
<activity
android:name=".SecondActivity"
android:parentActivityName=".MainActivity"
android:exported="false" />
ThirdFragment
binding.goToSecondActivity.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent a = new Intent(getActivity(), SecondActivity.class);
a.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(a);
}
});
In Second activity
public class SecondActivity extends AppCompatActivity {
ActivitySecondBinding binding;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivitySecondBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
getSupportActionBar().setTitle("Second Page");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// code here
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
super.onBackPressed();
}
}
You should define a class, with a method getInstance accessible globally, that contains the last fragment visited, when you press back you should use the fragment manager to recreate the last fragment (found in the new class) and then, looking at the model of the selected fragment, repopulate it with the old data (if there are inputs/non static datas in the fragment)

Android Studio refresh the activity and display the current fragment

I am just starting with android studio, so excuse me for any mistakes. I am trying to switch the language of the app by using spinner menu. I have come over some methods to do this, but I was trying to simplify it and see if I can make this just by using onOptionsItemSelected method. Everything works fine and the language changes in the app, but only if I load another fragment in this activity. I was looking for a solution how to refresh the activity so that the user doesn't have to click any other button to see that the language has changed. I came up with a solution to finish the activity and make the intent to start it again, but here the problem starts. The activity restarts but it shows the default fragment which I assigned on the onCreate method. I don't know how to make it load the fragment which the user was currently seeing. It would be great if I could make the activity start loading from the onResume method, instead of onCreate again, I think it would show the current fragment. Is it even possible to do this? Is there any other easy way to make it show the current fragment with the new language? Maybe there's no easy way and I should start all over again? Please help me. This is what I've tried:
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
Configuration configuration = new Configuration();
Intent intent = new Intent();
switch (item.getItemId()){
case R.id.action_polski:
Locale localePl = new Locale("pl");
Locale.setDefault(localePl);
configuration.locale = localePl;
getBaseContext().getResources().updateConfiguration(configuration,getBaseContext().getResources().getDisplayMetrics());
finish();
startActivity(new Intent(this, MainActivity.class));
overridePendingTransition(0, 0);
break;
case R.id.action_english:
Locale localeEn = new Locale("en");
Locale.setDefault(localeEn);
configuration.locale = localeEn;
getBaseContext().getResources().updateConfiguration(configuration,getBaseContext().getResources().getDisplayMetrics());
finish();
startActivity(new Intent(this, MainActivity.class));
overridePendingTransition(0, 0);
break;
}
return true;
}
Unfortunately I can't just refresh the fragment. The entire activity has to be refreshed because otherwise the navigation drawer doesn't change the language, it stays in the previous language.
Edit: This is the code in onCreate, I add the fragment at the end of this code. But it's the home fragment, so whenever I "refresh" the activity with my method it loads the same fragment.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
hideSystemUI();
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
navigationView.bringToFront();
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar,
R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, new HomeFragment()).commit();
navigationView.setCheckedItem(R.id.nav_home);
}
}
Instead of start new with same Activity you should call recreate and inside onCreate method you have to check savedInstanceState == null before init default fragment
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
Configuration configuration = new Configuration();
Intent intent = new Intent();
switch (item.getItemId()){
case R.id.action_polski:
Locale localePl = new Locale("pl");
Locale.setDefault(localePl);
configuration.locale = localePl;
getBaseContext().getResources().updateConfiguration(configuration,getBaseContext().getResources().getDisplayMetrics());
recreate()
break;
case R.id.action_english:
Locale localeEn = new Locale("en");
Locale.setDefault(localeEn);
configuration.locale = localeEn;
getBaseContext().getResources().updateConfiguration(configuration,getBaseContext().getResources().getDisplayMetrics());
recreate()
break;
}
return true;
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState == null) {
// init default fragment
}
}

Android setting fragment toolbar title

I was having some minor bug with fragment transaction. The problem occurs when I opened up more than one fragment and press the back button and the title shown on toolbar is wrong.
For instance, from my Home -> Expenses fragment, and I press back button from Expenses fragment, the title shown on toolbar is correct.
However, let's say Home -> Expenses -> Incomes fragment, and I press back button from Incomes fragment, it will go back to Home fragment, but the title shown on toolbar will be 'Expenses' instead of 'Home'.
Here is my set up for MainActivity which extends AppCompatActivity:
// inside onCreate() put all these code
//Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
// This method will trigger on item Click of navigation menu
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
//Checking if the item is in checked state or not, if not make it in checked state
if(menuItem.isChecked()) menuItem.setChecked(false);
else menuItem.setChecked(true);
//Closing drawer on item click
drawerLayout.closeDrawers();
//Check to see which item was being clicked and perform appropriate action
final Bundle bundle = new Bundle();
switch (menuItem.getItemId()){
case R.id.home:
getSupportActionBar().setTitle("Home");
return true;
case R.id.expenses:
return true;
case R.id.incomes:
return true;
case R.id.history:
return true;
case R.id.setting:
return true;
}
}
});
Then inside each of my fragments which extends Fragment, I set the title and override the back button:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_expense,container,false);
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle("Expenses");
// override on back key pressed back to main fragment
v.setFocusableInTouchMode(true);
v.requestFocus();
v.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if( keyCode == KeyEvent.KEYCODE_BACK ) {
getFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle("Home");
return true;
} else {
return false;
}
}
});
return v;
}
I even added this line ((AppCompatActivity)getActivity()).getSupportActionBar().setTitle("Home"); to set the title when back button is on click but it is futile.
Try it this way: 1. In your activity override onBackPress:
#Override public void onBackPressed() {
if (count == 0) {
super.onBackPressed();
}
else {
getSupportFragmentManager().popBackStack(null,FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
}
Remove the KeyListener of the fragment.
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle("fragment title");
Just put this line in onCreateView() fragment.
and don't override back button in fragment override it in activity.

Go back to fragment of Activity A from Activity B

In my app, am using a navigation drawer (in Fragment A) to navigate to fragments:
public void displayView(int viewId){
Fragment fragment = null;
String title = getString(R.string.app_name);
switch (viewId) {
case R.id.nav_menu:
fragment = new MenuFragment();
title = getString(R.string.menu_title);
viewIsAtHome = false;
break;
case R.id.nav_reservation:
fragment = new ReservationFragment();
title = getString(R.string.reservation_title);
viewIsAtHome = false;
break;
...
if (fragment != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.commit();
}
// set the toolbar title
if (getSupportActionBar() != null) {
getSupportActionBar().setTitle(title);
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
}
}
displayView() is called in onNavigationItemSelected:
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
displayView(item.getItemId());
return true;
}
Now, in ReservationFragment I am displaying a list of reservations and a FloatingActionButton to start Activity B where the user can add a reservation if there are no reservations. When the user is done adding a reservation, I want to display it in the Reservation fragment. This requires me to "go back" to the Fragment.How do I accomplish this since Activity B knows nothing about Activity A?
What I've tried:
I tried creating a method in Activity A like this:
public void navigateToFragment(int viewId) {
displayView(R.id.nav_reservation);
}
and then called this method from Activity B:
saveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new MainActivity().navigateToFragment(R.id.nav_reservation);
//MainActivity is Activity A
}
});
the app crashes due to a nullPointerException in displayView() from the line:
String title = getString(R.string.app_name);
This isn't surprising since am creating a new MainActivity object that knows nothing about the previous state of the Activity, right?
This question mirrors my problem but is based on Settings so I can't really use the answer in my case.
How do I accomplish this task?
There are three quick methods that come to my mind. First you can start activityB with startActivityForResult and handle the result in activityA after user does what he wants in activityB. Second you can set activityA as singleTop and before finishing activityB you can startActivityA with clearTop an intent flag called clear_top(https://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_CLEAR_TOP).
Last but not the least, you can connect two activity by binding service in both activities and communicate via that service that you bound.

How to set back activity to Fragment classes?

I am developing an Android Application with navigation activity and there are some list of options in navigation drawer and my First page is also in this activity. I am navigating to another page through the options present in the navigation drawer which are Fragment classes. I need to come back to the first page if I press back button on device. But it goes to pages which I visited before. My Target is to come back to First page from the respective Fragment class.
At times when I hit back button, it also comes to my splash screen, Kindly help me to fix this. Thanks in advance.
This is the code of my FirstPage from where I am navigating to another pages through drawer. I need to come back to this same page again from the drawer (FirsPage)
public void selectDrawerItem(MenuItem menuItem) {
switch(menuItem.getItemId()) {
//1.User Profile
case R.id.navigation_item_attachment:
fragmentClass = ProfileTab.class;
// finish();
break;
//2.FeedBack
//case R.id.navigation_item_images:
/* fragmentClass = SearchHistoryTab.class;
break;*/
case R.id.navigation_refer:
fragmentClass = ReferFrndz.class;
// finish();
break;
case R.id.navigation_daily:
fragmentClass = DailyUsage.class;
break;
//4.About Us
case R.id.navigation_about:
fragmentClass = AboutJc.class;
break;
//4.Contact Us
case R.id.navigation_item_location:
fragmentClass = ContactJc.class;
break;
default:
break;
}
try {
fragment = (Fragment) fragmentClass.newInstance();
}
catch (Exception e) {
e.printStackTrace();
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.search_layout, fragment).commit();
menuItem.setChecked(true);
setTitle(menuItem.getTitle());
mDrawerLayout.closeDrawers();
}
I used Finish() but it didn't work. It terminating my entire application.
Splash Screen Code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread mythread = new Thread() {
public void run(){
try{
sleep(3000);
}catch(InterruptedException e){
e.printStackTrace();
}
finally {
.....
}
}
}
};
mythread.start();
}
Update your Fragmenttransaction code to add ProfileTab (FirstPage) in backstack entry.' So you get ProfileTab (FirstPage) back after click back button.
FragmentManager fragmentManager = getSupportFragmentManager();
if(fragment.equals(ProfileTab.class)){
fragmentManager.beginTransaction().replace(R.id.search_layout, fragment).addToBackStack("fragment_tag").commit();
//Only add backstack entry for first page so you get after click on back button
}
else
{
fragmentManager.beginTransaction().replace(R.id.search_layout, fragment).commit();
}
menuItem.setChecked(true);
setTitle(menuItem.getTitle());
mDrawerLayout.closeDrawers();
Use this solution and share your feedback with replay will help us to improve solution.

Categories