Android BaseAdapter:getView()返回时convertView为null

Android BaseAdapter:getView()返回时convertView为null,android,baseadapter,convertview,Android,Baseadapter,Convertview,我正在根据中描述的技术构建一个包含部分的ListView。但我想通过对非节项重用convertView来扩展它。但是,我发现每次输入getView()方法时,convertView变量都为null。有人能解释一下为什么会这样吗 ViewHolder holder; final ListViewItem item = items.get(position); if (item.isSection()) { Section section = (Section)item; con

我正在根据中描述的技术构建一个包含部分的ListView。但我想通过对非节项重用convertView来扩展它。但是,我发现每次输入getView()方法时,convertView变量都为null。有人能解释一下为什么会这样吗

ViewHolder holder;
final ListViewItem item = items.get(position);

if (item.isSection()) {
    Section section = (Section)item;

    convertView = inflater.inflate(R.layout.section, null);
    TextView title = (TextView) convertView.findViewById(R.id.section_title);
    title.setText(section.title);
} else {
    if (convertView == null) {
        Log.d("Adapter", "convertView was null");
    }

    Server server = (Server)item;

    convertView = inflater.inflate(R.layout.server_row, null);
    holder = new ViewHolder();
    holder.serverName = (TextView) convertView.findViewById(R.id.server_name);
    holder.serverStatusIcon = (ImageView)convertView.findViewById(R.id.server_status_icon);
    convertView.setTag(holder);

    holder.serverName.setText(server.name);
}

return convertView;

列表正在创建和显示中,没有错误,并且包含部分和非部分项目。我刚刚使用我创建的GridView完成了此操作。当我尝试将新膨胀的视图分配给convertView时,出现了问题。我采用的一般结构是

public View getView(int position, @Nullable View convertView, ViewGroup parent) {

    View newView = null;
    TextView someText;

    // Test to see if there is already a view, if not create one, else use what is
    // already existant in convertView
    if (null == convertView) {
        // inflate your view type into newView here
        newView = myInflater.inflate(R.layout._________);

        // Get all of your subviews you wish to edit here from newView
        someText = (TextView)newView.findViewById(R.id._______);
    }else{
        // Get all of your subviews you wish to edit here from convertView
        someText = (TextView)convertView.findViewById(R.id._______);
    }

    // Perform all re-alignments, view layouts etc... here

    // Perform all updating of subviews data here

    // Return structure
    if (null == convertView) {
        return newView;
    } else {
        return convertView;
    }
}

希望这有帮助

您的实施是否正确

getItemViewType (int position) ?
请参阅Android的文档:

返回

表示视图类型的整数。如果一个视图可以在getView(int、View、ViewGroup)中转换为另一个视图,则两个视图应共享相同的类型。注意:整数必须在0到getViewTypeCount()的范围内-1。也可以返回忽略\u项\u视图\u类型

因此,convertView可能总是空的,因为适配器不知道哪些项属于一起,所以它不知道哪些项经过循环使用

试试这个:

@Override
public int getItemViewType(int position) {
    if (((MyItem)getItem(position)).isHeader()) {
        return 1;
    } else {
        return 0;
    }
}

@Override
public int getViewTypeCount() {
    return 2;
}
在getItemViewType中返回的索引只是将标题分组的标识符,而不是将标题分组在一起


在这种情况下,您必须在模型项中实现一个方法“isHeader”(或类似方法)。

感谢您让我想起了Ixx:我没有注意到的是,我的列表很短,实际上从未填满屏幕,因此没有进行回收

为完整起见,我将补充一点,如果您创建多个视图类型,getView()会根据其默认实现返回convertView,即使您没有覆盖getItemViewType()和getViewTypeCount()。当然,这可能不是你想要的行为

public int getItemViewType(int position) {
    return 0;
}

public int getViewTypeCount() {
    return 1;
}

你在哪里用这个?在ListView、ExpandableListView、Gallery、Spinner……中,如果没有可重用的视图,Android将向convertView参数传递null。我在API中查看了这些方法,但它没有说它们是必需的。我希望收到上次返回的任何视图。但是,我确实添加了这些方法(如您的帖子所示),并且仍然收到null convertView。我猜您无法从上次获取视图,因为您很可能仍然在使用它(列表中的前一个元素)。框架决定何时向您传递要回收的“旧”视图。现在,如果您使用的是不同类型的项,那么框架无法向您传递任何视图,它必须知道回收(旧)视图与您正在创建的视图兼容。这些方法有助于实现这一点。它们不是必需的,因为如果不实现它,它不会破坏任何东西。但是你不能循环使用视图,并且总是空的(这只是我的理论)。但是为什么你不尝试去实现它,看看它是否有帮助。这个理论是不正确的,但它确实帮助我找到了答案。非常感谢。如果我理解正确的话,您的意思可能是第一次需要使用自声明的视图变量。我对此进行了测试,结果似乎没有什么不同。我似乎可以毫无问题地充气到converView。不过,谢谢你的建议。