我需要实现以下布局:
我在相对布局中有两个TextView:绿色的是带有wrap_content
的固定文本,黑色的带有wrap_content
的动态文本。黑色文本可以更改并变得非常长。我希望黑色TextView随文本一起展开,直到绿色视图到达父级的末尾。如果发生这种情况,黑色TextView应该停止扩展并椭圆化结束。
我怎样才能做到这一点?
我尝试了什么:
<RelativeLayout
android:id="@+id/parent"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/leftTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:layout_alignParentLeft="true"
android:textSize="18sp" />
<TextView
android:id="@+id/rightTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/leftTextView"
android:textSize="18sp" />
</RelativeLayout>
但是当黑色文字越来越大时,它会将绿色文本推出视图
答案 0 :(得分:20)
您可以按TableLayout
和shrinkColumns
属性归档此布局。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Row 1 -->
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:shrinkColumns="0">
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="4dp"
android:maxLines="1"
android:ellipsize="end"
android:text="abcdefghijklmnopqrstuvwxyz"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="4dp"
android:maxLines="1"
android:ellipsize="none"
android:text="rightText"/>
</TableRow>
</TableLayout>
<!-- Row 2 -->
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:shrinkColumns="0">
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="4dp"
android:maxLines="1"
android:ellipsize="end"
android:text="Longer Text view abcdefghijklmnopqrstuvwxyz"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="4dp"
android:maxLines="1"
android:ellipsize="none"
android:text="rightText"/>
</TableRow>
</TableLayout>
<!-- Row 3 -->
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:shrinkColumns="0">
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="4dp"
android:maxLines="1"
android:ellipsize="end"
android:text="Text view that is very logn and will not fit the parent width abcdefghijklmnopqrstuvwxyz"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="4dp"
android:maxLines="1"
android:ellipsize="none"
android:text="rightText"/>
</TableRow>
</TableLayout>
</LinearLayout>
Here是同一个问题;)
答案 1 :(得分:5)
这是ConstraintLayout解决方案。
魔术是Chains。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp">
<TextView
android:id="@+id/leftTv"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textColor="#333333"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/rightTv"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="wrap"
tools:text="Text view that is very long and will not fit the" />
<TextView
android:id="@+id/rightTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:textColor="#21b38a"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/leftTv"
app:layout_constraintTop_toTopOf="parent"
tools:text="Text View" />
</androidx.constraintlayout.widget.ConstraintLayout>
答案 2 :(得分:3)
这是一个可以完成您喜欢的布局:
ffmpeg -i input -filter_complex "subtitles=diagonal.srt:force_style='Angle=45'" output
这里的关键部分是相对布局的重力,并将右侧textview与alignParentRight对齐,左侧是左侧的textview。
答案 3 :(得分:2)
我建议将两个TextView
包装成LinearLayout
。然后将android:weightSum="1"
应用于此LinearLayout
并将android:layout_weight="1"
应用于必须延长的子TextView
。
<?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:orientation="horizontal"
android:weightSum="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:padding="8dp"
android:text="blabla bla bla bla bla bla bla bla bla bla bla bla bla "/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:text="static text"/>
</LinearLayout>
请记住设置两个属性使其完美地运作:
android:ellipsize="end"
android:maxLines="1"
且LinearLayout
必须有android:layout_width="wrap_content"
如果您希望此ViewGroup
占用整个空间,请使用其他ViewGroup
包裹它:
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="match_parent">
<!--The previous view group-->
</RelativeLayout>
答案 4 :(得分:1)
可以使用layout_weight
附带的LinearLayout
attirbute帮助创建您期望的布局。因此,您可能需要将LinearLayout
与weightSum
和layout_weight
(传递给childview
)属性一起使用。
这是一个布局,它将您的布局宽度分为四个部分,分成两个Textview
之间的 3:1 。完成正确TextView
使左TextView
显示尽可能多的文字,而不会扰乱右TextView
。
请随意根据您的需要尝试使用变体weightSum
和layout_weight
组合。
布局:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="4" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:singleLine="true"
android:text="StackOverflow StackOverflow StackOverflow "
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_weight="3"
android:maxLines="1"
android:text="TextView"
android:textColor="@android:color/white" />
</LinearLayout>
答案 5 :(得分:0)
我设置了右侧textview宽度的左侧textview基数的最大宽度,看看我的代码。希望这会有所帮助。
TextView leftText ;
TextView rightText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
leftText = (TextView) findViewById(R.id.leftTextView);
rightText = (TextView) findViewById(R.id.rightTextView);
measureView(leftText);
measureView(rightText);
leftText.setMaxWidth(getWidth() - rightText.getMeasuredWidth());
}
private void measureView(View view) {
ViewGroup.LayoutParams params = view.getLayoutParams();
int childWidth = ViewGroup.getChildMeasureSpec(0, view.getPaddingLeft() + view.getPaddingRight(), params.width);
int childHeight = ViewGroup.getChildMeasureSpec(0, view.getPaddingBottom() + view.getPaddingTop(), params.height);
view.measure(childWidth, childHeight);
}
private int getWidth() {
WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
return display.getWidth();
}
,xml是:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/leftTextView"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:singleLine="true"
android:text="abadabadabadabadabadabadabadabadabadabaasdfasdfasdfadabadabadabadabadabadabadabadabadabadabaasdfasdfasdfadabadabadabadabadabadabadabadabadabadabaasdfasdfasdfad"/>
<TextView
android:id="@+id/rightTextView"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:textColor="#adc391"
android:singleLine="true"
android:text="adsfasd"/>
</LinearLayout>
这是运行后的屏幕截图:
答案 6 :(得分:0)
我在我们的应用程序中遇到过这种用例。在我们的应用程序中,有3个视图。 ImageView | TextView | ImageView
。两个ImageView必须在布局中可见。最后应将TextView椭圆化。我想出了一个自定义ViewGroup
。
public class PriorityLayoutHorizontal extends ViewGroup
{
private ArrayList<Integer> mPriorityHighChildren;
public PriorityLayoutHorizontal(Context context)
{
this(context, null);
}
public PriorityLayoutHorizontal(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
}
public PriorityLayoutHorizontal(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
TypedArray typedArray = null;
try
{
typedArray = context.obtainStyledAttributes(attrs, R.styleable.PriorityLayoutHorizontal, defStyleAttr, 0);
final int id = typedArray.getResourceId(R.styleable.PriorityLayoutHorizontal_priorityHigh, -1);
if(id != -1)
{
final int[] highPriorityChildren = getResources().getIntArray(id);
setPriorityHigh(highPriorityChildren);
}
}
finally
{
if(typedArray != null)
{
typedArray.recycle();
}
}
}
public void setPriorityHigh(int... priorityHigh)
{
Integer[] priorityHighInteger = new Integer[priorityHigh.length];
int i = 0;
for(int value : priorityHigh)
{
priorityHighInteger[i++] = Integer.valueOf(value);
}
mPriorityHighChildren = new ArrayList<Integer>(Arrays.asList(priorityHighInteger));
}
int mMaxHeight = 0;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthUsed = 0;
int heightUsed = 0;
final int childCount = getChildCount();
for(int childPosition : mPriorityHighChildren)
{
final View childView = getChildAt(childPosition);
if(childView.getVisibility() != View.GONE)
{
measureChildWithMargins(childView, widthMeasureSpec, widthUsed, heightMeasureSpec, heightUsed);
widthUsed += getMeasuredWidthWithMargins(childView);
heightUsed = Math.max(getMeasuredHeightWithMargins(childView), heightUsed);
}
}
for(int childPosition = 0; childPosition < childCount; childPosition++)
{
if(! mPriorityHighChildren.contains(Integer.valueOf(childPosition)))
{
final View childView = getChildAt(childPosition);
if(childView.getVisibility() != View.GONE)
{
measureChildWithMargins(childView, widthMeasureSpec, widthUsed, heightMeasureSpec, heightUsed);
widthUsed += getMeasuredWidthWithMargins(childView);
heightUsed = Math.max(getMeasuredHeightWithMargins(childView), heightUsed);
}
}
}
mMaxHeight = heightUsed;
int heightSize = heightUsed + getPaddingTop() + getPaddingBottom();
setMeasuredDimension(widthSize, heightSize);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
final int paddingLeft = getPaddingLeft();
final int paddingTop = getPaddingTop();
int spaceUsed = paddingLeft;
for (int childPosition = 0; childPosition < getChildCount(); childPosition++)
{
final View childView = getChildAt(childPosition);
if(childView.getVisibility() != View.GONE)
{
final int top = (mMaxHeight / 2) - (childView.getMeasuredHeight() / 2);
layoutView(childView, spaceUsed, paddingTop + top, childView.getMeasuredWidth(), childView.getMeasuredHeight());
spaceUsed += getWidthWithMargins(childView);
}
}
}
private int getWidthWithMargins(View child)
{
final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
return child.getWidth() + lp.leftMargin + lp.rightMargin;
}
private int getHeightWithMargins(View child)
{
final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
return child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
}
private int getMeasuredWidthWithMargins(View child)
{
final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
return child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
}
private int getMeasuredHeightWithMargins(View child)
{
final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
return child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
}
private void layoutView(View view, int left, int top, int width, int height)
{
MarginLayoutParams margins = (MarginLayoutParams) view.getLayoutParams();
final int leftWithMargins = left + margins.leftMargin;
final int topWithMargins = top + margins.topMargin;
view.layout(leftWithMargins, topWithMargins, leftWithMargins + width, topWithMargins + height);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs)
{
return new MarginLayoutParams(getContext(), attrs);
}
@Override
protected LayoutParams generateDefaultLayoutParams()
{
return new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
}
在values / attrs.xml
中声明自定义属性<declare-styleable name="PriorityLayoutHorizontal">
<attr name="priorityHigh" format="reference"/>
</declare-styleable>
使用此布局,您可以优先考虑应该在布局中可见的视图。将根据屏幕中的剩余宽度绘制剩余的一个TextView。
要使用此布局:
<com.example.component.PriorityLayoutHorizontal
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:priorityHigh="@array/priority_array"
>
<TextView
android:id="@+id/contact_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/your_drawable"
/>
</com.example.component.PriorityLayoutHorizontal>
在values / arrays.xml
中定义priority_array<integer-array name="priority_array">
<item>1</item>
</integer-array>
在这里,我们已经提到了View&#34; 1&#34;的优先级。这是布局中的第二个TextView。因此,第二个TextView将始终可见,并且第一个TextView将被椭圆化。
P.S:这是一个通用的解决方案。即,这可以与不同的视图一起使用,并且可以在一行中使用2个以上的视图。您可以使用此布局,也可以编写特定于您的用例的自定义ViewGroup。