Android:如何隐藏ListView项目

时间:2010-04-14 14:25:47

标签: android listview visibility listviewitem

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

我尝试将View的可见性设置为GONE,但它仍然保留了项目的空间(高度)。

8 个答案:

答案 0 :(得分:24)

重新确定一个旧问题,但我只是遇到了这个问题,我想根据列表数据之外的标准临时隐藏列表项。我最终做的是在xml中创建一个“null item”布局,并根据我的标准而不是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>

答案 1 :(得分:11)

如果你想隐藏这样的项目:

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

不能是AbsListView.LayoutParams(-1,0);

如果重新使用convertview,你应该在下面添加它以将其设置为高度:

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

答案 2 :(得分:8)

说到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;
    }

我们检查项目的View类型,如果它遇到隐藏检查,它将返回1,否则为0.LinViewView知道getViewTypeCount将有2种类型的View。现在,getView将返回approriate视图,具体取决于hideStatusCheck。为了制作健壮的ListView,我们想要使用ViewHolder模式。隐藏时我们不需要使用ViewHolder。我们只是给R.layout.row_null充气并返回它。我们将使用ViewHolder作为R.layout.normal_item。假设隐藏检查不是静态的,这是一个棘手的部分。 rowView==null的第一次检查是标准的。 rowView.getTag()==null的第二次检查是查看View是否恢复正常 从隐藏。最后一个else子句中的第三个检查是检查标记中保留的ViewHolder是否是正确的ViewHolder。如果满足这些条件,我们总是再次膨胀视图。是的,确实,ViewHolder模式并未在整个过程中使用,但它用于某些扩展。总比没有好。

答案 3 :(得分:2)

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

那就是说,如果你真的想暂时减去一行,那么改变Adapter的支持并在其上调用notifyDataSetChanged()可能是个好主意。

答案 4 :(得分:2)

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

注意:具有此类不可见元素的行将是可选择的。

P.S:如果您想隐藏群组视图,这对ExpandableListView非常有用。

答案 5 :(得分:0)

答案 6 :(得分: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;
}

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

答案 7 :(得分:0)

要在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);
    }
}