【问题标题】:ListView Items change position on scrollListView 项目在滚动时更改位置
【发布时间】:2014-04-07 17:41:29
【问题描述】:

我已经实现了一个加载新闻的 ListView,但是当我滚动列表时新闻会改变位置。这是列表

public class ListNewsFragment extends SherlockListFragment{

private ListNewsAdapter mAdapter;

@Override
public void onCreate(Bundle savedInstanceState) {
    mAdapter = new ListNewsAdapter(this, app.getAllNews());
    setListAdapter(mAdapter);
    super.onCreate(savedInstanceState);
}
}


public class ListNewsAdapter extends BaseAdapter{
private List<News> news;
private Context mContext;
private LayoutInflater inflater;
private ViewHolder holder;

public ListNewsAdapter(final Fragment c, List<News> news) {
    super();
    this.news = news;
    this.mContext = c.getActivity();
    inflater = LayoutInflater.from(mContext);
}

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

    View v = convertView;
    if (v == null) {               
         inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);         
         holder = new ViewHolder();
         v = inflater.inflate(R.layout.fragment_list_news, null);

         holder.name = (TextView) v.findViewById(R.id.tittle);
         holder.tweet = (TextView) v.findViewById(R.id.news);
         holder.avatar = (ImageView) v.findViewById(R.id.image);


         holder.name.setText(news.get(position).getTitulo());
         holder.tweet.setText(news.get(position).getCopete());
         new ImagefetcherTask(position).execute(holder);

         v.setTag(holder);
    } else {              
     holder = (ViewHolder) convertView.getTag();          
     }                             
   return v; 

}

private class ViewHolder{
    public TextView name, tweet;
    public ImageView avatar;
}

private class ImagefetcherTask extends AsyncTask<ViewHolder, Void, ViewHolder> {

        private Bitmap bitmap;
        int position; 

        public ImagefetcherTask(int position) {
            this.position = position;
        }

        @Override
        protected ViewHolder doInBackground(ViewHolder... params) {
             ViewHolder viewHolder = params[0];

            try{
                bitmap = BitmapFactory.decodeStream((InputStream) new URL("...."+ news.get(position).getImagen().toString()).getContent());
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

          return viewHolder;
        }

    @Override
    protected void onPostExecute(ViewHolder result) {
        // TODO Auto-generated method stub
        if (bitmap == null) {
            result.avatar.setImageResource(com.dev.suma_intranet_v1.R.drawable.img_perfil);
        } else {
            result.avatar.setImageBitmap(bitmap);
        }
    }

}

}

【问题讨论】:

  • 只有在视图为 null 时才将文本设置为 textview,最好使用延迟加载来加载图像。还可以缓存它们,这样您就不必每次都下载
  • @Raghunandan 我该怎么做?
  • 在getView方法的else语句后移动设置为文本代码

标签: android listview


【解决方案1】:

将您的 getView() 方法更改为:

Map<Integer, View> views = new HashMap<Integer, View>;

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

    if (views.containsKey(position)) {    
         return views.get(position);
    }

     inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);         
     holder = new ViewHolder();
     View v = inflater.inflate(R.layout.fragment_list_news, null);

     holder.name = (TextView) v.findViewById(R.id.tittle);
     holder.tweet = (TextView) v.findViewById(R.id.news);
     holder.avatar = (ImageView) v.findViewById(R.id.image);

     holder.name.setText(news.get(position).getTitulo());
     holder.tweet.setText(news.get(position).getCopete());
     new ImagefetcherTask(position).execute(holder);

     v.setTag(holder); 
     views.put(position, v);
     return v; 

}

【讨论】:

  • 如果我这样做,图像会不断变化
  • 那是因为你的ImagefotherTask。你可以为它添加代码吗?我的猜测是,它会在您滚动并重用 View 后更新图像。如果列表中的项目数量有限,则可以停止重复使用View,它应该可以解决问题。您可能需要考虑将所有Views 存储在List 中。
  • 这就是我拥有的所有代码,是的,我有 30 个项目,如何停止重用视图?
  • 我已经更新了代码。如果 stmh 不清楚,请发表评论。
  • 据我所知,创建视图的成本很高。如果我现在要写答案,我真的会使用视图,而不仅仅是缓存它们。这样,代码将只使用屏幕上可以容纳的尽可能多的视图对象,而无需创建新对象。
【解决方案2】:

在您的else 语句之后调用您的ImageFetcherTextView.seText,以便当convertView 不是null 并且已被回收时,您正在更新您的行:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    if (v == null) {
        inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        holder = new ViewHolder();
        v = inflater.inflate(R.layout.fragment_list_news, null);

        holder.name = (TextView) v.findViewById(R.id.tittle);
        holder.tweet = (TextView) v.findViewById(R.id.news);
        holder.avatar = (ImageView) v.findViewById(R.id.image);

        v.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }
    holder.name.setText(news.get(position).getTitulo());
    holder.tweet.setText(news.get(position).getCopete());
    new ImagefetcherTask(position).execute(holder);
    return v;
}

【讨论】:

  • 还请写一些解释,以便他更好地理解ViewsTableView中的Recycling/Reusability
  • @adneal 如果我这样做,图像会不断变化
  • @IgnacioGarat 这可能与您的ImageFetcher 有关。
  • @IgnacioGarat 您没有检查该项目是否已被回收。您应该在 Android 开发者网站上阅读:Making ListView Scrolling Smooth
【解决方案3】:

我已经通过在我的适配器类中覆盖这两个方法来解决这个问题。

@Override
public int getViewTypeCount() {
   return getCount();
}

@Override
public int getItemViewType(int position) {
   return position;
}

【讨论】:

    【解决方案4】:

    尝试使用this 通用图像加载器库来延迟加载图像。并尝试捕捉图像。

    所以根据this 的答案将位图选项设置为

    DisplayImageOptions  options = new DisplayImageOptions.Builder()
                            .showImageOnLoading(R.drawable.ic_stub)
                            .showImageForEmptyUri(R.drawable.ic_empty)
                            .showImageOnFail(R.drawable.ic_error)
                            .cacheInMemory(true)
                            .cacheOnDisc(true)
                            .considerExifParams(true)
                            .build();
    

    我相信这会解决你的问题

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-21
      相关资源
      最近更新 更多