1

リストビューにスラムをロードするためにUILを使用しています。

セルレイアウトのイメージビューとスピナーは次のとおりです。

        <ImageView
            android:id="@+id/imgAlbum"
            android:layout_width="48dip"
            android:layout_height="48dip"
            android:layout_gravity="center|left"
            android:scaleType="centerCrop"
            android:visibility="gone" />

        <ProgressBar
            android:id="@+id/loading"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:visibility="gone" />

リスト :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/list_restaurant"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="4dp" >
    </ListView>

</LinearLayout>

私はそのようにローダーを設定します:

public void setImageLoader(ImageLoader imageLoader, Context context) {

        File cacheDir = StorageUtils.getCacheDirectory(context);
        ImageLoaderConfiguration _config;
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
            _config = new ImageLoaderConfiguration.Builder(context).memoryCacheExtraOptions(0, 0).discCacheExtraOptions(480, 800, CompressFormat.JPEG, 75).taskExecutor(null)
                    .taskExecutorForCachedImages(null).threadPoolSize(3) // default
                    .threadPriority(Thread.NORM_PRIORITY - 1) // default
                    .tasksProcessingOrder(QueueProcessingType.FIFO) // default
                    .denyCacheImageMultipleSizesInMemory().memoryCache(new UsingFreqLimitedMemoryCache(2 * 1024 * 1024)) // default
                    .memoryCacheSize(2 * 1024 * 1024).discCache(new UnlimitedDiscCache(cacheDir)) // default
                    .discCacheSize(50 * 1024 * 1024).discCacheFileCount(100).discCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default
                    .imageDownloader(new BaseImageDownloader(context)) // default
                    .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default
                    .enableLogging().build();
        }
        else {
            _config = new ImageLoaderConfiguration.Builder(context).memoryCacheExtraOptions(0, 0)
                    // default/screendimensions
                    .discCacheExtraOptions(480, 800, CompressFormat.JPEG, 75).taskExecutor(AsyncTask.THREAD_POOL_EXECUTOR).taskExecutorForCachedImages(AsyncTask.THREAD_POOL_EXECUTOR)
                    .threadPoolSize(3) // default
                    .threadPriority(Thread.NORM_PRIORITY - 1) // default
                    .tasksProcessingOrder(QueueProcessingType.FIFO) // default
                    .denyCacheImageMultipleSizesInMemory().memoryCache(new UsingFreqLimitedMemoryCache(2 * 1024 * 1024)) // default
                    .memoryCacheSize(2 * 1024 * 1024).discCache(new UnlimitedDiscCache(cacheDir)) // default
                    .discCacheSize(50 * 1024 * 1024).discCacheFileCount(100).discCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default
                    .imageDownloader(new BaseImageDownloader(context)) // default
                    .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default
                    .enableLogging().build();
        }
        if (!imageLoader.isInited()) {
            imageLoader.init(_config);
        }
    }

そしてbaseadapterでは、次のように使用します:

private ImageLoader             _imageLoader;
private DisplayImageOptions     _options;

コンストラクター

this._imageLoader = ImageLoader.getInstance();
this._options = new DisplayImageOptions.Builder().showImageForEmptyUri(R.drawable.error).showImageOnFail(R.drawable.error).cacheInMemory().cacheOnDisc().bitmapConfig(Bitmap.Config.RGB_565)
        .build();
Utils utils = new Utils();
utils.setImageLoader(_imageLoader, _activity);

GetView()で:

    final ProgressBar spinner = (ProgressBar) convertView.findViewById(R.id.loading);
                _imageLoader.displayImage(etablissement.getImgThumb(), cellHolder.imageIcon, _options, new SimpleImageLoadingListener() {
                    @Override
                    public void onLoadingStarted(String imageUri, View view) {

                        view.setVisibility(View.GONE);
                        spinner.setVisibility(View.VISIBLE);
                        spinner.invalidate();
                        view.invalidate();
                    }

                    @Override
                    public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                        String message = null;
                        switch (failReason.getType()) {
                            case IO_ERROR:
                                message = "Input/Output error";
                                break;
                            case DECODING_ERROR:
                                message = "Image can't be decoded";
                                break;
                            case NETWORK_DENIED:
                                message = "Downloads are denied";
                                break;
                            case OUT_OF_MEMORY:
                                message = "Out Of Memory error";
                                break;
                            case UNKNOWN:
                                message = "Unknown error";
                                break;
                        }
                        view.setVisibility(View.VISIBLE);
                        spinner.setVisibility(View.GONE);spinner.invalidate();
                        view.invalidate();
                    }

                    @Override
                    public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {

                        view.setVisibility(View.VISIBLE);
                        spinner.setVisibility(View.GONE);
                        spinner.invalidate();
                        view.invalidate();
                    }
                });

すべて正常に動作しますが、リストをスクロールしてセルを再描画するまで、画像ビューの代わりにスピナーが残ります。

ここで、リストの読み込みはそのままです:http://imagik.fr/view-rl/45673

ここで、イメージビューの更新を下にスクロールすると: http://imagik.fr/view-rl/45674

ここで、イメージビューの更新を再スクロールすると: http://imagik.fr/view-rl/45675

何か案が ??

編集:

完全なアダプター コード (UIL 部分を含む) :

public class AdapterDirectories extends BaseAdapter {
    /**
     * PRIVATE ATTRIBUTES
     */
    // LOG
    private static final String     TAG             = AdapterDirectories.class.getSimpleName();
    // IHM
    private static LayoutInflater   _inflater       = null;
    private Activity                _activity;
    // DATA
    private DataManager             _dataManager;
    private ImageLoader             _imageLoader;
    private DisplayImageOptions     _options;
    private int                     _section;
    private float                   _latitude;
    private float                   _longitude;
    private List<Contact>           _listContacts   = new ArrayList<Contact>();
    private List<Favoris>           _listFavoris    = new ArrayList<Favoris>();

    public AdapterDirectories(Activity activity, boolean favoris, float latitude, float longitude, int section) {

        this._activity = activity;
        this._latitude = latitude;
        this._longitude = longitude;
        this._section = section;
        //
        ContactRepository contactRep = null;
        //
        if (favoris == false) {
            _listContacts = EtablissementApplication._dataManager.get_listOfContacts(_section, _activity);
        }
        else {
            // FAVORITE
            this._listFavoris = EtablissementApplication._dataManager.get_listOfFavoris();
            // DATA
            contactRep = new ContactRepository(_activity);
            contactRep.Open();
            for (Favoris unFavoris : _listFavoris) {
                _listContacts.add(contactRep.GetById(unFavoris.getIdentifiantContact()));
            }
            contactRep.Close();
        }
        _inflater = (LayoutInflater) _activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        this._imageLoader = ImageLoader.getInstance();
        this._options = new DisplayImageOptions.Builder().showImageForEmptyUri(R.drawable.error).showImageOnFail(R.drawable.error).cacheInMemory().cacheOnDisc()
                .displayer(new RoundedBitmapDisplayer(Utils.IMAGE_BORDER_RADIUS)).bitmapConfig(Bitmap.Config.RGB_565).build();
        Utils utils = new Utils();
        utils.setImageLoader(_imageLoader, _activity);
    }

    @Override
    public int getCount() {

        return _listContacts.size();
    }

    @Override
    public Object getItem(int position) {

        return position;
    }

    @Override
    public long getItemId(int position) {

        return position;
    }

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

        View view = convertView;
        CellHolder cellHolder = null;
        Contact _contact = _listContacts.get(position);
        Etablissement etablissement = new Etablissement();
        //
        // GET
        if (convertView == null) {
            view = _inflater.inflate(R.layout.directory_list_item, null);
            cellHolder = new CellHolder();
            cellHolder.textTitle = (TextView) view.findViewById(R.id.annuaire_titre_etablissement);
            cellHolder.textCategory = (TextView) view.findViewById(R.id.annuaire_categorie_etablissement);
            cellHolder.textDistance = (TextView) view.findViewById(R.id.annuaire_distance_etablissement);
            cellHolder.imageIcon = (ImageView) view.findViewById(R.id.img_icon);
            cellHolder.textPromo = (TextView) view.findViewById(R.id.promo);
            cellHolder.textTarif = (TextView) view.findViewById(R.id.annuaire_tarif_etablissement);
            view.setTag(cellHolder);
        }
        else {
            cellHolder = (CellHolder) convertView.getTag();
        }
        //
        // SET
        cellHolder.textTitle.setText(_contact.getName().toUpperCase());
        try {
            //
            EtablissementRepository etablissementRep = new EtablissementRepository(_activity);
            etablissementRep.Open();
            int idEta = etablissementRep.GetByIdContact(_contact.getIdentifiant());
            etablissement = etablissementRep.GetById(idEta);
            etablissementRep.Close();
            // CATEGORIES
            if (_section == 0) {
                if (etablissement.getSection() != null && !etablissement.getSection().getLibelle().equals("")) {
                    cellHolder.textCategory.setText(etablissement.getSection().getLibelle());
                }
                else {
                    cellHolder.textCategory.setVisibility(View.GONE);
                }
            }
            else {
                String categories = "";
                for (Categorie cat : etablissement.getCategories()) {
                    categories = categories + cat.getLibelle() + "|";
                }
                if (!categories.equals("")) {
                    cellHolder.textCategory.setText(categories);
                }
                else {
                    cellHolder.textCategory.setText(_activity.getString(R.string.txt_no_categories));
                }
            }
            //
            // TARIF
            String trancheTarif = "";
            if (etablissement.getTarif() != null) {
                trancheTarif = etablissement.getTarif().getMinPrice() + "\u20ac à " + etablissement.getTarif().getMaxPrice() + "\u20ac";
            }
            if (!trancheTarif.equals("") && etablissement.getTarif().getMinPrice() > 0 && etablissement.getTarif().getMaxPrice() > 0) {
                cellHolder.textTarif.setText(trancheTarif);
            }
            else {
                cellHolder.textTarif.setText("- \u20ac à - \u20ac");
            }
            // PROMO
            boolean etatPromotion = false;
            for (Promotion promo : etablissement.getPromotions()) {
                if (promo.isPromoOnGoing()) {
                    etatPromotion = true;
                }
            }
            if (!etatPromotion) { // PROMO OFF
                cellHolder.textPromo.setVisibility(View.VISIBLE);
            }
            else { // PROMO ON
                cellHolder.textPromo.setVisibility(View.VISIBLE);
            }
            // LOGO
            final ProgressBar spinner = (ProgressBar) convertView.findViewById(R.id.loading);
            _imageLoader.displayImage(etablissement.getImgThumb(), cellHolder.imageIcon, _options, new SimpleImageLoadingListener() {
                @Override
                public void onLoadingStarted(String imageUri, View view) {

                }

                @Override
                public void onLoadingFailed(String imageUri, View view, FailReason failReason) {

                    String message = null;
                    switch (failReason.getType()) {
                        case IO_ERROR:
                            message = "Input/Output error";
                            break;
                        case DECODING_ERROR:
                            message = "Image can't be decoded";
                            break;
                        case NETWORK_DENIED:
                            message = "Downloads are denied";
                            break;
                        case OUT_OF_MEMORY:
                            message = "Out Of Memory error";
                            break;
                        case UNKNOWN:
                            message = "Unknown error";
                            break;
                    }
                }

                @Override
                public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {

                }
            });
        }
        catch (Exception e) {
        }
        // DISTANCE
        int distanceFormatee = 0;
        if (_latitude == 0 || _longitude == 0) {
            cellHolder.textDistance.setText("");
        }
        else {
            int distance = (int) distanceBetween(_latitude, _longitude, _contact.getLatitude(), _contact.getLongitude());
            distanceFormatee = distance / 1000;
            if (distance < 1000) {
                cellHolder.textDistance.setText("< 1 km");
            }
            else {
                cellHolder.textDistance.setText(distanceFormatee + " km");
            }
        }
        //
        // SAVE DISTANCE
        EtablissementApplication._dataManager.get_listOfContacts(_section, _activity).get(position).setDistance(distanceFormatee);
        //
        // DATA SAVE
        List<Integer> _mapData = new ArrayList<Integer>();
        _mapData.add(_contact.getIdentifiant());
        _mapData.add(etablissement.getIdentifiant());
        DataManager._contactForEtaHashMap.put(_contact.getName(), etablissement);
        DataManager._mapContact.put(position, _mapData);
        return view;
    }

    public class CellHolder {
        public TextView     textTitle;
        public TextView     textAdress;
        public TextView     textCategory;
        public TextView     textTarif;
        public TextView     textPromo;
        public ImageView    imageIcon;
        public TextView     textDistance;
    }

    public void clearData() {

        _listContacts.clear();
        _listFavoris.clear();
    }

    private double distanceBetween(float lat_a, float lng_a, float lat_b, float lng_b) {

        float pk = (float) (180 / 3.14169);
        float a1 = lat_a / pk;
        float a2 = lng_a / pk;
        float b1 = lat_b / pk;
        float b2 = lng_b / pk;
        float t1 = FloatMath.cos(a1) * FloatMath.cos(a2) * FloatMath.cos(b1) * FloatMath.cos(b2);
        float t2 = FloatMath.cos(a1) * FloatMath.sin(a2) * FloatMath.cos(b1) * FloatMath.sin(b2);
        float t3 = FloatMath.sin(a1) * FloatMath.sin(b1);
        double tt = Math.acos(t1 + t2 + t3);
        return 6366000 * tt;
    }
}
4

3 に答える 3

4

これにより、期待される動作を実現できます。

リスト アイテムのレイアウト:

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <ProgressBar
        android:id="@+id/loading"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center" />

    <ImageView
        android:id="@+id/imgAlbum"
        android:layout_width="48dip"
        android:layout_height="48dip"
        android:layout_gravity="center|left"
        android:scaleType="centerCrop" />
</RelativeLayout

この順序でを持っている場合ProgressBarImageViewImageView は ProgressBar をオーバーレイし、Image Loader が画像をそれに設定すると、表示されProgressBarなくなります。

次に、getView()メソッドで、標準的な方法で画像をロードするだけです。非表示/表示に煩わされる必要はありませんProgressBar

于 2013-09-13T11:34:53.660 に答える
0

このコードを試して、Async タスクを使用すると、次のことができます。

http://thinkandroid.wordpress.com/2012/06/13/lazy-loading-images-from-urls-to-listviews/

于 2013-09-13T13:06:34.210 に答える
0

ダウンロードが完了したら、スピナーに画像リソースを提供している「ソース」を手動で更新する関数を配置する必要があります。このようにして、スピナーにリソースを提供するソースが常に更新されます。

于 2013-09-13T06:36:44.240 に答える