V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
LancerXin
V2EX  ›  Android

探讨一个关于 Android Support 修改的问题

  •  
  •   LancerXin · 2017-02-15 14:15:36 +08:00 · 10131 次点击
    这是一个创建于 2840 天前的主题,其中的信息可能已经有所发展或是发生改变。

    需求是这样的,项目里用了 Android Support v7 的 Toolbar:

    mToolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(mToolbar);
    

    这样就可以直接用 Toolbar 里面的 OverflowButton 作为 Menu 的扩展:

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
          // Inflate the menu; this adds items to the action bar if it is present.
          getMenuInflater().inflate(R.menu.main, menu);
          return true;
    }
    

    现在需要对 OverflowButton 的弹出菜单做样式修改,已经修改的差不多了,发现弹出菜单的 minWidth 是定死的,由于菜单里的字比较少,弄一个很宽的菜单感觉很别扭. 一些代码 support v7 的源码:

    android.support.v7.view.menu.MenuAdapter:
    
    public class MenuAdapter extends BaseAdapter {
        static final int ITEM_LAYOUT = R.layout.abc_popup_menu_item_layout;
    .....
    }
    

    这里的 R.layout.abc_popup_menu_item_layout 就是弹出的 popuwindow 里 Listview 的 item 的 layout

    再看看具体布局:

    <android.support.v7.view.menu.ListMenuItemView
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="?attr/dropdownListPreferredItemHeight"
            android:minWidth="196dip"
            style="@style/RtlOverlay.Widget.AppCompat.PopupMenuItem">
    .........
    

    这里竟然固定将 android:minWidth 固定设置成了 196dip

    顿时一万头草泥马在心里路过....

    刚开始想用反射的方式将 ITEM_LAYOUT 改变成其它的值,但是 static final 修饰的没办法修改

    不到万不得以不想自己重写 OverflowButton 的逻辑,时间问题.

    请问大家有什么好的方法,比如通过 android studio 编译器将这个资源文件替换掉之类的?

    9 条回复    2017-02-15 18:06:49 +08:00
    saberpowermo
        1
    saberpowermo  
       2017-02-15 14:19:46 +08:00
    我们 title 全都是自己写, 为的不是 自己写的比官方的好 就是因为怕碰见你这种情况。
    LancerXin
        2
    LancerXin  
    OP
       2017-02-15 14:28:55 +08:00
    @saberpowermo 之前也是自己写的,最近大改版成 Material Design 风格,我想着官方的应该比较好用吧,没想到还有扩展性这么差的控件...
    michaelzhou
        3
    michaelzhou  
       2017-02-15 14:37:15 +08:00
    有个不是很优雅的办法,但至少能解决你的问题:

    在那之前把那个 xml 直接给替换掉

    Field field = MenuPopupHelper.class.getDeclaredField("ITEM_LAYOUT");
    field.setAccessible(true);
    field.set(null, R.layout.custom_popup_menu_item_layout);
    bjzhou1990
        4
    bjzhou1990  
       2017-02-15 14:38:29 +08:00
    @LancerXin 官方很多控件扩展性都非常差,用官方的话加个 icon 会好看很多,也不需要自定义宽度了
    LancerXin
        5
    LancerXin  
    OP
       2017-02-15 14:46:59 +08:00
    @michaelzhou 这个方法我想过,你可以看看帖子后面几句话,ITEM_LAYOUT 的修饰是 final static int 用反射并不能修改这个值,如果是 final static Integer 或许可以,int 是基本类型,在 jvm 存储的地方是不同的.
    KNOX
        6
    KNOX  
       2017-02-15 17:27:04 +08:00
    自己写 PopupWIndow ?
    LancerXin
        7
    LancerXin  
    OP
       2017-02-15 17:36:35 +08:00
    @KNOX 自己写比较麻烦,耗时耗力.
    banxi1988
        8
    banxi1988  
       2017-02-15 17:44:55 +08:00
    MenuAdapter 不是公开的接口, 没什么扩展性,这没什么大问题.

    ```java
    /**
    * @hide
    */
    @RestrictTo(LIBRARY_GROUP)
    public class MenuAdapter extends BaseAdapter {
    ```
    LancerXin
        9
    LancerXin  
    OP
       2017-02-15 18:06:49 +08:00
    @banxi1988 这并不是重点,重点是我已经这么用了,有什么简单的方法挽救?

    如果找不到答案我就只能放弃用官方的 Toolbar 了.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5938 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 02:17 · PVG 10:17 · LAX 18:17 · JFK 21:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.