我知道如何更改样式 xml 文件中的 homeAsUpIndicator。问题是如何以编程方式更改它。
我想要这样做的原因是因为在某些视图中我支持侧边导航(滑动菜单) - 按向上/后退标题按钮,显示侧边菜单。
在其他观点中,我支持自然的向上/向后按钮。
因此,我想用不同的指示器图标来指示两种不同的逻辑 - 侧边导航与上/后。
请不要争论这样做的动机。那是给定的状态。谢谢。
我知道如何更改样式 xml 文件中的 homeAsUpIndicator。问题是如何以编程方式更改它。
我想要这样做的原因是因为在某些视图中我支持侧边导航(滑动菜单) - 按向上/后退标题按钮,显示侧边菜单。
在其他观点中,我支持自然的向上/向后按钮。
因此,我想用不同的指示器图标来指示两种不同的逻辑 - 侧边导航与上/后。
请不要争论这样做的动机。那是给定的状态。谢谢。
int upId = Resources.getSystem().getIdentifier("up", "id", "android");
if (upId > 0) {
ImageView up = (ImageView) findViewById(upId);
up.setImageResource(R.drawable.ic_drawer_indicator);
}
@matthias 的解决方案不适用于所有设备,更好的解决方案homeAsUpIndicator
是将其设置为 @null 样式并以编程方式更改徽标资源。
下面是我来自 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>
在代码中,您可以使用方法更改徽标setLogo()
。
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
另请注意,Android API 18
具有以编程方式编辑 homeAsUpIndicator 的方法,请参阅文档。
这对我有用
getSupportActionBar().setHomeAsUpIndicator(R.drawable.my_home_as_up)
尽管此答案可能会达到预期的行为,但您可以在下面的评论中阅读:“此黑客在某些设备上不起作用”。根据Adneal 的回答,我找到了另一种方法,这给了我线索,特别是正确的方法。
较低的 API:使用 id R.id.up来检索相关的ImageView
.
API >= 14:获取Parent
Home ImageView
( android.R.id.home ) 的亲戚并检索第一个子项UpIndicator
( android.R.id.up )。
然后,此代码段动态更改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));
}
我没有在多个设备上进行测试(这就是为什么我不确定上面的代码是否适用于所有设备),但是这似乎在此处更新部分提到的API 中效果很好。
注意:如果您不区分较高和较低的 API,您将收到 NullPointerException,因为R.id.up
在较高的 APIandroid.R.id.up
中不可用,而在较低的 API 中不可用。
我为此写了解决方案。它不漂亮但有效:
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;
}
作为参数:getWindow().getDecorView()
在少数设备(nexus 7 (4.4.2)、samsung galaxy s+ (2.3.6)、yaiu g3 (4.2.2))和带有 android 2.3.3 和 4.1.1 的模拟器上进行测试
这是工作代码
final Drawable upArrow = getResources().getDrawable(R.drawable.ic_arrow_back_black_24dp);
upArrow.setColorFilter(Color.parseColor("#000000"), PorterDuff.Mode.SRC_ATOP);
getSupportActionBar().setHomeAsUpIndicator(upArrow);