【问题标题】:ListView filling items all the time in the adapter适配器中的ListView一直在填充项目
【发布时间】:2012-05-12 13:49:38
【问题描述】:

下面是我的ListView 适配器。您可以在其中看到有一个FillData 函数为列表项填充数据。我看到它总是被调用。列表和ListAdapter 不应该每项填写一次吗?我做错了什么?

public class GlobalRecipeListAdapter extends ArrayAdapter<Recipe> {

    private final static String mTAG = "GlobalRecipeListAdapter";

    private LayoutInflater  mInflater = null;
    private int mListViewItemResId  = -1;
    private ImageLoader mImageLoader = new ImageLoader( CookTales.Instance() );

    public GlobalRecipeListAdapter(Context context, int resId, ArrayList<Recipe> items) {
         super(context, resId, items );
         mListViewItemResId = resId;
         mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

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

        if (convertView == null) {
            convertView = mInflater.inflate( mListViewItemResId, null );
            holder.recipePic = new DisplayableImageView( (ImageView) convertView.findViewById( R.id.list_RecipeImageViewId ) );
            holder.name = (TextView)  convertView.findViewById( R.id.name_entry );
            holder.author = (TextView)  convertView.findViewById( R.id.username_entry );
            holder.likes = (TextView)  convertView.findViewById( R.id.likes_entry );
            holder.diffculty = (ImageView) convertView.findViewById( R.id.list_DifficultyImageViewId );
            holder.preparationTime = (ImageView) convertView.findViewById( R.id.list_TimeImageViewId );
            holder.recipePic.GetImageView().setOnClickListener(new ImageClickListener(getContext(), holder.recipePic)); 
                holder.name.setTypeface( CookTales.Fonts.ARIAL );
            holder.name.setTextSize(  CookTales.Fonts.RUNNING_TEXT_SIZE );
            holder.author.setTypeface(  CookTales.Fonts.ARIAL );
            holder.author.setTextSize(  CookTales.Fonts.RUNNING_TEXT_SIZE );
            holder.likes.setTypeface(  CookTales.Fonts.ARIAL );
            holder.likes.setTextSize(  CookTales.Fonts.RUNNING_TEXT_SIZE );
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        if( super.getItem(position) != null) {
            if( position == 0 && position == getCount() - 1 ) {
                convertView.setBackgroundResource( R.drawable.list_single );                } else if( position == 0 ) {
                convertView.setBackgroundResource( R.drawable.list_up );
            }
            else if( position == getCount() - 1 ) {
                convertView.setBackgroundResource( R.drawable.list_down );
            } else {
                convertView.setBackgroundResource( R.drawable.list_middle );                }

            FillRecipeDataToHolder( position, holder );
            convertView.setTag(holder);
        } else  {
            holder = (ViewHolder)convertView.getTag();
        }    
        return convertView;
    }

    protected void FillRecipeDataToHolder(int position, ViewHolder viewHolder ) {
        viewHolder.name.setText( getItem(position).GetName() );
        viewHolder.author.setText( getItem(position).GetAuthor() );
        viewHolder.likes.setText( getItem(position).GetNumOfLikes() + " likes.");

        viewHolder.diffculty.setImageResource( Convertor.Difficulty2ImageResId( getItem(position).GetDifficulty(), mTAG ) );
        viewHolder.preparationTime.setImageResource( Convertor.Time2ImageResId( getItem(position).GetPreparationTime() ) );

        if( getItem( position ).GetRecipePicture().isValid() ){
            viewHolder.recipePic.GetImageView().setImageResource( Convertor.Category2ImageView( getItem( position ).GetCategory(), mTAG ) );
            mImageLoader.DisplayImage(  getItem( position ).GetRecipePicture().GetImageLocation(), 
                                        getItem( position ).GetRecipePicture().isUploaded() == false,
                                        getContext(), 
                                        viewHolder.recipePic );
        }
        else
        {
            viewHolder.recipePic.GetImageView().setImageResource( Convertor.Category2ImageView( getItem( position ).GetCategory(), mTAG ) );
        }
    }

    static protected class ViewHolder {
        DisplayableImageView    recipePic;
        TextView                name;
        TextView                author;
        TextView                likes;
        ImageView               diffculty;
        ImageView               preparationTime;
    }
}

【问题讨论】:

    标签: android android-listview


    【解决方案1】:

    getView()(和你的FillRecipeDataToHolder())方法将在每次ListView 需要一个新视图(因为用户上下滚动列表)显示在可见屏幕上时被调用。

    如果用户滚动列表直到最后一个元素,该方法将为适配器中的每个项目调用,然后如果用户再次开始向上滚动,那么getView() 方法也将再次为与用户滚动(并且每次都会调用您的填充方法)。

    【讨论】:

    • 但是为什么行:holder = (ViewHolder)convertView.getTag();从未调用过?
    • @user1136875 应该调用该行,因为该列表将回收视图。你怎么看它没有被调用?此外,convertView.setTag(holder); 应该在你对convertView(如果它为空)进行膨胀之后放在 if 子句中。
    【解决方案2】:

    当您使用标准列表适配器时,框架仅构建足以填满屏幕(以节省内存和 CPU 周期)。您已经构建了一个自定义的,并且正在使用一个视图持有者,它正在做同样的事情。

    如果您列出的列表不超过一个屏幕,我相信您会看到您所期望的活动(或其 lac)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-22
      • 1970-01-01
      • 2018-02-10
      • 2016-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-22
      相关资源
      最近更新 更多