当对话框的宽度包含ListView
时,我遇到了问题:对话框总是几乎填满了屏幕的宽度。以下是问题的一个示例:
我需要对话框宽度来匹配图标。我试过通过播放here和here所描述的对话框样式来解决这个问题,但无济于事。我认为这些线程在错误的轨道上(至少对于这个问题),因为(1)它们没有解决问题,(2)我可以通过简单地不使用{{1}来使对话框按照需要调整大小}。例如,如果我将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>
使用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
ImageView
内VerticalLayout
放置一些ScrollView
,以便在短期内解决这个问题。不幸的是,根据应用程序的内部状态,图标的排列和数量会有很大差异,因此这不是一种可持续的方法;从长远来看,我真的需要使用ListView
。有关如何解决此问题的任何想法?
答案 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>
所以,我的意见是你可以设置:
将width_value精确设为Dialog
,并将ListView
的宽度设为match_parent
或fill_parent
。
ListView
的宽度乘以Activity
宽度的x%。
在测试中添加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,不会使对话框变大。