listview 列表项中的子项变为空 p.e.当视图回收

Posted

技术标签:

【中文标题】listview 列表项中的子项变为空 p.e.当视图回收【英文标题】:child in listview list item becomes null p.e. when view recycled 【发布时间】:2018-02-27 18:35:51 【问题描述】:

按钮视图的可见性应该改变onClick,但是当视图回收时,所述视图出现空。似乎是以下项目可见性的状态与列表中的先前状态不同时。这是相关的Java:

class OpenChavrutaAdapter extends ArrayAdapter<HostSessionData> 


private Context mContext;
private static final String LOG_TAG = 
OpenChavrutaAdapter.class.getSimpleName();
HostSessionData hostSessionItemData;

public OpenChavrutaAdapter(Context context, ArrayList<HostSessionData> 
hostSessionArrayList) 
    super(context, 0, hostSessionArrayList);
    this.mContext = context;

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

    //get data item for position
    final ViewHolder viewHolder;
    View listItemView = convertView;
    Boolean hostListItemView = true;
    String userId = UserDetails.getmUserId();
    final HostSessionData hostLookup = getItem(position);
    final String hostId = hostLookup.getmHostId();


    if (listItemView == null) 
        viewHolder = new ViewHolder();

        //sets correct listItemView based on Caller's Context
        if (hostId.equals(userId) && mContext == mainActivityContext) 
            hostListItemView = true;
            listItemView = 
LayoutInflater.from(
getContext()).inflate(R.layout.hosting_chavrutas_list_item, parent, false); 

 else 
    //adapter called from HostSelect.class
    listItemView = 
LayoutInflater.from(getContext()).inflate(R.layout.open_host_list_item, 
parent, false);
    hostListItemView = false;
           
//cache the viewHoslder object inside the fresh view
        listItemView.setTag(viewHolder);

     else 
        //view is already been populated
        hostListItemView = false;
        viewHolder = (ViewHolder) listItemView.getTag();
    
    final HostSessionData hostSessionDatas = getItem(position);

    if (hostListItemView) 
        String idOfConfirmedUser = hostLookup.getmConfirmed();
        String request1NullCheck = hostLookup.getMchavrutaRequest1();
        String request2NullCheck = hostLookup.getMchavrutaRequest2();
        String request3NullCheck = hostLookup.getMchavrutaRequest3();

下面是尝试 setVisibility 时抛出 NPE 的情况!!似乎仅当“pendingRequest1”按钮线性布局视图处于与填充的前一个视图不同的状态时才会发生。请...一些见解!

        if (request1NullCheck != null && 
hostLookup.getMchavrutaRequest1().length() > 5) 
            String chavrutaRequestIdOne = hostLookup.getMchavrutaRequest1();
            viewHolder.pendingRequest_1.setVisibility(View.VISIBLE);

            if( idOfConfirmedUser.equals(chavrutaRequestIdOne))  
viewHolder.confirmRequest_1.setBackgroundColor(Color.parseColor("#10ef2e"));
            
        elseviewHolder.pendingRequest_1.setVisibility(View.GONE);
        notifyDataSetChanged();
    
    return listItemView;

【问题讨论】:

【参考方案1】:

问题是您使用了两种不同的布局。当视图被回收时,它有可能是两者中的任何一个,而您不知道会得到哪一个。当 convertView 不为 null 时,会跳过使视图膨胀的代码,因此是 NPE。

好消息是有一种简单的方法可以使用 BaseAdapter 类解决这个问题。

您需要在适配器中覆盖的方法是 getItemViewType 和 getViewTypeCount。

这将帮助您的适配器知道如何将空视图传递给您的 getView 方法以进行回收。

【讨论】:

已解决!..我尝试通过 bool "hostListItemView" 监视活动的 viewType,但是当视图回收时,这并没有改变!使用 getItemViewType 并且效果很好!谢谢

以上是关于listview 列表项中的子项变为空 p.e.当视图回收的主要内容,如果未能解决你的问题,请参考以下文章

uiautomator - 当我验证每个列表项中的文本时,无法让 ListView 滚动。当我点击屏幕上的最后一个项目时它就失败了

在android中,当我按了listview中的一个子项时,利用ContextMenu弹出菜单,那怎么获取这个子项的数据呢?

过滤列表项后,ListView 中的 SwiftUI TextField 变为空白

如何将ListView选中的item编号提取出来

无法从 ListView 项中检索 Intent 的地址和电话号码

C#:在运行时添加项目和子项目时,VirtualMode 中的 ListView 不显示设计时列?