Android 使用自定义ArrayAdapter从GridView隐藏项目

Android 使用自定义ArrayAdapter从GridView隐藏项目,android,android-listview,android-arrayadapter,Android,Android Listview,Android Arrayadapter,我尝试使用以下代码动态隐藏GridView中的某些项: public class GridHelper extends ArrayAdapter<Object> { private Context context; private int layoutResourceId; private ArrayList<Object> mainlist = null; private ArrayList<Object> sic

我尝试使用以下代码动态隐藏GridView中的某些项:

public class GridHelper extends ArrayAdapter<Object>
{
    private Context context; 
    private int layoutResourceId;    

    private ArrayList<Object> mainlist = null;
    private ArrayList<Object> sichtbar = null;

    public GridHelper(Context context, int layoutResourceId, ArrayList<Object> mainlist) 
    {
        super(context, layoutResourceId, mainlist);

        this.layoutResourceId = layoutResourceId;
        this.context = context;

        this.mainlist = mainlist;
        this.sichtbar = ArrayList<Object>(); 
        // that's important otherwith the items are doublicated but the items 
        // are inside the List. I think the add method is called somewhere 
        // in the super constructor
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 
    {
        View row = convertView;

        if(row == null)
        {           
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, null);

            Object t = sichtbar.get(position);

            if(t != null)
           {
                row = (View) t;
           }
        }

        return row;
    }

    @Override
    public int getCount() 
    {
        return sichtbar.size();
    }

    @Override
    public void add(Object object)
    {
        super.add(object);
        sichtbar.add(object);
    }

    public void show(int pos)
    {
        if(sichtbar.contains(mainlist.get(pos)) == false)
        {
            sichtbar.add(mainlist.get(pos));
            notifyDataSetChanged();
        }
    }

    public void hide(int pos)
    {
        if(sichtbar.contains(mainlist.get(pos)) == true)
        {
            sichtbar.remove(mainlist.get(pos)); 
            notifyDataSetChanged();
        }
    }
}
公共类GridHelper扩展ArrayAdapter
{
私人语境;
私人内部布局资源;
private ArrayList mainlist=null;
私有ArrayList sichtbar=null;
公共GridHelper(上下文上下文、int-layoutResourceId、ArrayList主列表)
{
超级(上下文、布局资源ID、主列表);
this.layoutResourceId=layoutResourceId;
this.context=上下文;
this.mainlist=mainlist;
this.sichtbar=ArrayList();
//这一点很重要,因为项目是双重的,但是项目
//在列表中。我想add方法在某个地方被调用了
//在超级构造函数中
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图)
{
视图行=转换视图;
if(行==null)
{           
LayoutInflater充气器=((活动)上下文)。getLayoutInflater();
行=充气机。充气(布局资源ID,空);
对象t=sichtbar.get(位置);
如果(t!=null)
{
行=(视图)t;
}
}
返回行;
}
@凌驾
public int getCount()
{
返回sichtbar.size();
}
@凌驾
公共无效添加(对象)
{
super.add(object);
sichtbar.add(对象);
}
公共无效显示(int pos)
{
if(sichtbar.contains(mainlist.get(pos))==false)
{
sichtbar.add(mainlist.get(pos));
notifyDataSetChanged();
}
}
公共无效隐藏(int pos)
{
if(sichtbar.contains(mainlist.get(pos))==true)
{
sichtbar.remove(mainlist.get(pos));
notifyDataSetChanged();
}
}
}
但是搜索功能不起作用。在我的show/hide方法之后,列表的大小是正确的,但是第一个项目(
mainlist.get(0)
)始终可见,我认为它涵盖了正确的项目。我发现
getView
方法的调用总是比列表大小大一倍。如果列表有3项,则调用
getView
方法4次,依此类推

第二件事是:如果我在GridView中有3个项目,并为两个项目调用hide函数,
getView
methode被调用4次(旧大小+1),然后再调用2次(新大小+1)。这很奇怪,不是吗


为什么呢?我认为它背后的逻辑是正确的,不是吗?

我认为最简单的方法是在适配器中维护两个单独的列表。一个包含所有项,另一个仅包含可见项。或者一个包含可见项,另一个包含不可见项。两者皆有可能。请记住
getCount()
必须返回可见的项目数。

您的第一个项目始终可见(并且您可以看到getCount first items)(因为在
getView
中,您始终返回第一个元素

在我看来,您的SichBar中似乎包含要在GridView中显示的视图实例。在我看来,如果您已经扩展了这些元素,那么您的getView应该如下所示:

public View getView(int position, View convertView, ViewGroup parent) 
    {
        View row = convertView;
        row = (sichtbar.get(position) != null) ? (View)sichtbar.get(position) : row;
        return row;
    }
第二件事是:如果我在GridView中有3项,并调用 隐藏两项的函数getView方法调用4次( 旧尺码+1)和2倍以上(新尺码+1)。这非常重要 很奇怪,不是吗


无法保证调用getView回调的次数

好的,谢谢。我尝试过这样做,但现在不起作用。我用新的发现更新了我的问题。你能看一下吗?首先,无论多久调用一次
getView()调用了
。我认为可能会发生使用相同的位置参数多次调用它的情况。其次,不要将视图对象保存在可见列表中。这将导致混乱,因为ListView将循环视图。改为保存数据对象。我猜在开始时,所有项目都是可见的,因此您可以初始化使用this.sichtbar=ArrayList(mainlist)设置可见列表的大小并从中删除要隐藏的对象。我认为将视图对象存储在适配器中是一个好主意。我有许多对象,它们都扩展了线性布局,但都具有不同的XML布局。在这些对象的构造函数中,我加载了与对象完全相同的XML布局,以便可以添加所有不同的obj使用一个ArrayAdapter的ects,不必编写多个。这不是一个好主意吗?
ListView
为您处理许多子视图管理-比如重新使用不再可见的视图。您基本上希望删除所有这些功能,并以不希望的方式使用它。也许您应该考虑R使用另一个布局。例如,<代码>线性布局< /代码>。但是这确实取决于您的确切用例。好吧,我不知道,但是它是合理的。您应该考虑使用另一个布局吗?例如,一个线性布局?线性布局是如何解决这个问题的?谢谢,答案是GRE。at!现在就像一个符咒:)但我不明白为什么我总是返回第一个元素。我想我是用
Object t=sichtbar.get(position)
来实现的。