ListView在视图中一个接一个地加载图像

时间:2016-05-12 13:34:42

标签: android image listview android-asynctask

这个简单的应用程序从用户获取一个标签,并在ListView中显示与标签匹配的前10个闪烁图像。我使用了this简单教程,我只修改了它,因此可以使用闪烁搜索,而不是硬编码链接。它工作但不知何故它在一些视图中一个接一个地加载图像。因此用户可以看到视图中的图像会发生一段时间的变化。如果用户滚动,它会再次重新加载它们。如果它是一个指针问题,我无法解决它。我将静态ViewHolder更改为非静态类,但没有任何更改。为什么会发生这种情况?如何解决?

主要课程:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="file" id="files" multiple>
<ol></ol>

适配器类:

public class FlickerSearchMain extends AppCompatActivity implements AdapterView.OnItemClickListener, View.OnClickListener{
        private EditText tag;
        private Button send;
        private ListView listView;
        ArrayList<ListItem> listData;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_flicker_search_main);

            send = (Button) findViewById(R.id.send_button);
            send.setOnClickListener(this);  
            tag = (EditText) findViewById(R.id.tag_input);

            //ArrayList<ListItem> listData = getListData();
            listView = (ListView) findViewById(R.id.list);
            listView.setOnItemClickListener(this);


        }

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            int itemPosition = position;
            Toast.makeText(getApplicationContext(),
                    "Position :"+ itemPosition, Toast.LENGTH_SHORT)
                    .show();
        }


        @Override
        public void onClick(View v) {
            if(v == send){
                String input = tag.getText().toString();
                new FlickerRequest(this).execute(input);
            }
        }


        private class FlickerRequest extends AsyncTask<String, Void, ArrayList<ListItem>>{
            ArrayList<ListItem> elements_list;
            Context context;

            public FlickerRequest(Context context){
                this.context = context;
                this.elements_list = new ArrayList<ListItem>();

            }

            @Override
            protected ArrayList<ListItem> doInBackground(String... params) {
                String tag = params[0];

                int SIZE = 10;
                URL flicker;
                URLConnection urlcon;
                BufferedReader in = null;

                try {
                    flicker = new URL("https://api.flickr.com/services/feeds/photos_public.gne?tags="
                            + tag + "&format=json");
                    urlcon = flicker.openConnection();
                    in = new BufferedReader(new InputStreamReader(urlcon.getInputStream()));

                    String inputLine;
                    StringBuilder strbuilder = new StringBuilder();

                    in.skip(15);

                    while ((inputLine = in.readLine()) != null)
                        strbuilder.append(inputLine);

                    in.close();

                    JSONObject job = new JSONObject(strbuilder.toString());
                    JSONArray items = job.getJSONArray("items");

                    for(int i=0; i<SIZE; i++) {
                        JSONObject item = items.getJSONObject(i);
                        ListItem  newdata = new ListItem();
                        newdata.setHeadline(item.getString("title"));
                        newdata.setAuthor(item.getString("author"));
                        newdata.setDate(item.getString("date_taken"));
                        newdata.setUrl(item.getJSONObject("media").getString("m"));

                        elements_list.add(newdata);
                    }

                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                return elements_list;
            }

            protected void onPostExecute(ArrayList<ListItem> result) {
                if(listData == null) {
                    listData = result;
                    listView.setAdapter(new FlickerAdapter(context, listData));
                }
                else{
                    listData = result;
                    ((BaseAdapter) listView.getAdapter()).notifyDataSetChanged();
                }

            }

        }
    }

AsynTask ImageLoader类

    public class FlickerAdapter extends BaseAdapter {
        private ArrayList<ListItem> listData;
        private LayoutInflater layoutInflater;

        public FlickerAdapter(Context context, ArrayList<ListItem> listData) {
            this.listData = listData;
            layoutInflater = LayoutInflater.from(context);
        }

        @Override
        public int getCount() {
            return listData.size();
        }

        @Override
        public Object getItem(int position) {
            return listData.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if (convertView == null) {
                convertView = layoutInflater.inflate(R.layout.list_row_layout, null);
                holder = new ViewHolder();
                holder.headlineView = (TextView) convertView.findViewById(R.id.title);
                holder.authorView = (TextView) convertView.findViewById(R.id.author);
                holder.dateView = (TextView) convertView.findViewById(R.id.date);
                holder.imageView = (ImageView) convertView.findViewById(R.id.image);
                convertView.setTag(holder);

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

            ListItem newsItem = listData.get(position);
            holder.headlineView.setText(newsItem.getHeadline());
            holder.authorView.setText("By, " + newsItem.getAuthor());
            holder.dateView.setText(newsItem.getDate());

            if (holder.imageView != null) {
                new ImageDownloaderTask(holder.imageView).execute(newsItem.getUrl());
            }

            return convertView;
        }

        static class ViewHolder {
            TextView headlineView;
            TextView authorView;
            TextView dateView;
            ImageView imageView;
        }
    }

1 个答案:

答案 0 :(得分:0)

您必须确保填充ImageView的任务是ImageView的最新任务,因为在ImageView被回收之后,任务可能无法完成

这就是我的所作所为:

        if (holder.imageView != null) {
            Drawable placeholder = holder.imageView.getContext().getResources().getDrawable(R.drawable.penguin);
            holder.imageView.setImageDrawable(placeholder);

            ImageDownloaderTask task = new ImageDownloaderTask(holder.imageView);
            holder.imageView.setTag(R.id.tag_key, task);
            task.execute(newsItem.getUrl());
        }

...

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (isCancelled()) {
            bitmap = null;
        }

        if (bitmap != null && imageViewReference != null) {
            ImageView imageView = imageViewReference.get();
            if (imageView != null && imageView.getTag(R.id.tag_key) == this) {
                imageView.setImageBitmap(bitmap);
                imageView.setTag(R.id.tag_key, null);
            }
        }
    }

在您的资源中:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="tag_key" type="id" />
</resources>