How to change home as up resource programmatically?
Solution 1
int upId = Resources.getSystem().getIdentifier("up", "id", "android");
if (upId > 0) {
ImageView up = (ImageView) findViewById(upId);
up.setImageResource(R.drawable.ic_drawer_indicator);
}
Solution 2
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.
Solution 3
This worked for me
getSupportActionBar().setHomeAsUpIndicator(R.drawable.my_home_as_up)
Solution 4
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 HomeImageView
(android.R.id.home) and retrieve the first child which is theUpIndicator
(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.
Solution 5
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
Related videos on Youtube
AlikElzin-kilaka
Love my family, life, animals and code. Love to save time, love to spend time and spending too much time deciding on what love should I spend time.
Updated on September 15, 2022Comments
-
AlikElzin-kilaka over 1 year
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 because in some views I support side navigation (sliding menu) - pressing the up/back title button, shows the side menu.
In other views I support the natural up/back botton.
Thus I would like to different indicator icons to indicate the two different logics - side navigation vs. up/back.
Please, lets not argue on the motivation of doing this. That's the given state. Thanks.
-
AlikElzin-kilaka almost 11 yearsWorks, but feels like a hack. Is this documented? Can the
up
name change in the future? -
Matthias Robbers almost 11 yearsI would say it is a hack. However, it is the only way to get to the view. It could be changed in the future but I can't imagine a reason for this to happen.
-
AlikElzin-kilaka almost 11 yearsAs seufagner said, I validated that this does not work on the Samasung Galaxy S3.
-
Lalith B over 10 yearsSamsung got their firmwares tweaked from android. it actually refers to android.R.id
-
Kenumir over 10 yearsi check it. it does not working on android 4.1.1 and older (od 4.2.2+ works fine)
-
MSIslam about 10 yearsIt works with Nexus 4.4, Samsung 4.1 device, but not with Samsung 2.3, Nexus 7 4.3 device!!! Any idea? Any work around way?
-
AndroidHacker about 10 years@matthias Its working like charm in higher version. But how we can make this work for lower version as well. ?
-
natsumiyu about 4 yearsIs there a way to add padding left when used
getSupportActionBar()
? Thank you