Android Back Arrow icon on ActionBar not working - android

For some reason this activity has the back arrow in the actionbar, but when it is clicked it has no reaction, doesn't even seen to recognize the click. I have other activities that are similar that work fine though. Here is the code with some stuff removed:
public class LanguageActivity extends ActionBarActivity {
private static final String TAG = "LanguageActivity";
#InjectView(R.id.listView)
RecyclerView mRecyclerView;
#State
String selectedLang;
LangViewHolder selectedHolder = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Icepick.restoreInstanceState(this, savedInstanceState);
setContentView(R.layout.recyclerview);
ButterKnife.inject(this);
Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setTitle(R.string.ad_title_settings_lang);
selectedLang = PreferencesFacade.getInstance().getCurrentLang();
mRecyclerView.setLayoutManager(new TrueWrapContentLinearLayoutManager(this));
List<Pair<String, String>> langList = new LinkedList<>();
langList.add(Constants.Languages.US);
langList.add(Constants.Languages.LATIN_AMERICA_SPANISH);
mRecyclerView.setAdapter(new RecycleViewMappedArrayAdapter(R.layout.view_language_item, new LangViewHolder(mRecyclerView), langList));
}
#Override
protected void onSaveInstanceState(Bundle outState) {
Icepick.saveInstanceState(this, outState);
super.onSaveInstanceState(outState);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home:
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void finish() {
super.finish();
PreferencesFacade.getInstance().setCurrentLang(selectedLang);
Log.v(TAG, "Finishing?");
}
public class LangViewHolder extends RecycleViewMappedArrayAdapter.ViewHolder<Pair<String, String>>{
...
}
}
Manifest snippet:
<activity android:name=".activities.LanguageActivity"
android:parentActivityName=".activities.MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.MainActivity"/>
</activity>

This seems to be working for me:
Toolbar tBar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(tBar); // sets the Toolbar as the actionbar
tBar.setNavigationIcon(getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp));
tBar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed(); // calls the System onBackPressed method
}
});
Update:
getDrawable(int id) is depreciated so you should change this line of code:
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion >= Build.VERSION_CODES.LOLLIPOP){
tBar.setNavigationIcon(getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp, getApplicationContext().getTheme()));
} else {
tBar.setNavigationIcon(getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp));
}

why don't You extend AppCompatActivity(i think actionbaractivity is deprecated...)
?
and
Toolbar toolbar = (Toolbar) findViewById(R.id.the_id);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
//try this instead
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});

Related

Opening new activity from base activity

I have a base activity which holds toolbar that I need all over my activities. The toolbar consists of a textView on it. I need to handle click listener on that textView and open my MainActivity. I am not able to achieve it.
Here is my code:
public class BaseActivity extends AppCompatActivity implements View.OnClickListener {
private Toolbar toolbar;
private TextView txtLogin;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.profile_image:
startActivity(new Intent(this, ProfileActivity.class));
break;
case R.id.txtLogin:
startActivity(new Intent(this, LoginActivity.class));
break;
}
}
public void setUpToolbar() {
toolbar = findViewById(R.id.app_bar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
txtLogin = toolbar.findViewById(R.id.txtLogin);
txtLogin.setOnClickListener(this);
}
}
I am calling my setUpToolbar() method from my MainActivity.

How to handle back arrow click?

I am developing an Android app about music. In this app, I have two fragments: PopFragment e GenresFragment.
In the XML file of PopFragment called fragment_pop.xml, I have toolbar with a back arrow that goes back to GenresFragment.
My toolbar code is this:
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
>
<include
android:layout_height="wrap_content"
android:layout_width="match_parent"
layout="#layout/toolbar_layout"
/>
</android.support.design.widget.AppBarLayout>
<ImageButton
android:id="#+id/arrowPop"
android:layout_width="54dp"
android:layout_height="wrap_content"
android:src="#drawable/ic_arrow_back_black_24dp"
style="?android:attr/borderlessButtonStyle"
/>
In the Java file of PopFragment called PopActivity, I have some code but it's not working.
I have this code:
public class PopActivity extends AppCompatActivity implements View.OnClickListener {
public PopActivity() {
// Required empty public constructor
}
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_pop);
Toolbar toolbar = (Toolbar)findViewById(R.id.toolBar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
ImageButton backBtn = (ImageButton)findViewById(R.id.arrowPop);
}
#Override
public void onClick (View view) {
Intent i = new Intent();
switch (view.getId()) {
case R.id.arrowPop:
break;
}
}
Can you help me please?
Thank you
Try something like:
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
inflater.inflate(R.menu.your_menu, menu);
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home: {
getActivity().onBackPressed();
break;
}
}
return true;
}
You generally don't need to add your own arrow icon, the Toolbar should be able to handle it for you.
if(shouldShowArrow()) {
drawerLayout.setDrawerLockMode(LOCK_MODE_LOCKED_CLOSED, GravityCompat.START);
drawerToggle.setDrawerIndicatorEnabled(false);
MyActivity.this.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
} else { // hamburglar icon
drawerLayout.setDrawerLockMode(LOCK_MODE_UNLOCKED, GravityCompat.START);
MyActivity.this.getSupportActionBar().setDisplayHomeAsUpEnabled(false);
drawerToggle.setDrawerIndicatorEnabled(true);
}
drawerToggle.syncState();
And then you can define what happens when you click the arrow
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
drawerToggle = new ActionBarDrawerToggle(MyActivity.this, drawerLayout, toolbar, R.string.open, R.string.close) {
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
MyActivity.this.supportInvalidateOptionsMenu();
}
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
MyActivity.this.supportInvalidateOptionsMenu();
}
};
drawerLayout.setDrawerListener(drawerToggle);
drawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// what to do when you click the arrow
}
});
actionBar.setDisplayHomeAsUpEnabled(false);
actionBar.setHomeButtonEnabled(true);
}
#Override
protected void onPostCreate(Bundle bundle) {
super.onPostCreate(bundle);
drawerToggle.syncState();
}
#Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
drawerToggle.onConfigurationChanged(newConfig);
}
Use the following code as a quick fix, which mimics the back button being pressed.
switch (view.getId()) {
case R.id.arrowPop:
onBackPressed();
break;
}
Using this code, you shouldn't have to define the back button in the toolbar yourself, Android will handle it.
Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
Then when you click the back button, Android will call onBackPressed() for you.

How to implement android Toolbar Back button

I am using a custom toolbar. I need to add back button to it. Now I am using this code to add the back button.
Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
toolbar.setBackgroundColor(getResources().getColor(R.color.white));
toolbar.setNavigationIcon(getResources().getDrawable(R.drawable.back_arrow));
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
This works fine. I can see the back button added. But consider the case where I am in Fragment1 which has no back button. Now I move to Fragment2 and I add in Back Button. From Fragment 2 I open Fragment 3 and I add the back button again.
Now when I press back button from fragment3 to go back to fragment2 i have to check the Fragment Stack to see whether the back button is required in fragment 2 or not.
Is there any other way to handle back button automatically as we push fragments to stack?
Just add two new line of code. Something like this
Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
toolbar.setBackgroundColor(getResources().getColor(R.color.white));
toolbar.setNavigationIcon(getResources().getDrawable(R.drawable.back_arrow));
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
This assumes you are using an AppCompatActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.tool_bar); // Attaching the layout to the toolbar object
setSupportActionBar(toolbar);
// enabling action bar app icon and behaving it as toggle button
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
}
Then in the onOptionsItemSelected you can override the home button as follows:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
else if(id == android.R.id.home){
Intent i= new Intent(this, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
You can handle back icon very easily. If all of your fragment are in single Activity I really recommend to handle this with following way :
first crate a abstract BaseFragment class which implement FragmentManager .OnBackStackChangedListener then put following method inside that :
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainActivity = (MainActivity) getActivity();
getFragmentManager().addOnBackStackChangedListener(this);
shouldDisplayHomeUp();
}
#Override
public void onBackStackChanged() {
shouldDisplayHomeUp();
}
public boolean shouldDisplayHomeUp() {
//Enable Up button only if there are entries in the back stack
boolean canBack = false;
try {
canBack = getFragmentManager().getBackStackEntryCount() > 0;
} catch (Exception ex) {
// Log.e(getClass().getCanonicalName(), ex.getMessage());getMessage
}
if (canBack) {
mainActivity.drawerDisable();
} else {
mainActivity.drawerEnable();
}
return canBack;
}
By this way disableDrawer & enableDrawer function handle your Icon and OnBackPressed method handle your BackStack Now in your activity when you press back-icon display if needed. your onBackPressed should be something like this :
int backStackCount = getSupportFragmentManager().getBackStackEntryCount();
if (backStackCount == 0) {
//nothing exist in backStack OS handle it
super.onBackPressed();
} else {
getSupportFragmentManager().popBackStack();
}
See full implementation here.
use Method in Class your Activity
private void setupToolbar(){
Toolbar toolbar=(Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar=getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
It's works on back pressed function to toolbar
private setUpToolBar() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
}
i have Main activity and Four fragments.
In MainActivity i write this code
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
this is working fine and if you have fragments then create a onBackPressed() method
#Override
public void onBackPressed() {
int position = mViewPager.getCurrentItem();
if(position == 2) { // go back to search / result tab from info detail tab
mViewPager.setCurrentItem(2);
} else if(position == 0) { // switch from result to search tab or go back to home tab
SectionsPagerAdapter sectionsPagerAdapter = (SectionsPagerAdapter) mViewPager.getAdapter();
Fragment fragment = sectionsPagerAdapter.getItem(position);
if(fragment instanceof ResultFragment) {
Bundle bundle = ((ResultFragment) fragment).getArguments();
if(bundle != null) {
sectionsPagerAdapter.replaceFragment(SearchFragment.newInstance(bundle.getString(GlobalInfo.TAG_ID), bundle.getString(GlobalInfo.PART_NO), bundle.getString(GlobalInfo.SERIAL_NO), bundle.getString(GlobalInfo.PART_NAME)), getString(R.string.search), 0);
}
} else {
mViewPager.setCurrentItem(1);
}
}
else if(position == 3){
SectionsPagerAdapter sectionsPagerAdapter = (SectionsPagerAdapter) mViewPager.getAdapter();
Fragment fragment = new ToolMgtFragment();
sectionsPagerAdapter.replaceFragment(fragment,"Tool Mgt", 3);
}
else {
super.onBackPressed();
}
}

Add toolbar dynamically to an abstract activity

I have a base activity that all of my activities extend from. This class includes basics like a toolbar and a navigation drawer.
I am looking for a solution that will allow me to override a method in extended activities so I can change the type of toolbar that activity will use.
public abstract class BaseActivity extends AppCompatActivity {
private Toolbar mToolbar;
private FrameLayout mContentFrame;
private ActivityFragment mActivityFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(setLayout());
initViews();
initToolbar();
}
protected int setLayout() {
return R.layout.activity_base;
}
//I want to override this and provide a different toolbar layout!
protected int setToolbarLayout(){
return R.layout.toolbar;
}
protected void initViews() {
mToolbar = (Toolbar) findViewById(R.id.toolbar);
mContentFrame = (FrameLayout) findViewById(R.id.contentFrame);
}
private void initToolbar() {
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mToolbar.setElevation(10f);
}
}
protected void setContentFragment(ActivityFragment fragment) {
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(getContentFrame().getId(), fragment).commit();
supportInvalidateOptionsMenu();
this.mActivityFragment = fragment;
setTitle(fragment.getTitle(this));
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
public Toolbar getToolbar() {
return mToolbar;
}
public FrameLayout getContentFrame() {
return mContentFrame;
}
public ActivityFragment getActivityFragment() {
return mActivityFragment;
}
I have tried inflating the toolbar after setContentView() and setting the actionbar to it but it appeared with no icons or widgets!
Ok everyone (whoever it concerns) I figured it out. All I had to do was inflate my contentView prior to calling setContentView(). Once I have that inflated I add the inflated toolbar view!
public abstract class BaseActivity extends AppCompatActivity {
private Toolbar mToolbar;
private FrameLayout mContentFrame;
private ActivityFragment mActivityFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(inflateLayout());
initViews();
initToolbar();
}
protected int getLayoutRes(){
return R.layout.activity_base;
}
protected int getToolbarLayout(){
return R.layout.toolbar;
}
private View inflateLayout() {
View contentView = getLayoutInflater().inflate(getLayoutRes(), null, false);
attachToolbarToLayout(getLayoutInflater(), (ViewGroup) contentView);
return contentView;
}
private void attachToolbarToLayout(LayoutInflater inflater, ViewGroup parent){
mToolbar = (Toolbar) inflater.inflate(getToolbarLayout(),parent,false);
parent.addView(mToolbar,0);
}
protected void initViews() {
mContentFrame = (FrameLayout) findViewById(R.id.contentFrame);
}
private void initToolbar() {
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mToolbar.setElevation(10f);
}
}
protected void setContentFragment(ActivityFragment fragment) {
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(getContentFrame().getId(), fragment).commit();
supportInvalidateOptionsMenu();
this.mActivityFragment = fragment;
setTitle(fragment.getTitle(this));
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
public Toolbar getToolbar() {
return mToolbar;
}
public FrameLayout getContentFrame() {
return mContentFrame;
}
public ActivityFragment getActivityFragment() {
return mActivityFragment;
}

Drawer toggle not working as expected (icon remains the same)

I'm trying to implement an ActionBarDrawerToggle into my app but I can't make it. I've achieved to show the toggle in my toolbar, but the icon is the same always.
This is toggle's icon when drawer is closed:
http://i.stack.imgur.com/HTcom.png
And this is when drawer is opened:
http://i.stack.imgur.com/dX0Z2.png
As you can see, it doesn't change from ic_drawer to back arrow. ic_drawer is never shown.
So, here's my activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
initializeDrawer();
populateDrawer();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
}
private void initializeDrawer() {
tagTitles = getResources().getStringArray(R.array.item_names);
icons = getResources().getStringArray(R.array.item_icons);
dwLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
dwList = (ListView) findViewById(R.id.drawer_list);
dwList.setOnItemClickListener(new DrawerItemClickListener());
dwToggle = new ActionBarDrawerToggle(this, dwLayout, toolbar, R.string.drawer_open, R.string.drawer_close) {
public void onDrawerClosed(View view) {
getSupportActionBar().setTitle("pepe");
invalidateOptionsMenu();
}
public void onDrawerOpened(View drawerView) {
getSupportActionBar().setTitle("pop");
invalidateOptionsMenu();
}
};
dwLayout.setDrawerListener(dwToggle);
}
private void populateDrawer() {
ArrayList<DrawerItem> dwItems = new ArrayList<>();
for (int i = 0; i < tagTitles.length; i++) {
//ignore this; population is not properly working
dwItems.add(new DrawerItem(tagTitles[i], Resources.getSystem().getIdentifier("abc_ic_menu_copy_mtrl_am_alpha.png", "drawable", getBaseContext().getPackageResourcePath())));
}
dwList.setAdapter(new NavigationDrawerAdapter(this, dwItems));
}
#Override
public void onPostCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
super.onPostCreate(savedInstanceState, persistentState);
dwToggle.syncState();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (dwToggle.onOptionsItemSelected(item)) {
return true;
}
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
dwToggle.onConfigurationChanged(newConfig);
}
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
}
Thanks!
implement following method with DrawerLayout instace, in your case instance is dwLayout. implement following after this line
dwLayout.setDrawerListener(dwToggle);
add this
drawerLayout.post(new Runnable() {
#Override
public void run() {
// To display hamburger icon in toolbar
drawerToggle.syncState();
}
});
or you can do this as well
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState();
}

Categories

Resources