web-dev-qa-db-ja.com

ellipsize = endにもかかわらず、長いテキストのTextviewがGridLayoutの他のビューを押し出します

私の問題は 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] |
+----------------------------------------+

私はもう試した:

  • TableLayouts、ただし一部のデバイスではスクロールが非常に遅くなるようです。
  • RelativeLayoutsですが、重複するビューがあったか、view1またはview2が完全に消えました。
  • GridLayoutsですが、TextViewは常に画面の幅全体を占めるまで拡大するため、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>
40
Stefan Frye

GridLayoutのTextViewが際限なく成長して他のビューを押し出すのを防ぐための潜在的な解決策を見つけたようです。これが以前に文書化されているかどうかは不明です。

楕円形にする必要がある場合、fill Layout_gravityを使用し、長いTextViewに任意のlayout_widthまたは幅を設定する必要があります。

Android:layout_gravity="fill"
Android:layout_width="1dp"

GridLayoutとAndroid.support.v7.widget.GridLayoutの両方で機能します

18
Yuntao

私は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>
8
invertigo

目的に合わせてカスタムレイアウトを作るべきだと思います。デフォルトのレイアウト/ビューのみを使用してこれを実行し、すべてのケースで機能させる方法がわかりません。

3
Leonidos

ウィジェットの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] |
+----------------------------------------+
3
dinesh sharma

私にとってうまくいったトリックは、maxWidthを使用して最初のビューの幅を制限することでした。あなたはJavaでそれをする必要があります、これが基本的なロジックです:

firstView.setMaxWidth(parentView.getWidth() - view2.getWidth() - view1.getWidth() - padding * 2);

きれいではありませんが、動作します。

3
Vlad Spreys

私はレイアウトに解決できる小さな問題があると思います。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>

お役に立てれば...

よろしく!

2
Martin Cazares

レイアウトの重みを使用してみてください

   <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%になるまでかかるため、レイアウトは画面に応じて調整され、重なりの問題もありません。 。

私があなたを正しく理解しているなら、これはあなたが望んでいた答えです。

それが役に立てば幸い!

0
Armaan Stranger

最初に、[ビュー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>
0
Jenus Dong

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>
0
thanhbinh84

グリッドレイアウトにも同じ問題がありました。私がやったことは、テキストビューの固定幅が与えられ、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" />
0
Ameen Maheen

右側のビューが意図的にテキストに押しやられる場合は、GridViewの代わりにListViewを使用することもできます。

リストアイテムレイアウトのベースをRelativeLayoutにして、次のようなルールを設定するだけです。

  1. 右側の2つのビューをalignParentRightに設定できます(Android:layout_alignParentLeft = "true"を使用)。ただし、最初のビューが2番目のビューの左側に留まるようにして、ビューが伸びるときに自分自身を左側に押します。

  2. 左側のTextViewを左側に揃えることができますが、最初のビューの左側に留まるようにして(Android:layout_toLeftOf = "@ + id/viewId"を使用)、ビューと重ならないようにします。

0
afollestad

ケース番号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で、私はこれについて多くのことを試みませんでした。私はそれが役に立てば幸いです(そして私にもっと暇があるなら、私は最初のものを達成しようとします!)。

0
JJ86

これを試して

<?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つのLinearLayoutsは次のようになります(それぞれ右と左に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>
0
ozbek

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);
    }
}

楽しんで。

0
BluEOS