安卓:布局中使用android:gravity="left/right"提示使用start/end

本文详细解释了Android开发中布局文件的gravity属性设置方法,特别是left/right与start/end的区别。介绍了这两种属性在不同SDK版本和不同语言环境下的表现,并提供了最佳实践建议。

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

在AndroidStudio中,在布局文件中使用Android:gravity属性设置属性值为left或right时,会有对应的警告提示,提示内容如下:
这里写图片描述
这是由于从上面的警告内容中我们可以得知,当我们的minSdkVersion>=17时,使用start/end来代替left/right;当minSdkVersion<17时,旧的平台不支持RTL,start/end属性是未知的,会被忽略,所以要同时使用start/end和left/right

start/end与left/right有什么区别?

属性  说明
left    Push object to the left of its container, not changing its size.
right   Push object to the right of its container, not changing its size.
start   Push object to the beginning of its container, not changing its size.
end Push object to the end of its container, not changing its size.

left/right属于绝对对齐,而start/end会根据不同国家习惯改变。如阅读顺序是从左到右(LTR)的国家,start在左边,在阅读顺序是从右到左(RTL)的国家,start在右边。
参考:http://blog.youkuaiyun.com/tiewen/article/details/39925239

根据上述功能,优化包含边框的悬浮窗布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:clipChildren="true" android:clipToPadding="true" android:orientation="vertical"> <View android:id="@+id/drag_top" android:layout_width="wrap_content" android:layout_height="14dp" android:visibility="gone" android:layout_gravity="top" android:background="@color/milu_orange" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <View android:id="@+id/drag_left" android:layout_width="14dp" android:layout_height="match_parent" android:visibility="gone" android:background="@color/milu_orange" /> <LinearLayout android:id="@+id/content_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:paddingBottom="10dp"> <LinearLayout android:id="@+id/ll_draggable" android:layout_width="25dp" android:layout_height="25dp" android:layout_centerVertical="true" android:gravity="center"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/ml_chat_draggable" /> </LinearLayout> <TextView android:layout_width="43dp" android:layout_height="3dp" android:layout_centerInParent="true" android:background="@drawable/botton_yuan_ef_5" /> <LinearLayout android:id="@+id/ll_close" android:layout_width="25dp" android:layout_height="25dp" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:gravity="center"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/ml_bjlb_close" /> </LinearLayout> </RelativeLayout> <androidx.recyclerview.widget.RecyclerView android:id="@+id/rlv_messagr" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="5" android:scrollbars="none" /> <TextView android:layout_width="wrap_content" android:layout_height="0dp" android:background="@drawable/bg_redius_transparent_75" android:paddingHorizontal="15dp" android:layout_weight="1" android:paddingVertical="5dp" android:text="说点什么吧" android:textColorHint="@color/milu_color_99" /> </LinearLayout> <View android:id="@+id/drag_right" android:layout_width="14dp" android:layout_height="match_parent" android:visibility="gone" android:background="@color/milu_orange" /> </LinearLayout> <LinearLayout android:id="@+id/ll_bottom" android:layout_width="match_parent" android:layout_height="14dp" android:visibility="gone" android:layout_gravity="left|bottom" android:orientation="horizontal"> <View android:id="@+id/drag_bottom_left" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="@color/milu_orange" /> <View android:id="@+id/drag_bottom_right" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="@color/milu_orange" /> </LinearLayout> </LinearLayout>
07-03
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:app="http://schemas.android.com/apk/res-auto"> <data> <variable name="viewModel" type="com.tplink.tpmifi.viewmodel.SmsBoxViewModel" /> </data> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="top" android:addStatesFromChildren="true" android:background="@drawable/toolbar_background" android:minHeight="@dimen/titlebar_height"> <LinearLayout android:id="@+id/title_left" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_centerVertical="true" android:layout_marginStart="@dimen/titlebar_left_margin_start" android:background="@drawable/btn_bg" android:clickable="true" android:focusable="true" android:gravity="center" android:minWidth="@dimen/titlebar_height" android:minHeight="@dimen/titlebar_height" android:orientation="horizontal" android:visibility="visible" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> <ImageView android:id="@+id/title_left_icon" android:layout_width="@dimen/titlebar_action_image_size" android:layout_height="@dimen/titlebar_action_image_size" android:scaleType="centerInside" android:src="@drawable/arrow_back_white" android:visibility="visible" /> </LinearLayout> <com.tplink.design.text.TPTextView android:id="@+id/title_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginStart="@dimen/titlebar_title_name_margin_start" android:layout_toEndOf="@+id/title_left" android:layout_weight="1" android:fontFamily="sans-serif-medium" android:lines="1" android:textAlignment="gravity" android:textColor="@android:color/white" android:textSize="@dimen/tpds_all_text_size_18" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_bias="0" app:layout_constraintStart_toEndOf="@id/title_left" app:layout_constraintTop_toTopOf="parent" tools:text="Outbox" /> <com.tplink.design.text.TPTextView android:id="@+id/title_right_text1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginEnd="20dp" android:layout_toStartOf="@+id/title_right_text2" android:background="@drawable/btn_bg" android:gravity="center" android:lines="1" android:padding="@dimen/tpds_all_dp_16" android:text="@{viewModel.isAllItemSelected ? @string/common_deselect_all :@string/common_select_all }" android:textAlignment="gravity" android:textColor="@color/white" android:textSize="@dimen/tpds_all_text_size_16" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@id/title_right_text2" app:layout_constraintHorizontal_bias="1" app:layout_constraintStart_toEndOf="@id/title_name" app:layout_constraintTop_toTopOf="parent" app:visibleOrGone="@{viewModel.editing}" tools:visibility="visible" /> <com.tplink.design.text.TPTextView android:id="@+id/title_right_text2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_centerVertical="true" android:layout_marginEnd="16dp" android:background="@drawable/btn_bg" android:clickable="@{viewModel.totalMsgNum != 0 }" android:gravity="center" android:lines="1" android:padding="@dimen/tpds_all_dp_16" android:text="@{viewModel.editing ? @string/common_cancel : @string/common_edit }" android:textAlignment="gravity" android:textColor="@{viewModel.totalMsgNum != 0 ? @color/white : @color/title_bar_text_non_clickable }" android:textSize="@dimen/tpds_all_text_size_16" android:visibility="visible" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="1" app:layout_constraintStart_toEndOf="@id/title_right_text1" app:layout_constraintTop_toTopOf="parent" tools:text="@string/common_edit" /> </androidx.constraintlayout.widget.ConstraintLayout> </layout>
07-11
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/dialog_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="@dimen/dimen_84dp" android:orientation="vertical"> <com.google.android.material.appbar.COUIDividerAppBarLayout android:id="@+id/appbar" style="@style/CommonAppBarStyle" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/color_transparent" android:clickable="true" android:focusable="true" android:paddingLeft="@dimen/dimen_0dp" android:paddingRight="@dimen/dimen_0dp" app:elevation="@dimen/toolbar_elevation"> <com.coui.appcompat.toolbar.COUIToolbar android:id="@+id/toolbar" style="@style/COUIToolBarInAppBarLayoutStyle" android:layout_width="match_parent" android:background="@null" app:supportTitleTextAppearance="@style/textAppearanceSecondTitle" app:titleCenter="false" /> <com.coui.appcompat.tablayout.COUITabLayout android:id="@+id/tab_layout" android:background="@color/color_transparent" style="@style/COUISmallTabLayoutStyle" /> </com.google.android.material.appbar.COUIDividerAppBarLayout> <RelativeLayout android:id="@+id/content_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <com.filemanager.common.view.ViewPagerWrapperForPC android:id="@+id/view_pager_wrapper" android:layout_width="match_parent" android:layout_height="match_parent"> <com.filemanager.common.view.viewpager.RTLViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/appbar" android:clipChildren="false" android:clipToPadding="false" android:orientation="horizontal" /> </com.filemanager.common.view.ViewPagerWrapperForPC> </RelativeLayout> </LinearLayout> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:background="?attr/couiColorBackgroundElevatedWithCard" android:minHeight="@dimen/operation_btn_background_height"> <View android:id="@+id/button_divider" android:layout_width="match_parent" android:layout_height="@dimen/divider_background_height" android:layout_gravity="top" android:alpha="0" android:background="?attr/couiColorDivider" android:forceDarkAllowed="false" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <LinearLayout android:id="@+id/select_root_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginStart="@dimen/dimen_16dp" android:orientation="vertical"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:orientation="horizontal"> <TextView android:id="@+id/select_title_content" android:layout_width="match_parent" android:layout_height="match_parent" android:lineHeight="22dp" android:text="@string/not_selected_file" android:textAppearance="@style/couiTextHeadlineXS" android:textColor="?attr/couiColorLabelPrimary" android:textSize="16sp" android:visibility="visible" /> <ImageView android:id="@+id/select_arraw_up" android:layout_width="18dp" android:layout_height="18dp" android:src="@drawable/arrow_up" android:layout_marginLeft="@dimen/dimen_6dp" android:visibility="gone" android:layout_gravity="center"/> </LinearLayout> <TextView android:id="@+id/select_body_content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:lineHeight="20dp" android:textSize="14sp" android:textAppearance="?attr/couiTextBodyXS" android:textColor="?attr/couiColorLabelSecondary" android:visibility="gone" android:text="@string/selected_size"/> </LinearLayout> <View android:layout_width="0dp" android:layout_height="0dp" android:layout_weight="1"/> <com.coui.appcompat.button.COUIButton android:id="@+id/btn_add_file" style="@style/Widget.COUI.Button.Large" android:layout_width="@dimen/dimen_96dp" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginEnd="@dimen/dimen_16dp" android:text="@string/label_add_recent_file" /> </LinearLayout> </FrameLayout> </FrameLayout>这是这个页面
最新发布
07-29
拖拽边框让宽高同时改变,右、右下边框功能一致,左、左下边框功能一致。优化下面代码 package com.maiyou.maiysdk.util.window.draggable; import android.view.MotionEvent; import android.view.View; import com.maiyou.maiysdk.util.DeviceUtil; import com.maiyou.maiysdk.util.DisplayUtil; import com.maiyou.maiysdk.util.ResourceUtil; import com.maiyou.maiysdk.util.window.EasyWindow; public class ResizeDraggable extends BaseDraggable { private static int MIN_SIZE = 0; // 最小尺寸(px) private static int MAX_SIZE = 0; // 最大尺寸(px) private int mInitialWidth; private int mInitialHeight; private int mInitialX; private int mInitialY; private int mFixedCornerX; // 固定角点X坐标 private int mFixedCornerY; // 固定角点Y坐标 private boolean isResizing = false; private int mCornerType; // 当前操作的角落类型 // 角落类型常量 private static final int CORNER_TOP_LEFT = 1; private static final int CORNER_TOP_RIGHT = 2; private static final int CORNER_BOTTOM_LEFT = 3; private static final int CORNER_BOTTOM_RIGHT = 4; @Override public boolean isTouchMoving() { return isResizing; } @Override public void start(EasyWindow<?> easyWindow) { super.start(easyWindow); // 移除宽高比约束,允许自由调整 MIN_SIZE = DisplayUtil.dip2px(easyWindow.getContext(),150); MAX_SIZE = DisplayUtil.dip2px(easyWindow.getContext(),300); } @Override public boolean onTouch(View v, MotionEvent event) { int id = v.getId(); int drag_left = ResourceUtil.getId(v.getContext(), "drag_left"); int drag_right = ResourceUtil.getId(v.getContext(), "drag_right"); int drag_bottom_left = ResourceUtil.getId(v.getContext(), "drag_bottom_left"); int drag_bottom_right = ResourceUtil.getId(v.getContext(), "drag_bottom_right"); if (id == drag_left || id == drag_right || id == drag_bottom_left || id == drag_bottom_right) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mInitialWidth = getViewWidth(); mInitialHeight = getViewHeight(); mInitialX = getViewOnScreenX(); mInitialY = getViewOnScreenY(); isResizing = false; // 确定操作角落类型并设置固定点 if (id == drag_left || id == drag_bottom_left) { mCornerType = CORNER_BOTTOM_LEFT; mFixedCornerX = mInitialX + mInitialWidth; // 固定右上角X mFixedCornerY = mInitialY; // 固定右上角Y } else if (id == drag_right || id == drag_bottom_right) { mCornerType = CORNER_BOTTOM_RIGHT; mFixedCornerX = mInitialX; // 固定左上角X mFixedCornerY = mInitialY; // 固定左上角Y } break; case MotionEvent.ACTION_MOVE: float currentX = event.getRawX(); float currentY = event.getRawY(); int newWidth = mInitialWidth; int newHeight = mInitialHeight; int newX = mInitialX; int newY = mInitialY; // 根据角落类型计算新尺寸和位置 switch (mCornerType) { case CORNER_BOTTOM_LEFT: // 左下角 newWidth = (int) (mFixedCornerX - currentX); newHeight = (int) (currentY - mFixedCornerY); newX = (int) currentX; break; case CORNER_BOTTOM_RIGHT: // 右下角 newWidth = (int) (currentX - mFixedCornerX); newHeight = (int) (currentY - mFixedCornerY); break; } // 应用尺寸限制并保持最小尺寸 newWidth = Math.max(MIN_SIZE, Math.min(newWidth, MAX_SIZE)); newHeight = Math.max(MIN_SIZE, Math.min(newHeight, MAX_SIZE)); // 根据限制后的尺寸调整位置(保持固定点不变) switch (mCornerType) { case CORNER_TOP_LEFT: newX = mFixedCornerX - newWidth; newY = mFixedCornerY - newHeight; break; case CORNER_TOP_RIGHT: newY = mFixedCornerY - newHeight; break; case CORNER_BOTTOM_LEFT: newX = mFixedCornerX - newWidth; break; } // 边界保护:确保窗口不会超出屏幕 int screenWidth = DisplayUtil.getScreenWidth(v.getContext()); int screenHeight = DisplayUtil.getScreenHeight(v.getContext()); newX = Math.max(0, Math.min(newX, screenWidth - newWidth)); newY = Math.max(0, Math.min(newY, screenHeight - newHeight)); // 更新窗口尺寸和位置 getEasyWindow().setWidth(newWidth); getEasyWindow().setHeight(newHeight); updateLocation(newX, newY); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: // refreshLocationCoordinate(); break; } return true; } return false; } } <?xml version="1.0" encoding="utf-8"?><!-- 使用FrameLayout作为根容器便于拖拽区域定位 --> <!-- 内容区域 --> <LinearLayout android:id="@+id/content_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="4dp"> <RelativeLayout android:layout_width="match_parent" android:layout_height="40dp" android:paddingBottom="10dp"> <LinearLayout android:id="@+id/ll_draggable" android:layout_width="30dp" android:layout_height="30dp" android:layout_centerVertical="true" android:gravity="center"> <ImageView android:layout_width="20dp" android:layout_height="20dp" android:src="@mipmap/ml_chat_draggable" /> </LinearLayout> <TextView android:layout_width="match_parent" android:layout_height="3dp" android:layout_centerInParent="true" android:layout_marginHorizontal="100dp" android:background="@drawable/botton_yuan_ef_5" /> <LinearLayout android:id="@+id/ll_close" android:layout_width="30dp" android:layout_height="30dp" android:layout_alignParentEnd="true" android:layout_centerVertical="true" android:gravity="center"> <ImageView android:layout_width="20dp" android:layout_height="20dp" android:src="@mipmap/ml_bjlb_close" /> </LinearLayout> </RelativeLayout> <androidx.recyclerview.widget.RecyclerView android:id="@+id/rlv_messagr" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:scrollbars="none" /> <TextView android:layout_width="match_parent" android:layout_height="40dp" android:background="@drawable/bg_redius_transparent_75" android:gravity="center_vertical" android:paddingHorizontal="15dp" android:text="说点什么吧" android:textColorHint="@color/milu_color_99" /> </LinearLayout> <!-- 仅占位,形成框 --> <View android:id="@+id/drag_top" android:layout_width="match_parent" android:layout_height="4dp" android:layout_gravity="top" android:background="@color/milu_orange" android:visibility="gone" /> <!-- 拖拽区域 - 左边框 --> <View android:id="@+id/drag_left" android:layout_width="4dp" android:layout_height="wrap_content" android:layout_gravity="top|start" android:background="@color/milu_orange" android:visibility="gone" /> <!-- 拖拽区域 - 右边框 --> <View android:id="@+id/drag_right" android:layout_width="4dp" android:layout_height="wrap_content" android:layout_gravity="top|end" android:background="@color/milu_orange" android:visibility="gone" /> <!-- 拖拽区域 -下 --> <LinearLayout android:id="@+id/ll_bottom" android:layout_width="wrap_content" android:layout_height="4dp" android:visibility="gone" android:layout_gravity="bottom" android:orientation="horizontal"> <!-- 拖拽区域 - 下左边框 --> <View android:id="@+id/drag_bottom_left" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:background="@color/milu_orange" android:visibility="visible" /> <!-- 拖拽区域 - 下右边框 --> <View android:id="@+id/drag_bottom_right" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:background="@color/milu_orange" android:visibility="visible" /> </LinearLayout> </FrameLayout>
07-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值