リストビューにスラムをロードするために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;
}
}