v.getTag() 返回 null 而不是 ViewHolder

发布于 2024-11-25 17:52:08 字数 1847 浏览 0 评论 0原文

我有一个自定义适配器,它有标题和自定义行。有时我的 v.getTag() 在我存储 ViewHolder 的位置返回 null。它不会一直发生,我不知道它何时以及为何发生。

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

    //Header
    if(items.hasDescription() && 0 == position) {
        LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.app_list_header, null); 
        ((TextView) v.findViewById(R.id.app_list_header_description_text)).setText(items.getDescription());
        return v;
    }

    ViewHolder holder;
    // Inflate app view.
    if (v == null || v.getTag() == null) {
        LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(textViewResourceId, null); //TODO: parent instead of null?
        holder = new ViewHolder();
        holder.title = (TextView) v.findViewById(R.id.title);
        holder.company = (TextView) v.findViewById(R.id.company);
        holder.priceOrStatus = (TextView) v.findViewById(R.id.price);
        holder.rating = (RatingBar) v.findViewById(R.id.rating);
        holder.icon = (ImageView) v.findViewById(R.id.icon);
        v.setTag(holder);
    } else {
        holder = (ViewHolder) v.getTag();
    }

}
    App app;
    if(items.hasDescription()) {
        app = items.get(position-1);    
    } else {
        app = items.get(position);
    }

    // TODO: Do we need this?
    if (null == app || null == holder) {
        Log.d(TAG, "app: " +app +" holder: " +holder);
        return v;
    }

    //TODO: FIX THE XML BEFORE SO WE DO NOT NEED TO TRIM IT.
    // And get rid of all these ifs!!
    if(holder.title != null) {
        holder.title.setText(app.getTitle().trim());                            

    }

有人可以帮我吗?

I have a customized adapter that has a header and customized rows. Sometimes my v.getTag() returns null where I have stored my ViewHolder. It does not happen all the times and I can not figure out when and why it accurs.

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

    //Header
    if(items.hasDescription() && 0 == position) {
        LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.app_list_header, null); 
        ((TextView) v.findViewById(R.id.app_list_header_description_text)).setText(items.getDescription());
        return v;
    }

    ViewHolder holder;
    // Inflate app view.
    if (v == null || v.getTag() == null) {
        LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(textViewResourceId, null); //TODO: parent instead of null?
        holder = new ViewHolder();
        holder.title = (TextView) v.findViewById(R.id.title);
        holder.company = (TextView) v.findViewById(R.id.company);
        holder.priceOrStatus = (TextView) v.findViewById(R.id.price);
        holder.rating = (RatingBar) v.findViewById(R.id.rating);
        holder.icon = (ImageView) v.findViewById(R.id.icon);
        v.setTag(holder);
    } else {
        holder = (ViewHolder) v.getTag();
    }

}
    App app;
    if(items.hasDescription()) {
        app = items.get(position-1);    
    } else {
        app = items.get(position);
    }

    // TODO: Do we need this?
    if (null == app || null == holder) {
        Log.d(TAG, "app: " +app +" holder: " +holder);
        return v;
    }

    //TODO: FIX THE XML BEFORE SO WE DO NOT NEED TO TRIM IT.
    // And get rid of all these ifs!!
    if(holder.title != null) {
        holder.title.setText(app.getTitle().trim());                            

    }

Can anyone help me out?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

苍白女子 2024-12-02 17:52:08

您在此处使用自定义 ListAdapter 的标准模式。并非所有视图都会被回收,例如当它们首次创建以填充 ListView 时。

您可能还想在创建适配器时引用 LayoutInflater 以稍微提高效率,请参阅下面的代码片段

 private class AlertListAdapter extends ArrayAdapter< Alert >
 {
        private ViewHolder     holder;
        private LayoutInflater mInflater;

        public AlertListAdapter( Context context, List< Alert > items )
        {
            super( context, R.layout.dashboard_layout, items );
            mInflater = LayoutInflater.from( context );
        }

        public View getView( int position, View recycledView, ViewGroup parent )
        {
            if ( recycledView == null || recycledView.getTag() == null )
            {
                recycledView = mInflater.inflate( R.layout.list_item, null );

                holder = new ViewHolder();                
                holder.header = ( LinearLayout ) recycledView.findViewById( R.id.alert_list_item_header );
                holder.header_text = ( TextView ) recycledView.findViewById( R.id.alert_list_item_header_text );
                holder.header_count = ( TextView ) recycledView.findViewById( R.id.alert_list_item_header_count );
                holder.name = ( TextView ) recycledView.findViewById( R.id.alert_list_item_name );
                holder.distance = ( TextView ) recycledView.findViewById( R.id.alert_list_item_distance );

                recycledView.setTag( holder );
            }
            else
            {
                holder = ( ViewHolder ) recycledView.getTag();
            }

                holder.header_text.setText( title.substring( 0, space ) );
                holder.name.setText( title.substring( space + 1 ) );
                holder.header_count.setText( count );    
                holder.header.setBackgroundResource( resourceID );    

            return recycledView;
        }
    }

本质上,您必须始终为 v.getTag() 做好准备返回 null 并相应地膨胀一个新的 View

You're using the standard pattern for a custom ListAdapter here. Not all views will be recycled e.g. when they are first created to fill the ListView.

You may also want to take a reference the the LayoutInflater when you create the adapter to slightly improve efficiency, see snippet below

 private class AlertListAdapter extends ArrayAdapter< Alert >
 {
        private ViewHolder     holder;
        private LayoutInflater mInflater;

        public AlertListAdapter( Context context, List< Alert > items )
        {
            super( context, R.layout.dashboard_layout, items );
            mInflater = LayoutInflater.from( context );
        }

        public View getView( int position, View recycledView, ViewGroup parent )
        {
            if ( recycledView == null || recycledView.getTag() == null )
            {
                recycledView = mInflater.inflate( R.layout.list_item, null );

                holder = new ViewHolder();                
                holder.header = ( LinearLayout ) recycledView.findViewById( R.id.alert_list_item_header );
                holder.header_text = ( TextView ) recycledView.findViewById( R.id.alert_list_item_header_text );
                holder.header_count = ( TextView ) recycledView.findViewById( R.id.alert_list_item_header_count );
                holder.name = ( TextView ) recycledView.findViewById( R.id.alert_list_item_name );
                holder.distance = ( TextView ) recycledView.findViewById( R.id.alert_list_item_distance );

                recycledView.setTag( holder );
            }
            else
            {
                holder = ( ViewHolder ) recycledView.getTag();
            }

                holder.header_text.setText( title.substring( 0, space ) );
                holder.name.setText( title.substring( space + 1 ) );
                holder.header_count.setText( count );    
                holder.header.setBackgroundResource( resourceID );    

            return recycledView;
        }
    }

Essentially you must always be prepared for v.getTag() to return null and inflate a new View accordingly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文