Android中如何为属性设置两个值叠加?如layout_height=match_parent+?actionBarSize
实现LinearLayout高度为match_parent + actionBarSize的方法
XML布局属性不支持直接写match_parent+?actionBarSize这种叠加语法,得用下面几种方式实现需求:
方法一:动态代码设置高度
在Activity或Fragment里拿到目标LinearLayout,先算出actionBar的像素高度,再结合父容器的高度来设置:
- 获取
?actionBarSize对应的像素值:
TypedValue tv = new TypedValue(); int actionBarHeight = 0; if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) { actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics()); }
- 监听布局完成事件,计算父容器高度后设置LinearLayout的高度:
LinearLayout linearLayout = findViewById(R.id.your_linear_layout); linearLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { // 移除监听,避免重复触发 linearLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this); // 拿到父容器的高度(也就是match_parent对应的高度) int parentHeight = ((ViewGroup) linearLayout.getParent()).getHeight(); // 更新LinearLayout的高度 ViewGroup.LayoutParams params = linearLayout.getLayoutParams(); params.height = parentHeight + actionBarHeight; linearLayout.setLayoutParams(params); } });
方法二:用ConstraintLayout嵌套实现
如果项目里用ConstraintLayout当父布局,可以通过约束间接实现:
给LinearLayout设置填充父容器的约束,再添加一个高度为?actionBarSize的辅助View,让LinearLayout的底部超出父容器范围(要让父容器允许子View超出,需加android:clipChildren="false"):
<androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent" android:clipChildren="false"> <LinearLayout android:id="@+id/your_linear_layout" android:layout_width="match_parent" android:layout_height="0dp" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent"/> <View android:layout_width="match_parent" android:layout_height="?actionBarSize" app:layout_constraintTop_toBottomOf="@id/your_linear_layout" app:layout_constraintBottom_toBottomOf="parent"/> </androidx.constraintlayout.widget.ConstraintLayout>
这样LinearLayout的实际高度就是父容器高度加上actionBar的高度。
方法三:自定义LinearLayout重写测量逻辑
自己写一个LinearLayout子类,在测量阶段直接叠加高度:
public class ExtendedHeightLinearLayout extends LinearLayout { private int actionBarHeight = 0; public ExtendedHeightLinearLayout(Context context) { super(context); init(context); } public ExtendedHeightLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public ExtendedHeightLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } private void init(Context context) { // 初始化时获取actionBar的高度 TypedValue tv = new TypedValue(); if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) { actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics()); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // 拿到match_parent对应的高度值 int parentHeight = MeasureSpec.getSize(heightMeasureSpec); // 重新生成高度测量规则,叠加actionBar高度 int newHeightSpec = MeasureSpec.makeMeasureSpec(parentHeight + actionBarHeight, MeasureSpec.EXACTLY); super.onMeasure(widthMeasureSpec, newHeightSpec); } }
之后在XML里直接使用这个自定义View就行:
<com.yourpackage.ExtendedHeightLinearLayout android:layout_width="match_parent" android:layout_height="match_parent"/>
内容的提问来源于stack exchange,提问作者TP SINGH
相关产品推荐
相关产品推荐

