对话框包含ListView时太宽

时间:2013-08-14 03:49:23

标签: android layout dialog

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

overly wide dialog

我需要对话框宽度来匹配图标。我试过通过播放herehere所描述的对话框样式来解决这个问题,但无济于事。我认为这些线程在错误的轨道上(至少对于这个问题),因为(1)它们没有解决问题,(2)我可以通过简单地不使用{{1}来使对话框按照需要调整大小}。例如,如果我将ListView替换为简单的ListView(详情如下),则所有内容都会根据需要进行调整:

compact dialog

这是我用来显示对话框的代码:

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>

使用Android Debug Monitor检查视图层次结构显示只有<?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> 本身是对话框的整个宽度;每行(根据需要)的大小与图标宽度相匹配。它是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 ImageViewVerticalLayout放置一些ScrollView,以便在短期内解决这个问题。不幸的是,根据应用程序的内部状态,图标的排列和数量会有很大差异,因此这不是一种可持续的方法;从长远来看,我真的需要使用ListView。有关如何解决此问题的任何想法?

4 个答案:

答案 0 :(得分:5)

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

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

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

你也可以看到身高。 ListView不知道应该如何绘制行。 因此,在您的情况下,ListView的高度将延伸至Activity的高度。

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

据我所知,在您的情况下(ListView的高度为wrap_content),getView()将在ListView初始化时存在多行。 / p>

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

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

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


  3. 在测试中添加TextView中的Dialog

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

答案 1 :(得分:1)

我认为你可以通过制作Listview layout_width = 50sp来解决这个问题。我的意思是修改数字而不是wrap_content。

答案 2 :(得分:0)

我终于能够让这个工作..i子类化Listview并改变它的测量方式。看来listview本身只会衡量第一个孩子。所以它使用第一个孩子的宽度。我将其更改为在listviews中搜索最宽行。

所以对话框内容的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;
 }
}

答案 3 :(得分:0)

使用RecyclerView代替ListView,不会使对话框变大。