2010-04-14 93 views
20

如何隐藏ListView中的项目或至少将其高度设置为零?Android:如何隐藏ListView项目

我已经尝试设置视图的可见性,但它仍然保持项目的空间(高度)。

+1

你肯定在View.GONE有何评论? – Samuh 2010-04-14 14:33:51

+0

查看http://stackoverflow.com/questions/5041499/how-to-hide-an-item-in-a-listview-in-android – mattlary 2012-02-03 05:28:00

回答

2

我做了一些修改,从here拖放列表。当一个项目从列表中移出时,它将被占据的单元格空间移动,它的高度设置为1px(请参见第238行),以便它看起来“消失”了。我无法找到一种方法来更好地处理这个问题,因为将高度设置为0会失败,因为能见度已经降低。

这就是说,如果你真的想暂时摆脱一排,最好改变Adapter的支持,并且打电话notifyDataSetChanged()就可以了。

0

添加到您的ListView对象: 机器人:dividerHeight = “0像素” 机器人:分隔= “#FFFFFF”

分频器肤色并不重要 设置只dividerHeight不起作用

这虽然删除分隔线...

2

我看看源代码。没有notifyDataSetChanged(),只有一种方法可以隐藏物品。您必须为所有内部视图设置可见性GONE,并删除项目视图的背景图像和填充。

注意:具有这种不可见元素的行将是可选的。

P.S:这对ExpandableListView非常有用,如果你想隐藏自己的组视图。

24

重新审视一个老问题,但我刚刚遇到了这个问题,我想根据列表数据之外的标准临时隐藏列表项。我最终做的是在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> 
+7

为什么不只是返回一个新的视图对象?这样你就不会增加膨胀视图的开销。 – mdelolmo 2014-10-01 14:59:17

+0

@tawani没有提出这个解决方案吗?请将此标记为答案。 – Sufian 2014-10-02 08:06:40

+4

@ mdelolmo的方法有效。我只是测试它,它为您节省了额外的XML文件和通货膨胀的需要。你甚至不需要设置布局参数,只需'返回新的视图(上下文);' – 2014-10-31 20:35:06

7

当涉及到的ListView,使之高效,我们使用ViewHolder模式。该方法使用下面的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> 

getViewTypeCount()getItemViewType(int position)如下使用的ViewHolder模式和R.layout.row_null。

@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; 
    } 

我们做项目的查看类型的检查,如果它符合隐藏检查,它将返回1,否则为0 ListView控件知道会有2种类型查看从getViewTypeCount的。现在,getView将根据hideStatusCheck返回适当的视图。为了建立一个健壮的ListView,我们想要使用ViewHolder模式。隐藏时,我们不需要使用ViewHolder。我们只需膨胀R.layout.row_null并将其返回。我们将使用ViewHolder作为R.layout.normal_item。假设隐藏检查不是静态的,这是棘手的部分。 rowView==null的第一个检查是标准的。rowView.getTag()==null的第二项检查是查看视图是否会从隐藏回到正常 。最后一个else子句中的第三个检查是检查标记中保留的ViewHolder是否是正确的ViewHolder。如果这些条件得到满足,我们总是再次夸大观点。是的,的确,ViewHolder模式并没有在整个过程中使用,但它用于某些扩展。这总比没有好。

0

我觉得我有一个更简单/更安全的解决方案:您只需将项目“嵌入”到布局中,并更改此父布局的可见性。

<?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; 
} 

这样,你总是使用/重复使用相同的项目,只是隐藏/显示它。

+0

这是我准备写的正确答案:) – 2014-09-03 16:09:50

11

,如果你想隐藏像这样的项目:(-1,0)

convertView.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,1)); 
convertView.setVisibility(View.GONE); 

不能AbsListView.LayoutParams;

如果convertview被重用,你应该添加此下方设置它的高度回:

if(convertView.getVisibility() == View.GONE) { 
    convertView.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT)); 
    convertView.setVisibility(View.VISIBLE); 
}