私の問題は 1つのテキストを拡大して楕円にすることができるが、レイアウトの他の要素を乱さないレイアウトを取得する方法 ですが、提案されているようにTableLayoutsを使用できない理由を以下で読んでくださいそこ。
基本的に次のようなリストビュー行を作成しようとしています:
| TextView |表示1 |表示2 |
すべてのビューには、可変幅の要素が含まれています。 TextViewにはellipsize = "end"が設定されています。ビュー1はTextViewの左側に配置し、ビュー2は画面の右側に配置する必要があります。したがって、通常、ビュー1とビュー2の間に空白があります。TextViewのテキストが長くなると、TextViewが大きくなり、余白がなくなるまでビュー1を右に押します。次に、ellipsizeが起動し、TextViewでテキストを切り取り、最後に省略記号( "...")を追加します。
したがって、結果は次のようになります。
+----------------------------------------+
| short text [view1] [view2] |
+----------------------------------------+
| long text with ell ... [view1] [view2] |
+----------------------------------------+
私はもう試した:
これは私が試したGridLayoutです:
<GridLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content" >
<TextView
Android:layout_gravity="left|fill_horizontal"
Android:ellipsize="end"
Android:singleLine="true"
Android:text="Long text to demonstrate problem with TextView in GridLayout taking up too much space despite Ellipsis" />
<TextView
Android:layout_gravity="left"
Android:text="(view1)" />
<TextView
Android:layout_gravity="right"
Android:text="(view2)" />
</GridLayout>
ビュー1とビュー2は実際にはTextViewではありません。単純にするために例で使用しただけです。
TableLayoutsを使用せずにこれを達成する方法はありますか?
EDIT:リクエストに応じて、RelativeLayoutを使用してこれを解決する私の試みを次に示します。この場合、TextViewは画面の幅全体を占めるため、view1もview2も表示されません。
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content" >
<TextView
Android:id="@+id/rl0"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignParentLeft="true"
Android:ellipsize="end"
Android:singleLine="true"
Android:text="Long text to demonstrate problem with TextView in GridLayout taking up too much space despite Ellipsis" />
<TextView
Android:id="@+id/rl1"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_toRightOf="@id/rl0"
Android:layout_marginLeft="10dp"
Android:text="(view1)" />
<TextView
Android:id="@+id/rl2"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_toRightOf="@id/rl1"
Android:layout_alignParentRight="true"
Android:layout_marginLeft="10dp"
Android:text="(view2)" />
</RelativeLayout>
GridLayoutのTextViewが際限なく成長して他のビューを押し出すのを防ぐための潜在的な解決策を見つけたようです。これが以前に文書化されているかどうかは不明です。
楕円形にする必要がある場合、fill Layout_gravityを使用し、長いTextViewに任意のlayout_widthまたは幅を設定する必要があります。
Android:layout_gravity="fill"
Android:layout_width="1dp"
GridLayoutとAndroid.support.v7.widget.GridLayoutの両方で機能します
私はLinearLayoutsの大ファンなので、これらを使用した提案を次に示します。
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="horizontal" >
<LinearLayout
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:orientation="horizontal"
Android:layout_weight="1" >
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_weight="1"
Android:ellipsize="end"
Android:singleLine="true"
Android:text="Long text to demonstrate problem with TextView in GridLayout taking up too much space despite Ellipsis" />
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="(view1)" />
</LinearLayout>
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="right"
Android:text="(view2)" />
</LinearLayout>
目的に合わせてカスタムレイアウトを作るべきだと思います。デフォルトのレイアウト/ビューのみを使用してこれを実行し、すべてのケースで機能させる方法がわかりません。
ウィジェットのlayout_weightプロパティで遊ぶことをお勧めします
例:
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
tools:context=".MainActivity" >
<LinearLayout
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:orientation="horizontal"
Android:weightSum="10">
<LinearLayout
Android:id="@+id/ll_twoViewContainer"
Android:layout_weight="8"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:orientation="horizontal">
<TextView
Android:id="@+id/rl0"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignParentLeft="true"
Android:layout_weight="1"
Android:ellipsize="end"
Android:singleLine="true"
Android:text="Long text" />
<TextView
Android:id="@+id/rl1"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_marginLeft="10dp"
Android:layout_toRightOf="@id/rl0"
Android:layout_weight="1"
Android:minWidth="120dp"
Android:text="(view1)" />
</LinearLayout>
<TextView
Android:id="@+id/rl2"
Android:layout_weight="2"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_toRightOf="@id/rl1"
Android:layout_alignParentRight="true"
Android:layout_marginLeft="10dp"
Android:text="(view2)" />
</LinearLayout>
</LinearLayout>
最終的に、レイアウトは次のようになります。
+----------------------------------------+
| short text [view1] [view2] |
+----------------------------------------+
| long text with ell ... [view1] [view2] |
+----------------------------------------+
私にとってうまくいったトリックは、maxWidthを使用して最初のビューの幅を制限することでした。あなたはJavaでそれをする必要があります、これが基本的なロジックです:
firstView.setMaxWidth(parentView.getWidth() - view2.getWidth() - view1.getWidth() - padding * 2);
きれいではありませんが、動作します。
私はレイアウトに解決できる小さな問題があると思います。view3を右にアンカーし、そこから開始してビューに強制的に区切られた領域を持たせます(したがって楕円を適切に設定できます)。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content">
<TextView
Android:id="@+id/rl3"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignParentRight="true"
Android:text="(view2)" />
<TextView
Android:id="@+id/rl2"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_toLeftOf="@id/rl3"
Android:text="(view1)" />
<TextView
Android:id="@+id/rl1"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:ellipsize="end"
Android:singleLine="true"
Android:layout_alignParentLeft="true"
Android:layout_toLeftOf="@id/rl2"
Android:text="Long text to demonstrate problem with TextView in GridLayout taking up too much space despite Ellipsis" />
</RelativeLayout>
お役に立てれば...
よろしく!
レイアウトの重みを使用してみてください
<TableRow
Android:id="@+id/tableRow3"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_alignBottom="@+id/tableRow2"
Android:layout_alignParentBottom="true"
Android:gravity="center"
Android:weightSum="10"
Android:background="@Android:color/black" >
<TextView
Android:id="@+id/txtInningsTotal"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_weight="2"
Android:gravity="center"
Android:text="0"
Android:textColor="@Android:color/white" />
<TextView
Android:id="@+id/txtTeamOneTotal"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_weight="2.5"
Android:gravity="center"
Android:text="0"
Android:textColor="@Android:color/white" />
<View
Android:layout_width="0dp"
Android:layout_height="match_parent"
Android:layout_weight="0.2" />
<TextView
Android:id="@+id/txtTeamTwoTotal"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_weight="2.5"
Android:gravity="center"
Android:text="0"
Android:textColor="@Android:color/white" />
<View
Android:layout_width="0dp"
Android:layout_height="match_parent"
Android:layout_weight="0.2" />
<TextView
Android:id="@+id/txtGrandTotal"
Android:layout_width="0dp"
Android:layout_height="match_parent"
Android:layout_weight="3"
Android:gravity="center"
Android:text="0"
Android:textColor="@Android:color/white" />
</TableRow>
ここでは、レイアウトの重みの合計が10であるテーブル行を取り上げました。これは、親の幅が100%であることを意味します。すべての子ビューで、幅を0Dpに設定し、重みを1または2に設定しました。合計がその10%になるまでかかるため、レイアウトは画面に応じて調整され、重なりの問題もありません。 。
私があなたを正しく理解しているなら、これはあなたが望んでいた答えです。
それが役に立てば幸い!
最初に、[ビュー2]を親Rightにレイアウトする必要があります。
ここでも、最後の2つのレイアウトへの参照を参照します。
<Relativelayout Android:layout_width="match_parent"
Android:layout_height="wrap_content"
<TextView
Android:id="@+id/view2"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignParentRight="true"
/>
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_toLeft="@id/view2"
Android:gravity="left">
<TextView
Android:id="@+id/shortORlongtTextView"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_toRightOf="@id/view1"
Android:ellipsize="end"
Android:maxLines="1"
Android:textSize="18dp"/>
<TextView
Android:id="@+id/view1"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignParentRight="true"
/>
</RelativeLayout>
TableLayoutは予想される動作を提供します。質問の作成者が述べたようにパフォーマンスの問題を引き起こす可能性がありますが、シンプルなレイアウトでうまく機能します。行が繰り返し可能でスクロール可能な場合は、代わりにgridviewを使用することを検討してください
<TableLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:stretchColumns="1"
Android:shrinkColumns="0"
>
<TableRow>
<TextView/>
<View1/>
<View2/>
</TableRow>
</TableLayout>
グリッドレイアウトにも同じ問題がありました。私がやったことは、テキストビューの固定幅が与えられ、layout_columnWeight
各テキストビューのプロパティの問題が修正されました。
<TextView
Android:id="@+id/txtName"
style="@style/MyDetailTitle"
Android:layout_width="@dimen/detail_length"
Android:layout_height="wrap_content"
Android:text="@string/app_name"
app:layout_column="3"
app:layout_columnWeight="1"
app:layout_gravity="start"
app:layout_row="1" />
右側のビューが意図的にテキストに押しやられる場合は、GridViewの代わりにListViewを使用することもできます。
リストアイテムレイアウトのベースをRelativeLayoutにして、次のようなルールを設定するだけです。
右側の2つのビューをalignParentRightに設定できます(Android:layout_alignParentLeft = "true"を使用)。ただし、最初のビューが2番目のビューの左側に留まるようにして、ビューが伸びるときに自分自身を左側に押します。
左側のTextViewを左側に揃えることができますが、最初のビューの左側に留まるようにして(Android:layout_toLeftOf = "@ + id/viewId"を使用)、ビューと重ならないようにします。
ケース番号2(長いテキストのケース)の解決策が見つかりました。
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:weightSum="3" >
<TextView
Android:id="@+id/rl0"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_weight="3"
Android:ellipsize="end"
Android:singleLine="true"
Android:text="Long text to demonstrate problem with TextView in GridLayout taking up too much space despite Ellipsis" />
<TextView
Android:id="@+id/rl1"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_marginLeft="10dp"
Android:layout_weight="1"
Android:text="(view1)" />
<TextView
Android:id="@+id/rl2"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_marginLeft="10dp"
Android:layout_weight="1"
Android:text="(view2)" />
</LinearLayout>
本当の問題はケース1で、私はこれについて多くのことを試みませんでした。私はそれが役に立てば幸いです(そして私にもっと暇があるなら、私は最初のものを達成しようとします!)。
これを試して
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:baselineAligned="false"
Android:orientation="horizontal">
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_weight="1"
Android:gravity="center">
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:ellipsize="end"
Android:singleLine="true"
Android:text="Long text to demonstrate problem with TextView in GridLayout taking up too much space despite Ellipsis"/>
</LinearLayout>
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_weight="1"
Android:gravity="center">
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="left"
Android:text="(view1)"/>
</LinearLayout>
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_weight="1"
Android:gravity="center">
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="right"
Android:text="(view2)"/>
</LinearLayout>
</LinearLayout>
現在、すべてのビューが中央に配置されています。あなたは変えられる Android:gravity
プロパティを使用してニーズを満たします。たとえば、view1
右とview2
左の場合、最後の2つのLinearLayout
sは次のようになります(それぞれ右と左に5 dpのマージンがあります):
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_weight="1"
Android:gravity="center|right">
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="left"
Android:layout_marginRight="5dp"
Android:text="(view1)"/>
</LinearLayout>
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_weight="1"
Android:gravity="center|left">
<TextView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="right"
Android:layout_marginLeft="5dp"
Android:text="(view2)"/>
</LinearLayout>
GridLayoutは、他のAndroid:設計上の欠陥がある)のようなものです。
カスタムレイアウトが必要になります。次の例では、次のものをレイアウトできます。
[ label | short text | very long label | short text ]
[ long label | very very very | label | very long text ]
[ | long text | | ]
import Android.content.Context;
import Android.view.View;
import Android.view.ViewGroup;
import Java.util.ArrayList;
import Java.util.List;
public class TwoColumsGridLayout extends ViewGroup {
private final List<List<View>> rows;
private int rowCount = 0;
private int firstColumWidth;
private int secondColumWidth;
private int thirdColumWidth;
private int fourthColumnWidth;
private final List<Integer> rowHeights = new ArrayList<>();
private final List<List<Integer>> cellHeights = new ArrayList<>();
private final List<Integer> firstCellsWidths = new ArrayList<>(4);
private final List<Integer> thirdCellsWidths = new ArrayList<>(4);
public TwoColumsGridLayout(Context context, int rowCount) {
super(context);
rows = new ArrayList<>(rowCount);
}
public void add(Context ctx, TextView l1, View t1, TextView l2, View t2) {
final List<View> row = new ArrayList<>(4);
row.add(l1);
row.add(t1);
row.add(l2);
row.add(t2);
rows.add(row);
this.addView(l1);
this.addView(t1);
if (l2 != null)
this.addView(l2);
if (t2 != null)
this.addView(t2);
this.rowCount++;
}
public int getRowCount() {
return rowCount;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int curLeft = 0;
int curBottom;
int curRight;
int curTop = 0;
int i = 0;
for (List<View> row : rows) {
final int rowHeight = this.rowHeights.get(i);
final List<Integer> rowCellHeights = this.cellHeights.get(i);
final View v0 = row.get(0);
curLeft = 0;
curRight = curLeft + this.firstColumWidth;
if (v0 != null) {
curBottom = curTop + rowCellHeights.get(0);
// Right align
v0.layout(curLeft + this.firstColumWidth - this.firstCellsWidths.get(i), curTop + 7, curRight, curBottom + 7);
}
//
final View v1 = row.get(1);
curLeft += this.firstColumWidth;
curRight = curLeft + this.secondColumWidth;
if (v1 != null) {
curBottom = curTop + rowCellHeights.get(1);
v1.layout(curLeft, curTop, curRight, curBottom);
}
//
final View v2 = row.get(2);
curLeft += this.secondColumWidth;
curRight = curLeft + this.thirdColumWidth;
if (v2 != null) {
curBottom = curTop + rowCellHeights.get(2);
// Right align
v2.layout(curLeft + this.thirdColumWidth - this.thirdCellsWidths.get(i), curTop + 7, curRight, curBottom + 7);
}
//
final View v3 = row.get(3);
curLeft += this.thirdColumWidth;
curRight = curLeft + this.fourthColumnWidth;
if (v3 != null) {
curBottom = curTop + rowCellHeights.get(3);
v3.layout(curLeft, curTop, curRight, curBottom);
}
curTop += rowHeight;
i++;
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
// Compute first column width
firstColumWidth = 0;
for (List<View> row : rows) {
final View v = row.get(0);
if (v != null) {
v.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
measureChild(v, widthMeasureSpec, heightMeasureSpec);
final int w = v.getMeasuredWidth();
if (firstColumWidth < w) {
firstColumWidth = w;
}
}
}
// Compute third column width
thirdColumWidth = 0;
for (List<View> row : rows) {
final View v = row.get(2);
if (v != null) {
v.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
measureChild(v, widthMeasureSpec, heightMeasureSpec);
final int w = v.getMeasuredWidth();
if (thirdColumWidth < w) {
thirdColumWidth = w;
}
}
}
secondColumWidth = (parentWidth - firstColumWidth - thirdColumWidth) / 2;
fourthColumnWidth = parentWidth - firstColumWidth - secondColumWidth - thirdColumWidth;
// Clear
this.rowHeights.clear();
this.cellHeights.clear();
this.firstCellsWidths.clear();
this.thirdCellsWidths.clear();
// Compute heights
int height = 0;
for (List<View> row : rows) {
final ArrayList<Integer> rowCellHeights = new ArrayList<>(4);
cellHeights.add(rowCellHeights);
int rowHeight = 0;
// First column
final View v0 = row.get(0);
if (v0 != null) {
int h = v0.getMeasuredHeight();
this.firstCellsWidths.add(v0.getMeasuredWidth());
rowCellHeights.add(h);
if (rowHeight < h) {
rowHeight = h;
}
} else {
this.firstCellsWidths.add(0);
}
// Second column
final View v1 = row.get(1);
if (v1 != null) {
v1.setLayoutParams(new ViewGroup.LayoutParams(secondColumWidth, LayoutParams.WRAP_CONTENT));
measureChild(v1, widthMeasureSpec, heightMeasureSpec);
int h = v1.getMeasuredHeight();
rowCellHeights.add(h);
if (rowHeight < h) {
rowHeight = h;
}
}
// Third column
final View v2 = row.get(2);
if (v2 != null) {
int h = v2.getMeasuredHeight();
this.thirdCellsWidths.add(v2.getMeasuredWidth());
rowCellHeights.add(h);
if (rowHeight < h) {
rowHeight = h;
}
} else {
this.thirdCellsWidths.add(0);
}
// Fourth column
final View v3 = row.get(3);
if (v3 != null) {
v3.setLayoutParams(new ViewGroup.LayoutParams(fourthColumnWidth, LayoutParams.WRAP_CONTENT));
measureChild(v3, widthMeasureSpec, heightMeasureSpec);
int h = v3.getMeasuredHeight();
rowCellHeights.add(h);
if (rowHeight < h) {
rowHeight = h;
}
}
height += rowHeight;
this.rowHeights.add(rowHeight);
}
setMeasuredDimension(parentWidth, height);
}
}
楽しんで。