在开发中会遇到一个比较变态但又合理的需求:
在LinearLayout里放入如下控件
<LinearLayout >
<TextView />
<ImageView />
</LinearLayout>
要求:
1. TextView的宽度足够短的情形,则ImageView紧随其后
2. TextView的宽度足够长的情形,ImageView居右显示,TextView省略
解决方案一:布局设置rtf,但必须在Android 4.2以上才有效,前提是不需要适配中东阿拉伯语的应用。
最近又发现了一种完美解决方案,如何完美解决呢:在系统的源码里发现一个继承与LinearLayout的布局EllipsizeLayout,直接上源码:
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
* Created by zhanghehe on 2018/9/15.
* desc:
*/
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.a.b.widgets.EllipsizeLayout
android:layout_width="@dimen/dp_120"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_10"
app:layout_constraintBottom_toBottomOf="@+id/aivGroupIcon"
app:layout_constraintStart_toEndOf="@+id/aivGroupIcon"
app:layout_constraintTop_toTopOf="@+id/aivGroupIcon">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/atvUnionGroupName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:singleLine="true"
android:text="左边占位"
android:textColor="@color/colorWhite"
android:textSize="@dimen/sp_13"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:fontFamily="@font/pingfang_medium"
android:singleLine="true"
android:text="占位"
android:textColor="@color/colorWhite"
android:textSize="@dimen/sp_13"
android:textStyle="bold" />
</com.a.b.widgets.EllipsizeLayout>