【问题标题】:How to change home as up resource programmatically?如何以编程方式将 home 更改为 up 资源?
【发布时间】:2013-04-29 23:20:58
【问题描述】:

我知道如何change the homeAsUpIndicator in the styles xml file问题是如何以编程方式更改它

我想这样做的原因是因为在某些视图中我支持侧边导航(滑动菜单) - 按上/后标题按钮,显示侧边菜单。

在其他视图中,我支持自然向上/向后按钮。

因此,我想使用不同的指示器图标来指示两种不同的逻辑 - 侧边导航与向上/后退。

请不要争论这样做的动机。那是给定的状态。谢谢。

【问题讨论】:

  • 虽然在 Galaxy S3 设备上找到了资源 (upId),并定义了新的 ImageView,但这个 hack 不起作用。但是,当我在 Nexus 4 上进行测试时,工作正常。

标签: android android-actionbar


【解决方案1】:
int upId = Resources.getSystem().getIdentifier("up", "id", "android");
if (upId > 0) {
    ImageView up = (ImageView) findViewById(upId);
    up.setImageResource(R.drawable.ic_drawer_indicator);
}

【讨论】:

  • 工作,但感觉就像一个黑客。这有记录吗? up 以后可以改名吗?
  • 我会说这是一个 hack。然而,这是到达视图的唯一途径。将来可能会改变,但我无法想象发生这种情况的原因。
  • 正如 seufagner 所说,我确认这在 Samasung Galaxy S3 上工作。
  • 三星的固件是从安卓系统调整而来的。它实际上是指 android.R.id
  • 我检查一下。它不适用于 android 4.1.1 及更早版本(od 4.2.2+ 工作正常)
【解决方案2】:

@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 的方法,refer documentation

【讨论】:

    【解决方案3】:

    我为此编写解决方案。它不漂亮但有效:

    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 的模拟器上进行测试

    【讨论】:

      【解决方案4】:

      虽然this answer 可能会实现预期的行为,但您可以在其下方的 cmets 中阅读:“此 hack 不适用于某些设备”。我根据Adneal's answer 找到了另一种方法,它给了我线索,特别是正确的方法。

      • 较低的 API:使用 id R.id.up 检索相关的ImageView

      • API >= 14:获取 Home ImageView (android.R.id.home) 的相对 Parent 并检索第一个子元素 UpIndicator ( android.R.id.up)。

      然后,这个sn-p代码动态改变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));
      }  
      

      我没有在多个设备上测试过(这就是为什么我不确定上面的代码是否适用于所有设备),但是这似乎在the update part here 中提到的 API 中运行良好。

      注意:如果您不区分较高和较低的 API,您将收到 NullPointerException,因为 R.id.up 在较高的 API 中不可用,而 android.R.id.up 在较低的 API 中不可用。 em>

      【讨论】:

        【解决方案5】:

        这对我有用

        getSupportActionBar().setHomeAsUpIndicator(R.drawable.my_home_as_up)
        

        【讨论】:

        • 有没有办法在使用getSupportActionBar()时添加左边距?谢谢
        【解决方案6】:

        这是工作代码

        final Drawable upArrow = getResources().getDrawable(R.drawable.ic_arrow_back_black_24dp);
                upArrow.setColorFilter(Color.parseColor("#000000"), PorterDuff.Mode.SRC_ATOP);
                getSupportActionBar().setHomeAsUpIndicator(upArrow);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-19
          • 1970-01-01
          • 1970-01-01
          • 2011-01-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多