从需求出发
image.png- 显示用户名和用户 ID
- 整体宽度不能固定,要跟随内容变化
- 空间不够的话优先显示ID,截取用户名过长部分显示为“...”
抽象起来就是多个元素横向排列,在空间不足的小屏手机上,保证显示右边的元素,挤压左边的。
注:需求图和描述来自网友博文。
实现
实现方式一(很简单)
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_shop_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
style="@style/text_medium_color3_size12"
android:textColor="@color/black_33"
android:singleLine="true"
android:ellipsize="end"
android:textSize="16sp"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginStart="7dp"
android:gravity="center_vertical">
<ImageView
android:id="@+id/iv_shop_class"
android:layout_width="@dimen/store_grade_w"
android:layout_height="@dimen/store_grade_h"/>
<TextView
android:id="@+id/tv_shop_class"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4.5dp"
android:textSize="10sp"/>
</LinearLayout>
</LinearLayout>
很简单,给空间不足时需要挤压的TextView设置layout_width="wrap_content",layout_weight="1"即可。
实现方式二:EllipsizeLayout
源码:
public class EllipsizeLayout extends LinearLayout{
public EllipsizeLayout(Context context) {
this(context, null);
}
public EllipsizeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (getOrientation() == HORIZONTAL
&& (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY)) {
int totalLength = 0;
boolean outOfSpec = false;
TextView ellipView = null;
final int count = getChildCount();
for (int ii = 0; ii < count && !outOfSpec; ++ii) {
final View child = getChildAt(ii);
if (child != null && child.getVisibility() != GONE) {
if (child instanceof TextView) {
final TextView tv = (TextView) child;
if (tv.getEllipsize() != null) {
if (ellipView == null) {
ellipView = tv;
// clear maxWidth on mEllipView before measure
ellipView.setMaxWidth(Integer.MAX_VALUE);
} else {
// TODO: support multiple android:ellipsize
outOfSpec = true;
}
}
}
final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child
.getLayoutParams();
outOfSpec |= (lp.weight > 0f);
measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
totalLength += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
}
}
outOfSpec |= (ellipView == null) || (totalLength == 0);
final int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
if (!outOfSpec && totalLength > parentWidth) {
int maxWidth = ellipView.getMeasuredWidth() - (totalLength - parentWidth);
// TODO: Respect android:minWidth (easy with @TargetApi(16))
int minWidth = 0;
if (maxWidth < minWidth) {
maxWidth = minWidth;
}
ellipView.setMaxWidth(maxWidth);
}
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
使用方式:
<com.floruit.cxy.view.EllipsizeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_shop_name"
android:layout_width="0dp"
android:layout_weight="1"
android:singleLine="true"
android:ellipsize="end"
android:layout_height="wrap_content"
style="@style/text_medium_color3_size12"
android:textColor="@color/black_33"
android:textSize="16sp"
android:text="fkdjfklsdkdjflskdjfls"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginStart="7dp"
android:gravity="center_vertical">
<ImageView
android:id="@+id/iv_shop_class"
android:layout_width="@dimen/store_grade_w"
android:layout_height="@dimen/store_grade_h"/>
<TextView
android:id="@+id/tv_shop_class"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4.5dp"
android:text="aaaaaaaaa"
android:textSize="10sp"/>
</LinearLayout>
</com.floruit.cxy.view.EllipsizeLayout>
给空间不足时需要挤压的TextView设置layout_width="0dp",layout_weight="1"即可。
实现效果如图所示:
网友评论