5

当对话框包含 a 时,我遇到了对话框宽度的问题ListView:对话框总是几乎填满屏幕的宽度。这是问题的一个例子:

过宽的对话框

我需要对话框宽度来匹配图标。我尝试通过使用此处此处描述的对话框样式来解决此问题,但无济于事。我认为这些线程在错误的轨道上(至少对于这个问题),因为(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对话框中存在的。

ImageView我想我可以通过在 a 中放置一些s 在短期内解决这个VerticalLayout问题ScrollView。不幸的是,图标的排列和数量会根据应用程序的内部状态而有很大差异,因此这不是一种可持续的方法;从长远来看,我真的需要使用ListView. 关于如何解决这个问题的任何想法?

4

4 回答 4

6

首先,对不起我的英语不好,但我会尽力解释我的意见。

ListView可以包含任何短或长的数据(例如,字符串)。因此,如果您设置LayoutParamswrap_content,则无法知道它有多长。取决于数据,实际数据的宽度可能比屏幕的宽度长。

因此,如果您设置wrap_content,它将自动更改为match_parent/ fill_parent(我不确切知道,但其中之一)

您也可以在高度上看到这一点。 ListView不知道应该如何绘制行。因此,在您的情况下,ListView' 的高度将被拉伸到Activity' 的高度。

Google I/O 2010上,他们解释了为什么我们不应该在ListView.

据我所知,在您的情况下(ListView的高度是wrap_content),getView()将在ListView初始化时调用存在的行数。

所以,我的意见是你可以设置:

  1. 将 width_value 准确设置为Dialog,并将ListView的宽度设置为match_parentfill_parent

  2. ListView' 的宽度乘以 ' 的宽度的 x% Activity


在您的测试TextView中添加Dialog

我们可以通过测量文本来知道确切的宽度值。因此,可以使用wrap_content.

于 2013-08-14T07:50:45.187 回答
1

我认为您可以通过使 Listview layout_width = 50sp 来解决此问题。我的意思是固定数字而不是 wrap_content。

于 2013-08-14T05:05:30.233 回答
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 回答
0

使用 RecyclerView 而不是 ListView 它不会使对话框变大。

于 2018-08-17T08:22:13.093 回答