【发布时间】:2011-02-07 22:50:24
【问题描述】:
如何在 ListView 中隐藏项目或至少将其高度设置为零?
我尝试将 View 的可见性设置为 GONE,但它仍然保持项目的空间(高度)。
【问题讨论】:
-
你确定你对 View.GONE 的评论吗?
标签: android listview visibility listviewitem
如何在 ListView 中隐藏项目或至少将其高度设置为零?
我尝试将 View 的可见性设置为 GONE,但它仍然保持项目的空间(高度)。
【问题讨论】:
标签: android listview visibility listviewitem
我对@987654321@ 的拖放列表做了一些修改。当一个项目从列表中弹出以围绕它占用的单元格空间移动时,它的高度设置为 1px(参见第 238 行),因此它看起来“消失”。我找不到更好的方法来处理这个问题,因为将高度设置为 0 失败,可见性消失了。
也就是说,如果您真的想暂时少删除一行,最好更改Adapter 的支持并在其上调用notifyDataSetChanged()。
【讨论】:
添加到您的 ListView 对象: 安卓:dividerHeight="0px" android:divider="#FFFFFF"
分隔线颜色无关紧要 只设置dividerHeight 不起作用
这确实删除了分隔线...
【讨论】:
我看过源代码。并且只有一种方法可以在没有notifyDataSetChanged() 的情况下隐藏项目。您必须为所有内部视图设置可见性GONE,并删除项目视图的背景图像和填充。
注意:具有这种不可见元素的行将是可选的。
P.S:如果你想自己隐藏组视图,这对ExpandableListView 非常有用。
【讨论】:
解决一个老问题,但我刚刚遇到了这个问题,我想根据列表数据之外的标准临时隐藏列表项。我最终做的是在 xml 中创建一个“空项目”布局,并根据我的标准而不是 getView() 中的转换视图返回它...
我没有返回 convertView,而是返回了我的 null_item...
return inflater.inflate(R.layout.null_item, null);
null_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<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="wrap_content" >
</LinearLayout>
【讨论】:
return new View(context);
convertView 的View 类型,如果您正在回收它们。如果项目可以从隐藏状态来回更改,则当项目再次可见时,您必须为项目创建新布局。否则,您最终可能会尝试使用空的 View 对象作为标准项目布局,这可能会导致崩溃。
对于 ListView,为了提高效率,我们使用 ViewHolder 模式。以下xml的ViewHolder Pattern和R.layout.row_null的使用方式
<?xml version="1.0" encoding="utf-8"?>
<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="wrap_content" >
</LinearLayout>
与getViewTypeCount() 和getItemViewType(int position) 一起使用,如下所示。
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public int getItemViewType(int position) {
return (hideStatusCheck(position)) ? 1 : 0;
}
@Override
public View getView(int pos, View convertView, ViewGroup parent) {
View rowView = convertView;
if (hideStatusCheck(pos)) {
if (rowView == null || rowView.getTag() != null) {
LayoutInflater inflater = mActivity.getLayoutInflater();
rowView = inflater.inflate(R.layout.row_null, parent, false);
}
} else {
if (rowView == null) {
rowView = inflateNormalView(parent);
} else if (rowView.getTag() == null) {
rowView = inflateNormalView(parent);
} else {
ViewHolder holderToCheck = (ViewHolder) rowView.getTag();
Integer storedPos = (Integer) holderToCheck.getTag(POSITION);
if (storedPos == null || storedPos != pos)
rowView = inflateNormalView(parent);
}
ViewHolder holder = (ViewHolder) rowView.getTag();
holder.setTag(POSITION,pos);
/*
Populate data
*/
return rowView;
}
private View inflateNormalView(ViewGroup parent) {
View rowView;
LayoutInflater inflater = mActivity.getLayoutInflater();
rowView = inflater.inflate(R.layout.normal_item, parent, false);
ViewHolder viewHolder = new ViewHolder();
assert rowView != null;
/* Initiate normal findViewById thing*/
rowView.setTag(viewHolder);
return rowView;
}
我们检查item的View类型,如果满足隐藏检查则返回1,否则返回0。ListView从getViewTypeCount中知道有2种View。现在,getView 将根据 hideStatusCheck 返回适当的视图。为了制作一个健壮的 ListView,我们想使用 ViewHolder 模式。隐藏时我们不需要使用 ViewHolder。我们只是膨胀 R.layout.row_null 并返回它。我们将为 R.layout.normal_item 使用 ViewHolder。假设隐藏检查不是静态的,这是棘手的部分。 rowView==null 的第一次检查是标准的。 rowView.getTag()==null的第二次检查是看View是否恢复正常
从隐藏。最后else子句中的第三个检查是检查标签中保留的ViewHolder是否是正确的ViewHolder。如果满足这些条件,我们总是会再次膨胀视图。是的,确实,ViewHolder 模式并未自始至终使用,但它用于某些扩展。有总比没有好。
【讨论】:
我认为我有一个更简单/更安全的解决方案:您只需将您的项目“嵌入”到布局中,并更改此父布局的可见性。
<?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:orientation="horizontal" >
<!-- Embed ListView Item into a "parent" Layout -->
<LinearLayout
android:id="@+id/parentLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<!-- This is the normal content of your ListView Item -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="World" />
</LinearLayout>
</LinearLayout>
然后在你的代码中做:
public View getView(int position, View view, ViewGroup parent) {
if (view == null) {
LayoutInflater li = mActivity.getLayoutInflater();
view = li.inflate(R.layout.my_listview_item, null);
}
LinearLayout parentLayout = (LinearLayout) view.findViewById(R.id.parentLayout);
if (shouldDisplayItem(position)) {
parentLayout.setVisibility(View.VISIBLE);
} else {
parentLayout.setVisibility(View.GONE);
}
return view;
}
这样你总是使用/重复使用同一个项目,然后隐藏/显示它。
【讨论】:
如果你想像这样隐藏项目:
convertView.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,1));
convertView.setVisibility(View.GONE);
不能是 AbsListView.LayoutParams(-1,0);
如果转换视图被重用,你应该在下面添加它来设置它的高度:
if(convertView.getVisibility() == View.GONE) {
convertView.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT));
convertView.setVisibility(View.VISIBLE);
}
【讨论】:
在 android 的 listview 中隐藏整个原始数据:-
RelativeLayout parentLayout = (RelativeLayout) view.findViewById(R.id.relative);
if (productPojoList.get(position).getSERSERVICETYPE().toString().equals("Group|Promotional")){
view.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,1));
view.setVisibility(View.GONE);
} else {
if(view.getVisibility() == View.GONE) {
view.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT));
view.setVisibility(View.VISIBLE);
}
}
【讨论】: