Change the actionbar homeAsUpIndicator Programmatically

核能气质少年 提交于 2019-12-28 13:57:17

问题


I used the following hack to change the homeAsupIndicator programmatically.

int upId = Resources.getSystem().getIdentifier("up", "id", "android");
if (upId > 0) {
    ImageView up = (ImageView) findViewById(upId);
up.setImageResource(R.drawable.ic_action_bar_menu);
up.setPadding(0, 0, 20, 0);
}

But this is not working on most new phones (HTC One, Galaxy S3, etc). Is there a way that can be changed uniformly across devices. I need it to be changed only on home screen. Other screens would have the default one. So cannot use the styles.xml


回答1:


This is what i did to acheive the behavior. I inherited the base theme and created a new theme to use it as a theme for the specific activity.

<style name="CustomActivityTheme" parent="AppTheme">
    <item name="android:homeAsUpIndicator">@drawable/custom_home_as_up_icon</item>
</style>

and in the android manifest i made the activity theme as the above.

<activity
        android:name="com.example.CustomActivity"
        android:theme="@style/CustomActivityTheme" >
</activity>

works great. Will update again when i check on all devices I have. Thanks @faylon for pointing in the right direction




回答2:


The question was to change dynamically the Up Home Indicator, although this answer was accepting and it is about Themes and Styles. I found a way to do this programmatically, according to Adneal's answer which gives me the clue and specially the right way to do. I used the below snippet code and it works well on (tested) devices with APIs mentioned here.

For lower APIs, I use R.id.up which is not available on higher API. That's why, I retrieve this id by a little workaround which is getting the parent of home button (android.R.id.home) and its first child (android.R.id.up):

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
    // get the parent view of home (app icon) imageview
    ViewGroup home = (ViewGroup) findViewById(android.R.id.home).getParent();
    // get the first child (up imageview)
    ( (ImageView) home.getChildAt(0) )
        // change the icon according to your needs
        .setImageResource(R.drawable.custom_icon_up));
} else {
    // get the up imageview directly with R.id.up
    ( (ImageView) findViewById(R.id.up) )
        .setImageResource(R.drawable.custom_icon_up));
} 

Note: If you don't use the SDK condition, you will get some NullPointerException.




回答3:


API 18 has new methods ActionBar.setHomeAsUpIndicator() - unfortunately these aren't supported in the support library at this moment

http://developer.android.com/reference/android/app/ActionBar.html#setHomeAsUpIndicator(android.graphics.drawable.Drawable)

edit: these are now supported by the support library http://developer.android.com/reference/android/support/v7/app/ActionBar.html#setHomeAsUpIndicator(android.graphics.drawable.Drawable)




回答4:


All you need to do is to use this line of code:

getSupportActionBar().setDisplayHomeAsUpEnabled(true);

This will change the icon with the up indicator. To disable it later, just call this function again and pass false as the param.




回答5:


The solution by checking Resources.getSystem() doesn't work on all devices, A better solution to change the homeAsUpIndicator is to set it @null in style and change the logo resource programmatically.

Below is my code from style.xml

<style name="Theme.HomeScreen" parent="AppBaseTheme">
  <item name="displayOptions">showHome|useLogo</item>
  <item name="homeAsUpIndicator">@null</item>
  <item name="android:homeAsUpIndicator">@null</item>
</style>

In code you can change the logo using setLogo() method.

getSupportActionBar().setLogo(R.drawable.abc_ic_ab_back_holo_light); //for ActionBarCompat
getActionBar().setLogo(R.drawable.abc_ic_ab_back_holo_light); //for default actionbar for post 3.0 devices

Also note that the Android API 18 has methods to edit the homeAsUpIndicator programatically, refer documentation.




回答6:


You can achieve this in an easier way. Try to can change the homeAsUpIndicator attribute of actionBarStyle in your theme.xml and styles.xml.

If you want some padding, just add some white space in your image.




回答7:


You can try this:

this.getSupportActionBar().setHomeAsUpIndicator( R.drawable.actionbar_indicator ); //for ActionBarCompat
this.getActionBar().setHomeAsUpIndicator( R.drawable.actionbar_indicator ); //for default actionbar for post 3.0 devices

If you need change the position of the icon, you must create a drawable file containing a "layer-list" like this:

actionbar_indicator.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list
    xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:drawable="@drawable/indicator"
        android:right="5dp"
        android:left="10dp" />
</layer-list>



回答8:


use getActionBar().setCustomView(int yourView); because ActionBar haven't method to change homeUp icon!




回答9:


Adding to Fllo answer Change the actionbar homeAsUpIndicator Programamtically

I was able to use this hack on Android 4+ but could not understand why the up/home indicator was back to the default one when search widget was expanded. Looking at the view hierarchy, turns out that the up/home indicator + icon section of the action bar has 2 implementations and of course the first on is the one for when the search widget is not expanded. So here is the code I used to work around this and get the up/home indicator changed in both cases.

    mSearchItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
        @Override
        public boolean onMenuItemActionExpand(MenuItem item) {
            // https://stackoverflow.com/questions/17585892/change-the-actionbar-homeasupindicator-programamtically
            int actionBarId = getResources().getIdentifier("android:id/action_bar", null, null);
            View view = getActivity().getWindow().getDecorView().findViewById(actionBarId);
            if (view == null
                    || !(view instanceof ViewGroup)) {
                return true;
            }
            final ViewGroup actionBarView = (ViewGroup)view;

            // The second home view is only inflated after 
            // setOnActionExpandListener() is first called
            actionBarView.post(new Runnable() {
                @Override
                public void run() {
                    //The 2 ActionBarView$HomeView views are always children of the same view group
                    //However, they are not always children of the ActionBarView itself
                    //(depends on OS version)
                    int upId = getResources().getIdentifier("android:id/up", null, null);
                    View upView = actionBarView.findViewById(upId);
                    ViewParent viewParent = upView.getParent();
                    if (viewParent == null) {
                        return;
                    }
                    viewParent = viewParent.getParent();
                    if (viewParent == null
                            || !(viewParent instanceof ViewGroup)) {
                        return;
                    }

                    ViewGroup viewGroup = (ViewGroup) viewParent;
                    int childCount = viewGroup.getChildCount();
                    for (int i = 0; i < childCount; i++) {
                        View childView = viewGroup.getChildAt(i);
                        if (childView instanceof ViewGroup) {
                            ViewGroup homeView = (ViewGroup) childView;
                            upView = homeView.findViewById(upId);
                            if (upView != null
                                    && upView instanceof ImageView) {
                                Drawable upDrawable = getResources().getDrawable(R.drawable.ic_ab_back_holo_dark_am);
                                upDrawable.setColorFilter(accentColorInt, PorterDuff.Mode.MULTIPLY);
                                ((ImageView) upView).setImageDrawable(upDrawable);
                            }
                        }
                    }
                }
            });



回答10:


If someone uses the library support-v7 appcompat, you can directly call this method:

  • getSupportActionBar().setHomeAsUpIndicator(int redId)

In other case you can use this solution:

  • https://stackoverflow.com/a/23522910/944630



回答11:


If you are using DrawerLayout with ActionBarDrawerToggle, then check out this answer.




回答12:


this.getSupportActionBar().setDisplayUseLogoEnabled(true);
this.getSupportActionBar().setLogo(R.drawable.about_selected);

Also you can define the logo in manifest in attribute android:logo of and tags and set in theme that you want to use logo instead of app icon in the action bar.



来源:https://stackoverflow.com/questions/17585892/change-the-actionbar-homeasupindicator-programmatically

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!