How to change home as up resource programmatically?

前端 未结 6 1635
迷失自我
迷失自我 2020-12-25 15:02

I know how to change the homeAsUpIndicator in the styles xml file. The question is how to change it programmatically.

The reason I want to do it bec

相关标签:
6条回答
  • 2020-12-25 15:18

    Although this answer might achieve the expected behaviour, as you can read in the comments below it: "This hack does not work on some devices". I found another way according to Adneal's answer which gives me the clue and specially the right way to do.

    • Lower API: use id R.id.up to retrieve the related ImageView.

    • API >= 14: get the relative Parent of Home ImageView (android.R.id.home) and retrieve the first child which is the UpIndicator (android.R.id.up).

    Then, this snippet code changes dynamically the UpIndicator:

    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
            .setImageDrawable(getResources().getDrawable(R.drawable.custom_icon_up));
    } else {
        // get the up imageview directly with R.id.up
        ( (ImageView) findViewById(R.id.up) )
            .setImageDrawable(getResources().getDrawable(R.drawable.custom_icon_up));
    }  
    

    I have not tested on multiple devices (that's why I'm not sure this above code works for all devices), however this seems to work great in APIs mentioned in the update part here.

    Note: If you don't make the difference between higher and lower APIs, you will get a NullPointerException because R.id.up is not available in higher API while android.R.id.up is not available in lower API.

    0 讨论(0)
  • 2020-12-25 15:19

    This worked for me

    getSupportActionBar().setHomeAsUpIndicator(R.drawable.my_home_as_up)
    
    0 讨论(0)
  • 2020-12-25 15:22

    I write solution for this. It's not beautiful but works:

    public static ImageView getHomeAndUpIndicator(View decorView) {
        ImageView res = null;
    
        int upId = Resources.getSystem().getIdentifier("up", "id", "android");
        if (upId > 0) {
            res = (ImageView) decorView.findViewById(upId);
        } else {
            if (android.os.Build.VERSION.SDK_INT <= 10) {
                ViewGroup acbOverlay = (ViewGroup)((ViewGroup)decorView).getChildAt(0);
                ViewGroup abcFrame = (ViewGroup)acbOverlay.getChildAt(0);
                ViewGroup actionBar = (ViewGroup)abcFrame.getChildAt(0);
                ViewGroup abLL = (ViewGroup)actionBar.getChildAt(0);
                ViewGroup abLL2 = (ViewGroup)abLL.getChildAt(1);
                res = (ImageView)abLL2.getChildAt(0);
            } else if (android.os.Build.VERSION.SDK_INT > 10 && android.os.Build.VERSION.SDK_INT < 16) {
                ViewGroup acbOverlay = (ViewGroup)((ViewGroup)decorView).getChildAt(0);
                ViewGroup abcFrame = (ViewGroup)acbOverlay.getChildAt(0);
                ViewGroup actionBar = (ViewGroup)abcFrame.getChildAt(0);
                ViewGroup abLL = (ViewGroup)actionBar.getChildAt(1);
                res = (ImageView)abLL.getChildAt(0);
            } else {
                ViewGroup acbOverlay = (ViewGroup)((ViewGroup)decorView).getChildAt(0);
                ViewGroup abcFrame = (ViewGroup)acbOverlay.getChildAt(1);
                ViewGroup actionBar = (ViewGroup)abcFrame.getChildAt(0);
                ViewGroup abLL = (ViewGroup)actionBar.getChildAt(0);
                ViewGroup abF = (ViewGroup)abLL.getChildAt(0);
                res = (ImageView)abF.getChildAt(0);
            }
        }
        return res;
    }
    

    As a param put: getWindow().getDecorView()

    Test on few devices (nexus 7 (4.4.2), samsung galaxy s+ (2.3.6), yaiu g3 (4.2.2)) and emulators with android 2.3.3 and 4.1.1

    0 讨论(0)
  • 2020-12-25 15:24

    Here is working code

    final Drawable upArrow = getResources().getDrawable(R.drawable.ic_arrow_back_black_24dp);
            upArrow.setColorFilter(Color.parseColor("#000000"), PorterDuff.Mode.SRC_ATOP);
            getSupportActionBar().setHomeAsUpIndicator(upArrow);
    
    0 讨论(0)
  • 2020-12-25 15:29
    int upId = Resources.getSystem().getIdentifier("up", "id", "android");
    if (upId > 0) {
        ImageView up = (ImageView) findViewById(upId);
        up.setImageResource(R.drawable.ic_drawer_indicator);
    }
    
    0 讨论(0)
  • 2020-12-25 15:30

    The solution by @matthias 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.

    0 讨论(0)
提交回复
热议问题