标签

Android 44

Android Network security configuration Android 网络配置 Android Camera Preview gradlew 源码分析 Android 动态修改菜单 Android RelativeLayout 之 Gravity 的使用 Android Studio Gradle Download Error Android加载子View 【转】Android打开与关闭软键盘 Android EditText软键盘显示隐藏以及“监听” Android mipmap文件夹 Android 用命令行更新SDK Android Service学习之AIDL, Parcelable和远程服务 Android 5.0设备中,Notification小图标是白色的 Android最佳实践 Android Keystore 文件的密码修改 Android Studio 中加载so库文件 Android 中方法重载遇到的问题 ListView & RecyclerView Google Volley如何缓存HTTP请求文件 Creating logs in Android applications Advanced Android TextView TextView高亮URL地址解析 TextView 高亮URL地址,并实现跳转 Best practices in Android development Android Sdk Manager无法更新问题解决办法 Android ViewPager滑动事件 Google Volley 网络请求框架(一) Andorid UI注入工具的使用(ButterKnife) Android 项目中出现的奇葩bug, 数据NullPointExcption Android Drawable Animation Android 图片的毛玻璃效果 Android之使用Log打印日志 使用Fidder来拦截Android发送的HTTP请求 Android之Webview使用 Android之Notification的使用(二) Android之Notification的使用(一) Android Keyboard Show&Hiden Android 粘贴板的使用 Android中使用.9.png 使用Fidder来拦截Android发送的HTTP请求 Andorid JUnit 单元测试 Activity之间的切换动画 Android ListView中Adapter的使用

Android RelativeLayout 之 Gravity 的使用

2015年12月29日

在xml中,ViewGroup用来控制view布局位置,我们可以使用android:gravity="center"来实现。但是很少会在RelativeLayout中使用,今天碰到了一个项目中的布局使用了这个属性。但是在印象中这个属性在RelativeLayout是不生效的。但是,在项目中,这个属性生效了,并且引起了一个问题。去百度了一下,好多人在博客里面写的这个属性在RelativeLayout不生效,在这里,我在强调一下,RelativeLayout中andorid:gravity属性是生效

so,我们先来看一下,布局代码是怎么写的:

activity_main.xml

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:background="@android:color/holo_blue_bright"
    android:gravity="center"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/center_view"
        android:layout_width="100dp"
        android:layout_height="50dp"
        android:background="@android:color/holo_green_light"
        android:gravity="center"
        android:layout_centerInParent="true"
        android:text="@string/hello_world"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@android:color/holo_orange_light"
        android:layout_below="@id/center_view"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="6dp"
        android:padding="6dp"
        android:text="下面的文本"/>

</RelativeLayout>

代码很简单,那我们在来看一下他的运行效果:

效果图

我那个擦,为什么下面那个TextView上的文字内容显示不完整,这尼玛什么情况,于是乎,我调整了一个RelativeLayout的高度,让他变高一点,改成android:layout_height="125dp", run了一下,居然正常了,如下图: 效果图

我特么的惊呆了,内心中一万只草泥马奔腾而过,上面那个图中,RelativeLayout中明明还有空白,为什么会导致下面的TextView的高度不够呢。

带着疑惑,我去看了一下Android RelativeLayout的源码,才发现,RelativeLayout 先按照不写gravity属性的时候来计算子View的高度:

在Nexcus下调试,得到控件的高度:
1.首先得到RelativeLayout的高度为200px
2.写Hello World!的TextView的height为100px
3.可以得到最下面的那个TextView 的高度为:
  height <= 200px / 2 - 100px / 2 - marginTop(12px) = 48px = 24dp
  很明显,24dp不够显示TextView的内容
  
那加了gravity属性过后,RelativeLayout将所有的Content作为一个整体,作了个居中,如下:
得到两个了控件的高度过后,就得到RelativeLayout contentHeight:

contentHeight = 100px + 12px + 48px = 160px
就可以得到上下的宽度分别为20px

RelativeLayout中源码实现:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    
    // 1. 判断是否有水平gravity与垂直gravity属性
    // 2. 排序子View,并计算子View的大小
    if (horizontalGravity || verticalGravity) { //如果有
        final Rect selfBounds = mSelfBounds;
        selfBounds.set(mPaddingLeft, mPaddingTop, width - mPaddingRight,
                height - mPaddingBottom);

        final Rect contentBounds = mContentBounds;
        Gravity.apply(mGravity, right - left, bottom - top, selfBounds, contentBounds,
                layoutDirection);

        final int horizontalOffset = contentBounds.left - left;
        final int verticalOffset = contentBounds.top - top;
        if (horizontalOffset != 0 || verticalOffset != 0) {
            for (int i = 0; i < count; i++) {
                final View child = views[i];
                if (child.getVisibility() != GONE && child != ignore) {
                    final LayoutParams params = (LayoutParams) child.getLayoutParams();
                    if (horizontalGravity) {
                        params.mLeft += horizontalOffset;
                        params.mRight += horizontalOffset;
                    }
                    if (verticalGravity) {
                        params.mTop += verticalOffset;
                        params.mBottom += verticalOffset;
                    }
                }
            }
        }
    }
}

所以,虽然下面有空隙,TextView 也拿到到足够的空间进行展示,导致TextView中的内容显示不完整



友情链接: Hiro's Blog | Junjun's Blog