[已解决]Android 5.0之后的机器上面, Android Button 总是显示在FrameLayout的最前面

在Android 5.0及更高版本中,由于Material Design的引入,Button默认的TranslationZ导致其显示在其他视图之上。通过设置TextView的TranslationZ或Elevation值高于Button的Z值,或者将Button的StateListAnimation设为null,可以避免此问题。解决方案包括在XML布局或代码中调整组件属性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

测试了Android 5.0.1 Android 6.0.1机器上面都有这个问题。


布局代码:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.zhangyinshan.framelayouttest.MainActivity">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:textAlignment="center"
        android:text="Hello World!"
        android:id="@+id/hello"
        android:textSize="26sp" />
    <TextView
        android:id="@+id/up"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@android:color/holo_red_light"
        android:text="UP"
        android:textSize="26sp"
        android:layout_gravity="center"
        android:textAlignment="center"
        />

</FrameLayout>





这个是因为Android 5.0之后引入了一个Material Design的概念 

https://developer.android.com/training/material/shadows-clipping.html?hl=zh-cn 


视图的 Z值包含两个组件:

  • 高度(Elevation):静态组件。Elevation
  • 转换(Translation):用于动画的动态组件。

Z = elevation + translationZ

这里TranslationZ就是指的在Z轴上面的转换,注意转换,主要是用于动画的动态的组件,例如Button,它在按下去的时候是0dp的高度,正常的状态下是6dp的高度。所以Z = elevation + translationZ




在MainActivity中执行测试:


public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Button button = (Button)findViewById(R.id.hello);

        //设置触摸监听
        button.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                //当当前的android 的版本大于21,也就是5.0以上的时候,去检测Elevation 和TranslationZ
                if(Build.VERSION.SDK_INT>=21) {
                    switch (motionEvent.getAction()){
                        case MotionEvent.ACTION_DOWN:
                            Log.d("kodulf", "按下去的时候 Elevation="+button.getElevation() + "  TranslationZ=" + button.getTranslationZ());
                            break;
                        case MotionEvent.ACTION_UP:
                            Log.d("kodulf", "弹上来的时候 Elevation="+button.getElevation() + "  TranslationZ=" + button.getTranslationZ());
                            break;
                    }

                }
                return false;
            }
        });
    }
}

结果:

03-30 22:57:21.191 17218-17218/com.example.framelayouttest D/kodulf: 按下去的时候 Elevation=3.0  TranslationZ=0.0
03-30 22:57:21.364 17218-17218/com.example.framelayouttest D/kodulf: 弹上来的时候 Elevation=3.0  TranslationZ=6.0
03-30 22:57:22.517 17218-17218/com.example.framelayouttest D/kodulf: 按下去的时候 Elevation=3.0  TranslationZ=0.0
03-30 22:57:22.915 17218-17218/com.example.framelayouttest D/kodulf: 弹上来的时候 Elevation=3.0  TranslationZ=6.0

从结果可以看出:

在Android 5.0 之后的版本中,按钮Button 都会有一个TranslationZ的值,默认的没有点击的时候是6dp,如果点击了按下去了就是0dp


解决办法:

1: 给最上面的TextView设置一个TranslationZ或者是Elevation设置一个高的值,这个值要比上面测试的结果6+3=9大,就是至少10

就是上面的公式:Z = elevation + translationZ

这里TextView的Z值一定要比Button的Z值要大

        android:elevation="10dp"
        android:translationZ="10dp"


2: 将Button的动画的StateListAnimation设置为null,因为如果将Button的StateListAnimation 取消了Translation就会变成0了

android:stateListAnimator="@null"



解决办法1实例:

可以在xml布局中设置,也可以在代码中设置

在xml中设置:给最上面的TextView设置elevation或者设置translationZ,只要设置一个就可以了,两个都设置也可以的

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.zhangyinshan.framelayouttest.MainActivity">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:textAlignment="center"
        android:text="Hello World!"
        android:id="@+id/hello"
        android:textSize="26sp" />
    <TextView
        android:id="@+id/up"
        android:elevation="10dp"
        android:translationZ="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@android:color/holo_red_light"
        android:text="UP"
        android:textSize="26sp"
        android:layout_gravity="center"
        android:textAlignment="center"
        />

</FrameLayout>


在代码中设置:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Button button = (Button)findViewById(R.id.hello);
        final TextView upTextView = (TextView)findViewById(R.id.up);
        //如果android 的版本大于21,也就是5.0以上的时候,去设置Elevation 和TranslationZ
        if(Build.VERSION.SDK_INT>21) {
            upTextView.setElevation(10);
            upTextView.setTranslationZ(10);
        }

        //每一秒钟检测一次
        button.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                //当当前的android 的版本大于21,也就是5.0以上的时候,去检测Elevation 和TranslationZ
                if(Build.VERSION.SDK_INT>=21) {
                    switch (motionEvent.getAction()){
                        case MotionEvent.ACTION_DOWN:
                            Log.d("kodulf", "Button按下去的时候 Elevation="+button.getElevation()
                                    + "  TranslationZ=" + button.getTranslationZ()
                                    +" Z = Elevation+TranslationZ = "+(button.getElevation()+button.getTranslationZ()));
                            Log.d("kodulf","Button按下去的时候 upTextView Z = "
                                    + "  TranslationZ=" + upTextView.getTranslationZ()
                                    +" Z = Elevation+TranslationZ = "+(upTextView.getElevation()+upTextView.getTranslationZ()));
                            break;
                        case MotionEvent.ACTION_UP:
                            Log.d("kodulf", "Button弹上来恢复的时候 Elevation="+button.getElevation()
                                    + "  TranslationZ=" + button.getTranslationZ()
                                    +" Z = Elevation+TranslationZ = "+(button.getElevation()+button.getTranslationZ()));
                            Log.d("kodulf","Button弹上来恢复的时候 upTextView Z="
                                    + "  TranslationZ=" + upTextView.getTranslationZ()
                                    +" Z = Elevation+TranslationZ = "+(upTextView.getElevation()+upTextView.getTranslationZ()));
                            break;
                    }

                }
                return false;
            }
        });
    }
}
结果:


03-30 23:41:51.633 29545-29545/com.example.framelayouttest D/kodulf: Button按下去的时候 Elevation=3.0  TranslationZ=0.0 Z = Elevation+TranslationZ = 3.0
03-30 23:41:51.634 29545-29545/com.example.framelayouttest D/kodulf: Button按下去的时候 upTextView Z =   TranslationZ=10.0 Z = Elevation+TranslationZ = 20.0
03-30 23:41:51.734 29545-29545/com.example.framelayouttest D/kodulf: Button弹上来恢复的时候 Elevation=3.0  TranslationZ=5.6289196 Z = Elevation+TranslationZ = 8.62892
03-30 23:41:51.735 29545-29545/com.example.framelayouttest D/kodulf: Button弹上来恢复的时候 upTextView Z=  TranslationZ=10.0 Z = Elevation+TranslationZ = 20.0


现在就显示正常了:可以看到TextView 显示在Button上面了




解决办法2实例:

将Button的动画的StateListAnimation设置为null,因为如果将Button的StateListAnimation 取消了Translation就会变成0了,也分为布局中设置和代码中设置

android:stateListAnimator="@null"

布局中设置:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.zhangyinshan.framelayouttest.MainActivity">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:textAlignment="center"
        android:text="Hello World!"
        android:id="@+id/hello"
        android:stateListAnimator="@null"
        android:textSize="26sp" />
    <TextView
        android:id="@+id/up"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@android:color/holo_red_light"
        android:text="UP"
        android:textSize="26sp"
        android:layout_gravity="center"
        android:textAlignment="center"
        />

</FrameLayout>


代码中:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Button button = (Button)findViewById(R.id.hello);

        final TextView upTextView = (TextView)findViewById(R.id.up);

        //如果android 的版本大于21,也就是5.0以上的时候,设置button的stateAnimator为null
        if(Build.VERSION.SDK_INT>21) {
            button.setStateListAnimator(null);
        }
        //如果android 的版本大于21,也就是5.0以上的时候,去设置Elevation 和TranslationZ
//        if(Build.VERSION.SDK_INT>21) {
//            upTextView.setElevation(10);
//            upTextView.setTranslationZ(10);
//        }

        //每一秒钟检测一次
        button.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                //当当前的android 的版本大于21,也就是5.0以上的时候,去检测Elevation 和TranslationZ
                if(Build.VERSION.SDK_INT>=21) {
                    switch (motionEvent.getAction()){
                        case MotionEvent.ACTION_DOWN:
                            Log.d("kodulf", "Button按下去的时候 Elevation="+button.getElevation()
                                    + "  TranslationZ=" + button.getTranslationZ()
                                    +" Z = Elevation+TranslationZ = "+(button.getElevation()+button.getTranslationZ()));
                            Log.d("kodulf","Button按下去的时候 upTextView Z = "
                                    + "  TranslationZ=" + upTextView.getTranslationZ()
                                    +" Z = Elevation+TranslationZ = "+(upTextView.getElevation()+upTextView.getTranslationZ()));
                            break;
                        case MotionEvent.ACTION_UP:
                            Log.d("kodulf", "Button弹上来恢复的时候 Elevation="+button.getElevation()
                                    + "  TranslationZ=" + button.getTranslationZ()
                                    +" Z = Elevation+TranslationZ = "+(button.getElevation()+button.getTranslationZ()));
                            Log.d("kodulf","Button弹上来恢复的时候 upTextView Z="
                                    + "  TranslationZ=" + upTextView.getTranslationZ()
                                    +" Z = Elevation+TranslationZ = "+(upTextView.getElevation()+upTextView.getTranslationZ()));
                            break;
                    }

                }
                return false;
            }
        });
    }
}

结果:

03-30 23:50:32.682 9981-9981/com.example.framelayouttest D/kodulf: Button按下去的时候 Elevation=0.0  TranslationZ=0.0 Z = Elevation+TranslationZ = 0.0
03-30 23:50:32.682 9981-9981/com.example.framelayouttest D/kodulf: Button按下去的时候 upTextView Z =   TranslationZ=0.0 Z = Elevation+TranslationZ = 0.0
03-30 23:50:32.804 9981-9981/com.example.framelayouttest D/kodulf: Button弹上来恢复的时候 Elevation=0.0  TranslationZ=0.0 Z = Elevation+TranslationZ = 0.0
03-30 23:50:32.804 9981-9981/com.example.framelayouttest D/kodulf: Button弹上来恢复的时候 upTextView Z=  TranslationZ=0.0 Z = Elevation+TranslationZ = 0.0


正确的截图:






参考:Button always displays on top in FrameLayout







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值