Optimisation du BaseAdapter et Gestion du Chargement Infini sous Android

Encapsulation du BaseAdapter pour ListView

Dans le développement Android classique, l'implémentation répétitive des méthodes de l'interface BaseAdapter (getCount, getItem, getItemId, getView) alourdti le code des fragments. L'objectif est de créer une classe abstraite générique permettant de centraliser cette logique.

public abstract class AdaptateurDeBase<T> extends BaseAdapter {
    private ArrayList<T> listeDonnees;

    public AdaptateurDeBase(ArrayList<T> listeDonnees) {
        this.listeDonnees = listeDonnees;
    }

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

    @Override
    public T getItem(int position) {
        return listeDonnees.get(position);
    }

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

    @Override
    public abstract View getView(int position, View convertView, ViewGroup parent);
}

Le Patron de Conception BaseHolder

Pour optimiser la méthode getView, nous encapsulons le pattern ViewHolder dans une classe abstraite nommée BaseHolder. Cette classe gère l'initialisation de la vue, l'assignation des tags et la mise à jour des données.

public abstract class BaseHolder<T> {
    private View vueRacine;
    private T donnees;

    public BaseHolder() {
        vueRacine = initView();
        vueRacine.setTag(this);
    }

    public abstract View initView();
    public abstract void refreshView(T data);

    public void setData(T data) {
        this.donnees = data;
        refreshView(data);
    }

    public View getRootView() {
        return vueRacine;
    }
}

Gestion Multi-Types et Chargement Supplémentaire

Pour intégrer une fonction "Charger plus" en bas de liste, la ListView doit gérer deux types de layouts : le layout normal pour les données et un layout de progression pour le pied de page.

@Override
public int getViewTypeCount() {
    return 2; // Normal et Chargement
}

@Override
public int getItemViewType(int position) {
    if (position == getCount() - 1) {
        return TYPE_LOAD_MORE;
    }
    return getInnerType();
}

public int getInnerType() {
    return TYPE_NORMAL;
}

Dans la méthode getView, nous isntancions le MoreHolder si le type correspond au chargement. Ce dernier déclenche automatiquement une requête asynchrone dès qu'il devient visible.

Architecture de Protocole et Mise en Cache

Pour la partie réseau, l'utilisation de BaseProtocol permet d'abstraire les reequêtes HTTP et de gérer une persistance locale via des fichiers de cache. Le système vérifie la validité du cache (ex: 30 minutes) avant de solliciter le serveur.

private void setCache(String json, int index) {
    File dossierCache = UIUtils.getContext().getCacheDir();
    File fichierCache = new File(dossierCache, getKey() + "?index=" + index);

    try (BufferedWriter writer = new BufferedWriter(new FileWriter(fichierCache))) {
        long dateExpiration = System.currentTimeMillis() + 30 * 60 * 1000;
        writer.write(dateExpiration + "\n");
        writer.write(json);
        writer.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Analyse JSON et Validation des Données

Chaque protocole spécifique (ex: HomeProtocol) implémente sa propre logique d'analyse JSON via JSONObject et JSONArray. Une étape de validation est cruciale pour s'assurer que les données reçues ne sont pas vides avant de mettre à jour l'interface utilisateur.

public ArrayList<AppInfo> parseJson(String flux) {
    try {
        JSONObject racine = new JSONObject(flux);
        JSONArray listeApps = racine.getJSONArray("list");
        ArrayList<AppInfo> infos = new ArrayList<>();
        for (int i = 0; i < listeApps.length(); i++) {
            JSONObject objet = listeApps.getJSONObject(i);
            AppInfo info = new AppInfo();
            info.name = objet.getString("name");
            info.iconUrl = objet.getString("iconUrl");
            // ... mapping des autres champs
            infos.add(info);
        }
        return infos;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

Une fois les données validées par la méthode check(data), le HomeFragment notifie l'adaptateur pour rafraîchir la liste à l'écran.

Étiquettes: Android Java BaseAdapter ViewHolder JSON

Publié le 28 juin à 16h21