2

このカスタム アダプタによってロードされた画像が間違った位置に配置されます。つまり、正しいムービー バナーが正しいリスト ビュー アイテムに配置されません。しばらく変化し続けます。これは、URLから画像をロードしているASYNCTASKを備えた私のカスタムアダプターです

    import java.net.URL;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.List;

    import android.content.Context;
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.net.Uri;
    import android.os.AsyncTask;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ArrayAdapter;
    import android.widget.ImageView;
    import android.widget.TextView;
    import androlizer.yify.torrent.R;
    import androlizer.yify.torrents.models.UpcomingMovieListModel;

    public class UpcomingMoviesCustomAdapter extends ArrayAdapter<UpcomingMovieListModel> {


        Context context;
        public UpcomingMoviesCustomAdapter(
                Context context, int resource, List<UpcomingMovieListModel> objects) {
            super(context, resource, objects);
            this.context = context;
        }

        static class ViewHolder
        {
            TextView movieTitle_textView;
            TextView uploader_textView;
            TextView date_textView;
            ImageView movie_icon_imageView;
            ImageView imdb_url_imageView;
        }

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

            final ViewHolder holder;
            // getting data
            final UpcomingMovieListModel movie = getItem(position);     

            if (convertView == null) 
            {
                convertView = View.inflate(context, R.layout.movie_upcoming_row, null);                
                holder = new ViewHolder();

                holder.movieTitle_textView = (TextView) convertView.findViewById(R.id.movie_upcoming_movie_title);
                holder.uploader_textView = (TextView) convertView.findViewById(R.id.movie_upcoming_uploader);
                holder.date_textView = (TextView) convertView.findViewById(R.id.movie_upcoming_date);
                holder.imdb_url_imageView = (ImageView)convertView.findViewById(R.id.movie_upcoming_imageView_imdblink);
                holder.movie_icon_imageView = (ImageView)convertView.findViewById(R.id.movie_upcoming_movie_image_view);
                convertView.setTag(holder);
            }
            else
            {
                holder = (ViewHolder)convertView.getTag();
            }

            if (movie != null) 
            {
                holder.movieTitle_textView.setText(movie.getM_title());
                holder.uploader_textView.setText(movie.getUploader());

                SimpleDateFormat origFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                //Store it as a date object
                Date date = null;
                try {
                    date = origFormat.parse(movie.getDate_added());
                } catch (ParseException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                //Output it as a string that uses the new format
                SimpleDateFormat newFormat= new SimpleDateFormat("MMMMMMMMM dd, yyyy 'at' hh:mm a");

                String desiredDateFormat = newFormat.format(date);
                holder.date_textView.setText(desiredDateFormat);

                holder.imdb_url_imageView.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(movie.getImdb_url())));
                    }
                }); 
            }

            new ImageLoader().execute(convertView.g, movie.getM_cover());
            return convertView;

        }

        public class ImageLoader extends AsyncTask<Object, String, Bitmap> {

            private View view;
            private Bitmap bitmap = null;

            @Override
            protected Bitmap doInBackground(Object... parameters) {

                // Get the passed arguments here
                view = (View) parameters[0];
                String uri = (String)parameters[1];

                // Create bitmap from passed in Uri here
                // ...
                try {
                    URL req = new URL(uri);
                    bitmap = BitmapFactory.decodeStream(req.openConnection()
                            .getInputStream());
                } catch (Exception e) {
                    // TODO: handle exception
                }
                return bitmap;
            }

            @Override
            protected void onPostExecute(Bitmap bitmap) {
                if (bitmap != null && view != null) {
                    ImageView splash = (ImageView) view.findViewById(R.id.movie_upcoming_movie_image_view);
                    splash.setImageBitmap(bitmap);          
                }
            }
        }
    }
4

2 に答える 2

0

ここで起こっていることは、画像をロードして現在のリスト項目の ImageView に設定しているが、そのビットマップを他の場所に保存していないということです。Android の ListItems は再利用されるため、スクロールするときにデバイスが多くの ListItems をメモリに保存する必要はありません。その結果、スクロールすると OS がリスト項目に新しい画像を設定しますが、これは必要な画像ではありません。

解決策は、ListView をサポートする ArrayList にビットマップを格納することです。この場合、List<UpcomingMovieListModel> objectsリスト ビューのデータを保持するのは です。ここで行う必要がある変更がいくつかあるため、完全なコードは提供しませんが、プロセスについて説明します。

  1. UpcomingMovieListModelというフィールドを持つようにオブジェクトを拡張しますmovieIcon
  2. 現在のUpcomingMovieListModelオブジェクトを AsyncTask に渡し、AsyncTask をmovieIconダウンロードしたイメージに設定します。
  3. getViewメソッドで、ImageView がmovie.movieIconnull でない場合は値を設定します。
  4. movieIconを新しくダウンロードした画像に設定した後onPostExecuteAsyncTask呼び出しを行います。this.notifyDataSetChanged()これは、基になるデータを変更したことを ListView に通知し、更新して画面上の各項目に現在のムービーのアイコンを表示する必要があります。
  5. setImageBitmaponPostExecute で直接呼び出さないでください。データセットが変更されたことを通知すると、これは getView で処理されます。

これらを変更すると、基になるデータに対して正しく保存されるため、適切な画像がすべて表示されるはずです。

于 2013-06-13T15:03:07.203 に答える