5

ダイアログに が含まれている場合、ダイアログの幅に問題がListViewあります。ダイアログは常に画面の幅をほぼ埋め尽くします。問題の例を次に示します。

広すぎるダイアログ

アイコンに合わせてダイアログの幅が必要です。hereおよびhereで説明されているように、ダイアログスタイルをいじってこれを修正しようとしましたが、役に立ちませんでした。これらのスレッドは (少なくともこの問題では) 間違った方向に進んでいると思います。なぜなら、(1) 問題を解決できず、(2) ListView. たとえば、ListViewを単純なTextViewもの (詳細は以下) に置き換えると、すべてのサイズが希望どおりになります。

コンパクトダイアログ

ダイアログを表示するために使用しているコードは次のとおりです。

private void showDisplayStyleDialog(int id, int choices, int values) {
    final Dialog dlg = new Dialog(this);
    dlg.requestWindowFeature(Window.FEATURE_NO_TITLE);
    dlg.setContentView(R.layout.display_style_dialog);
    final ListView lv = (ListView) dlg.findViewById(android.R.id.list);
    if (lv != null) {
        displayStyleAdapter.setChoices(choices, values);
        lv.setAdapter(displayStyleAdapter);
        lv.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long itemId) {
                dlg.dismiss();
                setDisplayStyle(DisplayStyle
                        .valueOf(displayStyleAdapter.mValues[position]));
            }

        });
    }
    dlg.setCanceledOnTouchOutside(true);
    dlg.show();
}

を使用してダイアログを作成しようとしましたがAlertDialog.Builder、改善はありませんでした。ダイアログのレイアウト ( display_style_dialog.xml) は次のとおりです。

<?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" >

    <ListView
        android:id="@android:id/list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@android:color/white" >
    </ListView>

</LinearLayout>

アダプターは、このレイアウトからすべての行をロードします。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/holder"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="5dp" >

    <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/display_style_image_bg"
        android:contentDescription="@string/cd_display_style" />

</LinearLayout>

Android Debug Monitor でビュー階層を調べると、ListViewそれ自体だけがダイアログの全幅であることがわかります。各行は(必要に応じて)アイコンの幅に合わせてサイズ調整されます。ListView幅広い対話を強制しているのはそれ自体です。私が変更display_style_dialog.xmlした場合:

<?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" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/test_string"
        android:textColor="@android:color/black"
        android:background="@android:color/white" >
    </TextView>
</LinearLayout>

コードやリソースに他の変更を加えない場合、結果は上記のコンパクトなダイアログになります。私が知る限り、問題は厳密にListViewはダイアログ内の の存在によるものです。

ImageViewa の中に a のVerticalLayout中に多数の を配置することで、短期的にはこれを回避できると思いますScrollView。残念ながら、アイコンの配置と数はアプリの内部状態によってかなり異なるため、これは持続可能なアプローチではありません。長期的には、本当にListView. この問題を解決する方法についてのアイデアはありますか?

4

4 に答える 4

6

まず、英語が下手で申し訳ありませんが、私の意見について説明できるように最善を尽くします。

ListView短いまたは長い任意のデータ (文字列など) を含めることができます。したがって、LayoutParamsとして設定するとwrap_content、それがどのくらいの長さかを知る方法はありません。データによっては、実際のデータの幅が画面の幅より長くなる場合があります。

したがって、 を設定wrap_contentすると、自動的にmatch_parent/に変更されますfill_parent(正確にはわかりませんが、そのうちの 1 つです)。

それは高さでもわかります。 ListView行をいくつ描画する必要があるかわかりません。したがって、あなたの場合、ListViewの高さは の高さまで引き伸ばされActivityます。

Google I/O 2010から、wrap_content を使用すべきではない理由を説明しましたListView

私が知っているように、あなたの場合 (ListViewの高さはwrap_content) は、が初期化getView()されるときに、多くの行が存在するときに呼び出されListViewます。

したがって、私の意見では、次のように設定できます。

  1. width_value を に正確に指定し、の幅をまたはDialogに設定します。ListViewmatch_parentfill_parent

  2. ListViewの幅 x%Activityの幅。


TextViewテストで、 inDialogを追加します。

テキストを測定することで、正確な幅の値を知ることができます。ですので、ご利用は可能wrap_contentです。

于 2013-08-14T07:50:45.187 に答える
0

私はついにこれを機能させることができました..私はListviewをサブクラス化し、測定方法を変更しました。リストビューは最初の子だけをネイティブに測定するようです。したがって、最初の子の幅を使用します。リストビューの子で最も広い行を検索するように変更しました。

したがって、ダイアログ コンテンツの xml は次のようになります。

<?xml version="1.0" encoding="UTF-8"?>

<com.mypackage.myListView
    android:id="@+id/lv"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
 />

myListView は次のようになります。

public class MyListView extends ListView{

public MyListView(Context context, AttributeSet attrs) {
    super(context, attrs);
    // TODO Auto-generated constructor stub
}


@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    // TODO Auto-generated method stub
    int maxWidth = meathureWidthByChilds() + getPaddingLeft() + getPaddingRight();
    super.onMeasure(MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.EXACTLY), heightMeasureSpec);     
}


 public int meathureWidthByChilds() {
    int maxWidth = 0;
    View view = null;
    for (int i = 0; i < getAdapter().getCount(); i++) {
        view = getAdapter().getView(i, view, this);
        //this measures the view before its rendered with no constraints from parent
        view.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
        if (view.getMeasuredWidth() > maxWidth){
            maxWidth = view.getMeasuredWidth();
        }
    }
    return maxWidth;
 }
}
于 2014-06-21T01:46:13.257 に答える