IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Composants graphiques Android Discussion :

[ListView] ListView personnalisée avec tri alphabétique


Sujet :

Composants graphiques Android

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Inscrit en
    Juillet 2010
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 8
    Par défaut [ListView] ListView personnalisée avec tri alphabétique
    Bonjour à tous,

    Je rencontre quelques difficultés pour mettre en place une listeView dans laquelle les éléments sont rangés par ordre alphabétique. Ce que je veux faire, dans ce cas, c'est lire un fichier xml contenant des informations sur des musiques, puis les classé par ordre alphabétique en affichant le nom et le genre. Le tout séparé en section (comme pour les contacts).

    Pour cela, j'ai donc deux layouts, et deux Adapter personnalisés. Un pour gérer les sections, un autre pour l'affichage de la liste avec les informations personnalisé. En faisant des tests, j'ai essayé d'afficher une liste simple avec des sections, cela fonctionne. J'ai également essayé d'afficher ma liste avec les infos que je veux, ça marche aussi. Par contre, lorsque je combine, les deux, j'ai une erreur d'exécution lorsque j'essaye de scroller dans la liste. Pourtant, elle s'affiche correctement au lancement de l'application (et avec l'aspect voulu).

    Voici le code que j'utilise. D'abord l'Adapter qui permet de gérer les sections :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
     
    abstract public class MusicAdapter extends BaseAdapter{
     
    abstract protected View getHeaderView(String caption, int index,
            View convertView, ViewGroup parent);
    private List<Section> sections = new ArrayList<Section>();
     
    private static int TYPE_SECTION_HEADER = 0;
     
    public MusicAdapter() {
        super();
    }
     
    public void addSection(String caption, ItemAdapter adapter){
        sections.add(new Section(caption, adapter));
    }
     
    public Object getItem(int position){
        for (Section section : this.sections){
            if (position == 0){
                return section;
            }
     
            int size = section.adapter.getCount() + 1;
            if (position < size){
                return section.adapter.getItem(position - 1);
            }
            position -= size;
        }
        return null;
    }
     
    public int getCount(){
        int total = 0;
     
        for (Section section : this.sections){
            total += section.adapter.getCount() + 1;
        }
        return total;
    }
     
    public int getItemViewType(int position){
        int typeOffset = TYPE_SECTION_HEADER + 1;
     
        for (Section section : this.sections) {
            if (position == 0) {
                return (TYPE_SECTION_HEADER);
            }
     
            int size = section.adapter.getCount() + 1;
     
            if (position < size) {
                return (typeOffset + section.adapter
                        .getItemViewType(position - 1));
            }
     
            position -= size;
            typeOffset += section.adapter.getViewTypeCount();
        }
     
        return -1;
    }
     
    public boolean areAllItemsSelectable(){
        return false;
    }
     
    public boolean isEnabled(int position) {
        return (getItemViewType(position) != TYPE_SECTION_HEADER);
    }
     
    @Override
    public View getView(int position, View convertView, ViewGroup parent){
        int sectionIndex = 0;
     
        for (Section section : this.sections){
            if (position == 0){
                return (getHeaderView(section.caption, sectionIndex, convertView, parent));
            }
            int size = section.adapter.getCount() + 1;
     
            if (position < size){
                return (section.adapter.getView(position - 1, convertView,
                        parent));
            }
            position -= size;
            sectionIndex++;
        }
        return null;
    }
     
    @Override
    public long getItemId(int position){
        return position;        
    }
     
    class Section {
        String caption;
        ItemAdapter adapter;
     
        Section(String caption, ItemAdapter adapter) {
            this.caption = caption;
            this.adapter = adapter;
        }
    }
    }
    L'Adapter pour l'affichage d'une listView personnalisée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
     
    public class ItemAdapter extends BaseAdapter{
     
    private ListeMusicContainer<Music> mList;
    private LayoutInflater mInflater;
     
    public ItemAdapter(Context context, ListeMusicContainer<Music> musics){
        mInflater = LayoutInflater.from(context);
        mList = musics;
    }
     
    @Override
    public int getCount() {
        return mList.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) {
        ViewHolder holder;
     
        if (convertView == null){
            convertView = mInflater.inflate(R.layout.list_item, null);
     
            holder = new ViewHolder();
            holder.nom = (TextView) convertView.findViewById(R.id.nomAlbum);
            holder.genre = (TextView) convertView.findViewById(R.id.genreAlbum);
     
            convertView.setTag(holder);
        }
        else{
            holder = (ViewHolder) convertView.getTag();
        }
        holder.nom.setText(mList.getItem(position).getNom());
        holder.genre.setText(mList.getItem(position).getGenre());
     
        return convertView;
    }
     
    static class ViewHolder{
        TextView nom;
        TextView genre;
    }
     
    }
    Et enfin, l'activité qui est censé faire l'affichage :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
    public class TestView extends ListActivity {
    /** Called when the activity is first created. */
     
    private ListView mListView;
    private static String[] items;
    private XmlDataParser mParser;
    private ListeMusicContainer<Music> mList;
     
     
    private MusicAdapter mAdapter = new MusicAdapter() {
        protected View getHeaderView(String caption, int index,
                View convertView, ViewGroup parent) {
            TextView result = (TextView) convertView;
     
            if (convertView == null) {
                result = (TextView) getLayoutInflater().inflate(
                        R.layout.header, null);
            }
     
            result.setText(caption);
     
            return (result);
        }
    };
     
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
     
        mParser = new XmlDataParser();
        mList = mParser.parseXml(this);
     
        ListeMusicContainer<Music> groupe = new ListeMusicContainer<Music>();
        String currLetter = null;
     
        for (int i = 0; i < mList.size(); i++){
            if (!mList.getItem(i).getLabel().equalsIgnoreCase(currLetter) && currLetter != null){
                mAdapter.addSection(mList.getItem(i).getLabel().toUpperCase(), new ItemAdapter(this, groupe));
                groupe = new ListeMusicContainer<Music>();
                currLetter = mList.getItem(i).getLabel();
            }
            if (currLetter == null){
                currLetter = mList.getItem(i).getLabel();
            }
     
            groupe.addData(mList.getItem(i));
        }
     
        setListAdapter(mAdapter);
     
    }
    }
    J'obtiens les log suivants avec logcat au moment du plantage :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
     
    I/ActivityManager(   42): Displayed activity com.view/.TestView: 1480 ms (total
    1480 ms)
    D/dalvikvm(  975): GC_EXTERNAL_ALLOC freed 1214 objects / 78504 bytes in 96ms
    D/AndroidRuntime(  975): Shutting down VM
    W/dalvikvm(  975): threadid=1: thread exiting with uncaught exception (group=0x4
    001d800)
    E/AndroidRuntime(  975): FATAL EXCEPTION: main
    E/AndroidRuntime(  975): java.lang.NullPointerException
    E/AndroidRuntime(  975):        at com.view.ItemAdapter.getView(ItemAdapter.java
    :51)
    E/AndroidRuntime(  975):        at com.view.MusicAdapter.getView(Music
    Adapter.java:91)
    E/AndroidRuntime(  975):        at android.widget.AbsListView.obtainView(AbsList
    View.java:1294)
    E/AndroidRuntime(  975):        at android.widget.ListView.makeAndAddView(ListVi
    ew.java:1727)
    E/AndroidRuntime(  975):        at android.widget.ListView.fillDown(ListView.jav
    a:652)
    E/AndroidRuntime(  975):        at android.widget.ListView.fillGap(ListView.java
    :623)
    E/AndroidRuntime(  975):        at android.widget.AbsListView.trackMotionScroll(
    AbsListView.java:2944)
    E/AndroidRuntime(  975):        at android.widget.AbsListView.onTouchEvent(AbsLi
    stView.java:2065)
    E/AndroidRuntime(  975):        at android.widget.ListView.onTouchEvent(ListView
    .java:3315)
    E/AndroidRuntime(  975):        at android.view.View.dispatchTouchEvent(View.jav
    a:3766)
    E/AndroidRuntime(  975):        at android.view.ViewGroup.dispatchTouchEvent(Vie
    wGroup.java:897)
    E/AndroidRuntime(  975):        at android.view.ViewGroup.dispatchTouchEvent(Vie
    wGroup.java:936)
    E/AndroidRuntime(  975):        at android.view.ViewGroup.dispatchTouchEvent(Vie
    wGroup.java:936)
    E/AndroidRuntime(  975):        at android.view.ViewGroup.dispatchTouchEvent(Vie
    wGroup.java:936)
    E/AndroidRuntime(  975):        at com.android.internal.policy.impl.PhoneWindow$
    DecorView.superDispatchTouchEvent(PhoneWindow.java:1671)
    E/AndroidRuntime(  975):        at com.android.internal.policy.impl.PhoneWindow.
    superDispatchTouchEvent(PhoneWindow.java:1107)
    E/AndroidRuntime(  975):        at android.app.Activity.dispatchTouchEvent(Activ
    ity.java:2086)
    E/AndroidRuntime(  975):        at com.android.internal.policy.impl.PhoneWindow$
    DecorView.dispatchTouchEvent(PhoneWindow.java:1655)
    E/AndroidRuntime(  975):        at android.view.ViewRoot.handleMessage(ViewRoot.
    java:1785)
    E/AndroidRuntime(  975):        at android.os.Handler.dispatchMessage(Handler.ja
    va:99)
    E/AndroidRuntime(  975):        at android.os.Looper.loop(Looper.java:123)
    E/AndroidRuntime(  975):        at android.app.ActivityThread.main(ActivityThrea
    d.java:4627)
    E/AndroidRuntime(  975):        at java.lang.reflect.Method.invokeNative(Native
    Method)
    E/AndroidRuntime(  975):        at java.lang.reflect.Method.invoke(Method.java:5
    21)
    E/AndroidRuntime(  975):        at com.android.internal.os.ZygoteInit$MethodAndA
    rgsCaller.run(ZygoteInit.java:868)
    E/AndroidRuntime(  975):        at com.android.internal.os.ZygoteInit.main(Zygot
    eInit.java:626)
    E/AndroidRuntime(  975):        at dalvik.system.NativeStart.main(Native Method)
     
    W/ActivityManager(   42):   Force finishing activity com.view/.TestView
    Les données sont récupérées d'un fichier xml, et le sont vraisemblablement correctement puisque j'arrive à les afficher sans erreurs en faisant une liste simple. J'ai également essayé en mettant des données en dur pour remplir la liste, ça fonctionne un peu plus longtemps avant de planter avec le même message d'erreur.

    Je sais vraiment pas d'où peut venir le problème donc si l'un de vous à une idée, ce serait vraiment super.

    Merci d'avance

  2. #2
    Expert confirmé

    Avatar de Feanorin
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    4 589
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 4 589
    Par défaut
    Bonjour ,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    E/AndroidRuntime(  975): FATAL EXCEPTION: main
    E/AndroidRuntime(  975): java.lang.NullPointerException
    E/AndroidRuntime(  975):        at com.view.ItemAdapter.getView(ItemAdapter.java
    :51)
    Tu as un pointeur null qui apparait dans la procédure getView de ItemAdapter à la ligne 51.

    Soit c'est ta variable holder qui est nulle lorsque tu le récupère via
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     holder = (ViewHolder) convertView.getTag();
    sinon ça peut provenir lorsque tu essayes de récupérer le nom et le titre de ton item
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    holder.nom.setText(mList.getItem(position).getNom());
    holder.genre.setText(mList.getItem(position).getGenre());
    Essaye de mettre un try / catch ou débugger directement pour voir d'ou vient le problème .

  3. #3
    Membre habitué
    Inscrit en
    Juillet 2010
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 8
    Par défaut
    Salut,

    je n'ai pas réussi à trouver d'où venait le problème avec cette solution. J'ai changé d'implémentation. j'utilise toujours la classe MusicAdapter pour créer la liste avec les sections, et pour remplir les différentes sections, j'utilise un SimpleAdapter.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    new SimpleAdapter(this.getBaseContext(), itemList, R.layout.list_item, 
        new String[] {ITEM_COVER, ITEM_NOM, ITEM_GENRE}, 
        new int[] {R.id.logo, R.id.nomMusique, R.id.genre});
    itemList étant un ArrayList<HashMap<String, String>> contenant les informations à afficher.

    Merci quand même pour l'aide

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. listview ou datagrid avec un adorecord
    Par angelange dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 16/05/2008, 10h50
  2. Tri Alphabétique Listbox avec Boutons Radios
    Par ljuboja78 dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 01/05/2008, 09h55
  3. [WPF] Listview, vue personnalisée
    Par Jérem22 dans le forum C#
    Réponses: 6
    Dernier message: 06/11/2007, 11h57
  4. Réponses: 1
    Dernier message: 17/10/2007, 14h32
  5. Réponses: 1
    Dernier message: 04/05/2005, 11h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo