用于textview和imageview的android listview asynctask

时间:2015-05-31 19:47:54

标签: android android-listview android-asynctask

我正在尝试从google books api调用生成一个android listview, google books api调用返回JSON数据,其中一个属性是图书缩略图的URL,所以我考虑运行第一个asynctask,它将调用JSON google books API然后onPostExecute我将运行第二个asynctask来获取缩略图并将它们设置为图像视图但是行为不正确并且缩略图与列表视图中的正确行没有关联,而只获取第一行中的图像视图时获取缩略图,并且当下载完成时,订单混乱。

以下是我的代码摘录:

private class BookSearchListAdapter extends BaseAdapter {
    private ArrayList<Book> mBooks = new ArrayList<>();
    private LayoutInflater mLayoutInflater;

    public BookSearchListAdapter(Context c, ArrayList<Book> books) {
        mLayoutInflater = LayoutInflater.from(c);
        this.mBooks = books;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            convertView = mLayoutInflater.inflate(R.layout.view_book_search_row, null);
            holder = new ViewHolder();
            holder.mImageView = (ImageView) convertView.findViewById(R.id.book_cover_thumbnail);
            holder.mTitleTextView = (TextView) convertView.findViewById(R.id.book_title);
            holder.mAuthorTextView = (TextView) convertView.findViewById(R.id.book_author);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        Book b = mBooks.get(position);
        holder.mAuthorTextView.setText(TextUtils.join(", ", b.getAuthors()));
        holder.mTitleTextView.setText(b.getTitle());
        if (!b.getThumbnail().equalsIgnoreCase("")) {
            new ThumbNailDownloaderTask(holder.mImageView).execute(b.getThumbnail());
        }

        return convertView;
    }

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

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

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

private static class ViewHolder {
    ImageView mImageView;
    TextView mTitleTextView;
    TextView mAuthorTextView;
}

private class SearchBookTask extends AsyncTask<String, Void, String> {

    private final String TAG = "SearchBookTask";

    private ArrayList<Book> mBooks = new ArrayList<>();

    private final static String BOOK_ITEMS_KEY = "items";
    private final static String BOOK_VOLUMEINFO_KEY = "volumeInfo";
    private final static String BOOK_IMAGELINKS_KEY = "imageLinks";
    private final static String BOOK_ID_KEY = "id";
    private final static String BOOK_TITLE_KEY = "title";
    private final static String BOOK_AUTHORS_KEY = "authors";
    private final static String BOOK_DESCRIPTION_KEY = "description";
    private final static String BOOK_THUMBNAIL_KEY = "thumbnail";

    @Override
    protected String doInBackground(String... params) {
        String bookQuery = params[0];
        String url = Uri.parse(ENDPOINT).buildUpon()
                .appendQueryParameter("q", bookQuery)
                .appendQueryParameter("maxResults", "10")
                .appendQueryParameter("key", API_KEY)
                .build().toString();
        String result = new GoogleFetcher().getUrl(url);
        return result;
    }

    @Override
    protected void onPreExecute() {
        mEmptyTextView.setVisibility(View.GONE);
        mProgressBar.setVisibility(View.VISIBLE);
    }

    @Override
    protected void onPostExecute(String s) {
        if (s != null) {
            mProgressBar.setVisibility(View.GONE);
            constructBooksFromJSONResponse(s);
            mSearchResultListView.setAdapter(new BookSearchListAdapter(getActivity(), mBooks));
        }
    }

    @Override
    protected void onCancelled() {
        mProgressBar.setVisibility(View.GONE);
    }

    private void constructBooksFromJSONResponse(String jsonResponse) {
        try {
            JSONObject obj = new JSONObject(new JSONTokener(jsonResponse));
            JSONArray jsonArray = obj.getJSONArray(BOOK_ITEMS_KEY);
            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject currentObj = jsonArray.getJSONObject(i);

                String bookId = "";
                if (currentObj.has(BOOK_ID_KEY)) {
                    bookId = currentObj.getString(BOOK_ID_KEY);
                }

                JSONObject volumeInfo = currentObj.getJSONObject(BOOK_VOLUMEINFO_KEY);
                String bookTitle = "";
                if (volumeInfo.has(BOOK_TITLE_KEY)) {
                    bookTitle = volumeInfo.getString(BOOK_TITLE_KEY);
                }

                JSONArray bookAuthors = new JSONArray();
                if (volumeInfo.has(BOOK_AUTHORS_KEY)) {
                    bookAuthors = volumeInfo.getJSONArray(BOOK_AUTHORS_KEY);
                }
                ArrayList<String> authors = new ArrayList<>();
                if (bookAuthors != null) {
                    for (int j = 0; j < bookAuthors.length(); j++) {
                        authors.add(bookAuthors.getString(j));
                    }
                }

                String bookDescription = "";
                if (volumeInfo.has(BOOK_DESCRIPTION_KEY)) {
                    bookDescription = volumeInfo.getString(BOOK_DESCRIPTION_KEY);
                }

                JSONObject imageLinks = volumeInfo.getJSONObject(BOOK_IMAGELINKS_KEY);
                String bookThumbnail = "";
                if (imageLinks.has(BOOK_THUMBNAIL_KEY)) {
                    bookThumbnail = imageLinks.getString(BOOK_THUMBNAIL_KEY);
                }

                Book b = new Book(bookId, authors, bookTitle, bookDescription, bookThumbnail);
                mBooks.add(b);
            }
        } catch (JSONException e) {
            mBooks.clear();
        }
    }
}

private class ThumbNailDownloaderTask extends AsyncTask<String, Void, Bitmap> {

    private final WeakReference<ImageView> imageViewReference;

    private ThumbNailDownloaderTask(ImageView imageView) {
        imageViewReference = new WeakReference<ImageView>(imageView);
    }

    @Override
    protected Bitmap doInBackground(String... params) {
        return downloadBitmap(params[0]);
    }

    private Bitmap downloadBitmap(String param) {
        HttpURLConnection urlConnection = null;
        try {
            URL url = new URL(param);
            urlConnection = (HttpURLConnection) url.openConnection();
            int statusCode = urlConnection.getResponseCode();
            if (statusCode != HttpURLConnection.HTTP_OK) {
                return null;
            }
            InputStream in = urlConnection.getInputStream();
            if (in != null) {
                Bitmap bitmap = BitmapFactory.decodeStream(in);
                return bitmap;
            }
        } catch (IOException e) {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
        }
        return null;
    }

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

        if (imageViewReference != null) {
            ImageView imageView = imageViewReference.get();
            if (imageView != null) {
                if (bitmap != null) {
                    imageView.setVisibility(View.VISIBLE);
                    imageView.setImageBitmap(bitmap);
                }
            }
        }
    }
}

和触发搜索的搜索按钮如下:

 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_addbook, container, false);

    mSearchEditText = (EditText) v.findViewById(R.id.book_title_search_field);
    mSearchButton = (Button) v.findViewById(R.id.search_button);
    mSearchButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String bookQuery = mSearchEditText.getText().toString();
            new SearchBookTask().execute(bookQuery);
        }
    });
return v;
}

1 个答案:

答案 0 :(得分:1)

您可以尝试使用Volley ListView库。获取有关image cache的更多信息。你可以找到体面的教程herehere。它应该能够正确加载{{1}}张图片。