次のレイアウトを実現する必要があります。
相対レイアウトに2つのTextViewがあります。緑のTextViewはwrap_content
の固定テキストで、黒のTextViewは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>
しかし、黒いテキストがどんどん大きくなると、緑のテキストがビューから押し出されます
このレイアウトは、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>
ここ 同じ質問です;)
これがあなたが望むことをするレイアウトです:
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:gravity="left">
<TextView
Android:id="@+id/leftTextView"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_toLefOf="@+id/rightTextView"
Android:maxLines="1"
Android:textSize="18sp" />
<TextView
Android:id="@+id/rightTextView"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignParentRight="true"
Android:textSize="18sp" />
</RelativeLayout>
ここで重要なのは、相対レイアウトの重要性と、右側のテキストビューをalignParentRightとして、左側のテキストビューにアタッチされた左側のテキストビューに揃えることです。
2つのTextView
をLinearLayout
にラップすることをお勧めします。次に、このLinearLayout
にAndroid:weightSum="1"
を適用し、拡張する必要のある子TextView
にAndroid:layout_weight="1"
を適用します。
<?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>
完全に機能するように、2つの属性を設定することを忘れないでください。
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>
期待されるレイアウトは、LinearLayout
に付属するlayout_weight
attirbuteを使用して作成できます。したがって、LinearLayout
とweightSum
およびlayout_weight
(そのchildview
に渡す)属性を使用する必要がある場合があります。
これは、レイアウトの幅を4つの部分に分割し、両方のTextview
の間で: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>
私は私たちのアプリでこの種のユースケースに直面しました。私たちのアプリでは、3つのビューがあります。 ImageView | TextView | ImageView
。 2つの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>
このレイアウトを使用すると、レイアウトに明確に表示されるはずのビューに高い優先度を与えることができます。残りの1つの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>
ここでは、ビュー「1」の優先順位について説明しました。これは、レイアウトの2番目のTextViewです。したがって、2番目のTextViewは常に表示され、最初のTextViewは省略されます。
追伸:これは一般的な解決策です。つまり、これは異なるビュー、および1行に2つ以上のビューで使用できます。このレイアウトを使用することも、ユースケースに固有のカスタムViewGroupを作成することもできます。
左のテキストビューの最大幅を右のテキストビューの幅のベースに設定し、コードを見てみましょう。これがお役に立てば幸いです。
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>
これは実行後のスクリーンショットです: