[转]微信零基础美化反编译教程 – 9 – 修改输入框的背景与下划线

修改输入框背景展开目录

我们再次回到我们定位到的输入框的布局文件 g0.xml,获取输入框的背景图的资源 ID:

获取背景 ID

定位到输入框背景,是一张点九图:

可以发现其中有两个文件夹中都有输入框背景,从文件夹名也可以看出分别适配的是不同的 dpi,两个文件我们都需要替换为我们已经处理好的输入框背景点九图

这里输入框背景图要注意,如果是使用和我一样的类似的周围镂空的圆角背景,那么周围的颜色应当填充成聊天背景色,而不是使用透明颜色,我一开始想当然的,认为聊天背景延伸到画面最下方,而输入框是覆盖在下方的聊天背景之上,但是事实是输入框由于布局的原因,占据了下方的一部分位置,如果将输入框周围镂空的部分处理成透明,将会导致从主界面点击进入聊天后.. 从镂空的地方可以看到下方主界面的画面,想象一下就好.. 我就不演示了

我自己对于如何解决这个问题也有研究.. 奈何自己能力不足,暂时给不出一个良好的解决方案,只能先放着了,等学好 Java 再来..

两个文件都需要替换

重启微信查看效果:

需要继续调整

输入框背景和下面的选择表情的面板背景一并被替换了,而选择表情的各种按钮需要调整,我们先用「开发者助手」获取 ID 并搜索定位布局文件:

按部就班

打开 aa0.xml,代码我已经贴在下面,但在看代码之前,我们先要明确我们要找什么

选择表情界面的底部

从上图可以看出,我们需要做的首先是把被反复套用的输入框背景图去掉,让按钮看起来不会这么奇怪,我们之前找到的输入框背景图的 ID 是 7F020118,所以我们只需要把下面这个布局文件的调用了这个 ID 的部分去掉即可,我在代码中标识了出来:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:mm="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:id="@7F10110F"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.tencent.mm.plugin.emoji.ui.smiley.SmileyPanelViewPager
        android:id="@7F101110"
        android:scrollbars="none"
        android:fadingEdge="none"
        android:fadingEdgeLength="0dp"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:listSelector="@7F0204DC"
        android:layout_weight="1"
        android:layout_above="@7F101111"
        android:layout_alignParentTop="true"
        android:fadeScrollbars="false" />
    <com.tencent.mm.plugin.emoji.ui.smiley.SmileyPanelScrollView
        android:gravity="center"
        android:orientation="horizontal"
        android:id="@7F101111"
        android:visibility="invisible"
        android:layout_width="match_parent"
        android:layout_height="@7F0C02FF"
        android:layout_above="@7F101112"
        mm:dot_count="1" />
    <LinearLayout
        android:orientation="horizontal"
        android:id="@7F101112"
        android:layout_width="match_parent"
        android:layout_height="@7F0C025A"
        android:layout_toRightOf="@7F101113"
        android:layout_alignParentBottom="true">
        <com.tencent.mm.ui.base.HorizontalListViewV2
            android:id="@7F101114"
            android:background="@7F020118" 这里出现了第一次调用
            android:scrollbars="none"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:overScrollMode="never" />
        <ImageButton 
            android:layout_gravity="right"
            android:id="@7F101115"
            android:background="@7F020118" 这里是第二次调用
            android:layout_width="@7F0C025C"
            android:layout_height="@7F0C025B"
            android:src="@7F0701BE" />
    </LinearLayout>
    <FrameLayout
        android:layout_gravity="left"
        android:id="@7F101113"
        android:background="@7F020118" 这里是第三次调用
        android:layout_width="@7F0C025E"
        android:layout_height="@7F0C025A"
        android:layout_alignTop="@7F101112"
        android:layout_alignParentBottom="true">
        <ImageView
            android:gravity="center"
            android:layout_gravity="left"
            android:id="@7F101116"
            android:background="@7F020114"
            android:clickable="true"
            android:layout_width="@7F0C025E"
            android:layout_height="@7F0C025A"
            android:src="@7F07014B"
            android:scaleType="center"
            android:minWidth="60dp"
            android:minHeight="@7F0C014D" />
        <ImageView
            android:textSize="@7F0C015D"
            android:textStyle="bold"
            android:textColor="@7F0F02AD"
            android:layout_gravity="center|right|top"
            android:id="@7F101117"
            android:background="@7F070149"
            android:visibility="gone"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="@7F0C0154"
            android:scaleType="center" />
    </FrameLayout>
    <TextView
        android:textSize="@7F0C0109"
        android:textColor="@7F0F02E0"
        android:gravity="center"
        android:layout_gravity="right"
        android:id="@7F100DB8"
        android:background="@7F020117"
        android:visibility="gone"
        android:layout_width="wrap_content"
        android:layout_height="@7F0C025A"
        android:minWidth="60dp"
        android:minHeight="@7F0C014D"
        android:text="@7F0801A0"
        android:layout_alignTop="@7F101114"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true" />
</RelativeLayout>

可以看到以上三次调用的语句都是定义了 android:background 这个属性,我们只需要把这三个属性去掉即可,重启微信看看效果:

自然一些了

可以看到已经自然一些了,现在我们还需要把定义按钮本身的 drawable xml(类似之前修改语音按钮时修改的 xml) 修改一下,使它在不被选中、按压的时候保持透明,但是要如何在布局文件中辨别出哪一个是被调用的 drawable xml 呢?

如果在看之前的部分,足够细心的话,应该会发现一个 ID 代表的文件类型只需要看这个 ID 的前四位就可以清楚了,如下图对应关系

而我们需要找的定义选择表情按钮背景的 drawable xml 属于 drawable,ID 应该是 7F02 开头的,而决定具体显示成什么样子的又一般是 android:backgroundandroid:src 以这个思路我们再次审视一下这一长串代码,同样,我也把可能是按钮背景的 drawable xml 的点标识在了代码里:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:mm="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:id="@7F10110F"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.tencent.mm.plugin.emoji.ui.smiley.SmileyPanelViewPager
        android:id="@7F101110"
        android:scrollbars="none"
        android:fadingEdge="none"
        android:fadingEdgeLength="0dp"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:listSelector="@7F0204DC"
        android:layout_weight="1"
        android:layout_above="@7F101111"
        android:layout_alignParentTop="true"
        android:fadeScrollbars="false" />
    <com.tencent.mm.plugin.emoji.ui.smiley.SmileyPanelScrollView
        android:gravity="center"
        android:orientation="horizontal"
        android:id="@7F101111"
        android:visibility="invisible"
        android:layout_width="match_parent"
        android:layout_height="@7F0C02FF"
        android:layout_above="@7F101112"
        mm:dot_count="1" />
    <LinearLayout
        android:orientation="horizontal"
        android:id="@7F101112"
        android:layout_width="match_parent"
        android:layout_height="@7F0C025A"
        android:layout_toRightOf="@7F101113"
        android:layout_alignParentBottom="true">
        <com.tencent.mm.ui.base.HorizontalListViewV2
            android:id="@7F101114"
            android:scrollbars="none"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:overScrollMode="never" />
        <ImageButton 
            android:layout_gravity="right"
            android:id="@7F101115"
            android:layout_width="@7F0C025C"
            android:layout_height="@7F0C025B"
            android:src="@7F0701BE" 
            上一行虽然是android:src,但是ID7F07开头,属于上文提到的raw类型,即svg矢量图,故可以排除/>
    </LinearLayout>
    <FrameLayout
        android:layout_gravity="left"
        android:id="@7F101113"
        android:layout_width="@7F0C025E"
        android:layout_height="@7F0C025A"
        android:layout_alignTop="@7F101112"
        android:layout_alignParentBottom="true">
        <ImageView
            android:gravity="center"
            android:layout_gravity="left"
            android:id="@7F101116"
            android:background="@7F020114" 
            上一行定义了background,同时也是7F02开头,列为怀疑对象
            android:clickable="true"
            android:layout_width="@7F0C025E"
            android:layout_height="@7F0C025A"
            android:src="@7F07014B" 显然这也是svg矢量图
            android:scaleType="center"
            android:minWidth="60dp"
            android:minHeight="@7F0C014D" />
        <ImageView
            android:textSize="@7F0C015D"
            android:textStyle="bold"
            android:textColor="@7F0F02AD"
            android:layout_gravity="center|right|top"
            android:id="@7F101117"
            android:background="@7F070149" 同上,也是svg矢量图
            android:visibility="gone"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="@7F0C0154"
            android:scaleType="center" />
    </FrameLayout>
    <TextView
        android:textSize="@7F0C0109"
        android:textColor="@7F0F02E0"
        android:gravity="center"
        android:layout_gravity="right"
        android:id="@7F100DB8"
        android:background="@7F020117" 
        同样,上一行也定义了background,并且调用的是drawable资源,但是这一段的开头是TextView,基本可以断定是「发送」按钮,而不是选择表情的按钮
        android:visibility="gone"
        android:layout_width="wrap_content"
        android:layout_height="@7F0C025A"
        android:minWidth="60dp"
        android:minHeight="@7F0C014D"
        android:text="@7F0801A0"
        android:layout_alignTop="@7F101114"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true" />
</RelativeLayout>

这样,我们大概确定下来其中的 7F020114 是用于定义按钮背景的 drawable xml,我们搜索一下来验证这个结论:

找到的确实是一个 xml 文件,我们打开这个 xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_selected="true"
        android:drawable="@7F02011A" />
    <item
        android:state_checked="true"
        android:drawable="@7F02011A" />
    <item
        android:state_focused="true"
        android:drawable="@7F02011A" />
    <item
        android:state_pressed="true"
        android:drawable="@7F02011A" />
    <item android:drawable="@7F020119" /> 
</selector>

有了上一个改语音按钮的基础,这一个 xml 里的内容就很明显了,倒数第二行定义的是平时的样子,其余的是按压、选中的样子,分别按 ID 找到这两个图,将平时的替换为 1*1 透明图,按压的替换为纯色图片即可,替换后重启微信:

替换完成后

基本就还算过得去了,现在再把发送按钮改一改,在上面对布局文件进行分析的时候已经看出来「发送」按钮具体是需要改哪一个按钮了,按部就班找到 drawable xml 并定位到图片然后替换图片即可,这里不再详细演示,把代码再贴一次好了:

  <TextView
        android:textSize="@7F0C0109"
        因为我想替换成一个发送的图片,所以文字就不想要了,和隐藏底栏文字一样,把文字的大小调整为0dp即可
        android:textColor="@7F0F02E0"
        android:gravity="center"
        android:layout_gravity="right"
        android:id="@7F100DB8"
        android:background="@7F020117" 
        同样,上一行也定义了background,并且调用的是drawable资源,但是这一段的开头是TextView,基本可以断定是「发送」按钮,而不是选择表情的按钮
        android:visibility="gone"
        android:layout_width="wrap_content"
        android:layout_height="@7F0C025A"
        android:minWidth="60dp"
        android:minHeight="@7F0C014D"
        android:text="@7F0801A0"
        android:layout_alignTop="@7F101114"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true" />

这样做完之后基本就完成了底部的修改

完成

去掉输入框下划线展开目录

我们可以看到输入框还有一个很影响观感的下划线,我们最好把它给去掉

下划线很难看

回到输入框的布局文件,g0.xml,经过一个简单的查找就可以把下面这一段揪出来:

<com.tencent.mm.ui.widget.MMEditText
    android:textColor="@7F0F004E"
    android:layout_gravity="bottom"
    android:id="@7F100441"
    android:layout_marginTop="8dp"
    android:maxHeight="@7F0C007E"
    android:minHeight="@7F0C007F"
    android:hint="@null"
    android:singleLine="false"
    android:layout_weight="1"
    android:inputType="textCapSentences|textMultiLine"
    style="@style/MMEditText$7F0D018E" />
</LinearLayout>

我们重点看最后的 style="@style/MMEditText$7F0D018E" 这一行,我在之前也有提到 style 是定义了被反复调用的样式,那么这个 style 指向的其实就是微信几乎所有的输入框的样式,我们按照它所给的 7F0D018E 这个 ID 去搜索会发现它指向一个 style,而在 MT 管理器中,style 里的条目打开是这样子的:

是的,都是一些不明所以的内容,而且这个样式的名字也被混淆了,并不是 MMEditText,我们再来看看 PC 端反编译后的 /value/styles.xml 中,这个样式长什么样子:

这样才能让人看得懂啊.. 各个值分别定义的是什么属性都一目了然了,而 MT 管理器的视图下看不到每一个条目分别定义的属性,也无法增加属性,这也是 MT 局部反编译的局限性

所以说还是希望大家能够从一开始修改的时候就直接用 APKDB 反编译再回编译一次,省的各种混淆看的心烦,能取消一点混淆就取消一点吧 (这里的 MMEditText 就是在反编译过程中被重命名的一部分内容)

我们看到它的 background 属性是 drawable/ez,我们到 k 文件夹下 (也就是实际的 drawable 文件夹),找到这个 ez.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_focused="true"
        android:drawable="@7F0203BE" />
    <item android:drawable="@7F0203BF" />
</selector>

然后分别把两个 ID 指向的文件替换成透明图片即可,这里不再演示了

文 / anson
LEAVE A REPLY
loading