34 votes

Android: Ajouter ListView Sous Le Texte D'Un Élément

J'ai créé un lecteur de flux RSS qui contient une liste d'éléments dans une liste. Je veux aussi une date au-dessous de chaque article, mais je n'ai aucune idée de comment faire cela. J'ai besoin de l'aide de quelqu'un pour faire le Sous-Élément de l'affichage du texte le pubDate qui a été récupéré à partir du flux RSS.

C'est le code que j'ai pour ma classe:

public class RSSReader extends Activity implements OnItemClickListener
{

public final String RSSFEEDOFCHOICE = "http://app.calvaryccm.com/mobile/android/v1/devos";

public final String tag = "RSSReader";
private RSSFeed feed = null;

/** Called when the activity is first created. */

public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.main);

    // go get our feed!
    feed = getFeed(RSSFEEDOFCHOICE);

    // display UI
    UpdateDisplay();

}


private RSSFeed getFeed(String urlToRssFeed)
{
    try
    {
        // setup the url
       URL url = new URL(urlToRssFeed);

       // create the factory
       SAXParserFactory factory = SAXParserFactory.newInstance();
       // create a parser
       SAXParser parser = factory.newSAXParser();

       // create the reader (scanner)
       XMLReader xmlreader = parser.getXMLReader();
       // instantiate our handler
       RSSHandler theRssHandler = new RSSHandler();
       // assign our handler
       xmlreader.setContentHandler(theRssHandler);
       // get our data via the url class
       InputSource is = new InputSource(url.openStream());
       // perform the synchronous parse           
       xmlreader.parse(is);
       // get the results - should be a fully populated RSSFeed instance, or null on error
       return theRssHandler.getFeed();
    }
    catch (Exception ee)
    {
        // if we have a problem, simply return null
        System.out.println(ee.getMessage());
        System.out.println(ee.getStackTrace());
        System.out.println(ee.getCause());
        return null;
    }
}
public boolean onCreateOptionsMenu(Menu menu) 
{
    super.onCreateOptionsMenu(menu);
    menu.add(Menu.NONE, 0, 0, "Refresh");
    Log.i(tag,"onCreateOptionsMenu");
    return true;
}

public boolean onOptionsItemSelected(MenuItem item){
    switch (item.getItemId()) {
    case 0:

        Log.i(tag,"Set RSS Feed");
        return true;
    case 1:
        Log.i(tag,"Refreshing RSS Feed");
        return true;
    }
    return false;
}


private void UpdateDisplay()
{
    TextView feedtitle = (TextView) findViewById(R.id.feedtitle);
    TextView feedpubdate = (TextView) findViewById(R.id.feedpubdate);
    ListView itemlist = (ListView) findViewById(R.id.itemlist);


    if (feed == null)
    {
        feedtitle.setText("No RSS Feed Available");
        return;
    }

    if(feedtitle != null)
        feedtitle.setText(feed.getTitle());
    if(feedpubdate != null)
        feedpubdate.setText(feed.getPubDate());


    ArrayAdapter<RSSItem> adapter = new ArrayAdapter<RSSItem>(this,android.R.layout.simple_list_item_1,feed.getAllItems());

    itemlist.setAdapter(adapter);

    itemlist.setOnItemClickListener(this);

    itemlist.setSelection(0);

}

 @Override
 public void onItemClick(AdapterView parent, View v, int position, long id)
 {

     //Log.i(tag,"item clicked! [" + feed.getItem(position).getTitle() + "]");      

     Intent itemintent = new Intent(this,ShowDescription.class);

     Bundle b = new Bundle();
     b.putString("title", feed.getItem(position).getTitle());
     b.putString("description", feed.getItem(position).getDescription());
     b.putString("link", feed.getItem(position).getLink());
     b.putString("pubdate", feed.getItem(position).getPubDate());

     itemintent.putExtra("android.intent.extra.INTENT", b);

     startActivity(itemintent);

 }

}

C'est mon XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
 <TextView  
android:layout_width="fill_parent" 
android:layout_height="wrap_content" 
android:text="Android RSSReader"
android:id="@+id/feedtitle"/>
<TextView  
android:layout_width="fill_parent" 
android:layout_height="wrap_content" 
android:text=""
android:id="@+id/feedpubdate"/>
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/itemlist"

android:fastScrollEnabled="true"/>    
 </LinearLayout>

C'est à quoi il ressemble maintenant dans Eclipse:

ListView Currently

C'est à quoi il ressemble en cours d'exécution:

In Process

J'ai besoin de l'aide de quelqu'un pour faire le Sous-Élément de l'affichage du texte le pubDate qui a été récupéré à partir du flux RSS.

82voto

Giulio Piancastelli Points 4537

La solution la plus simple est probablement de remplacer l' ArrayAdapter et de la android.R.layout.simple_list_item_1 que vous utilisez avec un SimpleAdapter et de la android.R.layout.simple_list_item_2 modèle prédéfini. Cette structure est composée par deux TextViews, avec l'id android.R.id.text1 (le "point") et android.R.id.text2 (le "sous-élément") respectivement, ce qui vous aurez besoin d'une référence pour l' SimpleAdapter de travail.

En regardant le constructeur pour SimpleAdapter vous remarquerez que, outre un Context de l'instance et l'id d'une disposition de ressources, il prend trois paramètres qui peuvent être nouvelles pour vous:

  • un List<? extends Map<String, ?>> instance où vous mettez les éléments que vous voulez l' ListView de spectacle. Les éléments sont sous la forme d'un Map, c'est à dire quelque chose qui s'apparente à une structure composée par les propriétés de la forme de paires nom/valeur. Par exemple, vous pouvez utiliser "title" et "date" comme clés pour le titre et la date de chaque RSS élément, respectivement.
  • un tableau de chaînes, où mettre les noms des touches dans chaque carte que vous souhaitez afficher sur l' ListView.
  • un tableau d'entiers où vous avez besoin de mettre l'id de la pièces dans l'élément de la liste où vous voulez que le seul éléments référencés par les touches dans le précédent tableau de chaînes de caractères à afficher. Par exemple, si vous souhaitez afficher le titre et la date d'un flux RSS d'élément dans le "point" et "sous-rubrique" points de vue, respectivement, vous utilisez new String[] { "title", "date" } comme le tableau de chaînes de caractères de l'argument, et new int[] { android.R.id.text1, android.R.id.text2 } que cet argument.

Une rude exemple de code, juste pour vous donner l'idée:

List<Map<String, String>> data = new ArrayList<Map<String, String>>();
for (RSSItem item : feed.getAllItems()) {
    Map<String, String> datum = new HashMap<String, String>(2);
    datum.put("title", item.getTitle());
    datum.put("date", item.getDate().toString());
    data.add(datum);
}
SimpleAdapter adapter = new SimpleAdapter(this, data,
                                          android.R.layout.simple_list_item_2,
                                          new String[] {"title", "date"},
                                          new int[] {android.R.id.text1,
                                                     android.R.id.text2});
itemList.setAdapter(adapter);

La documentation indique que "les cartes contiennent les données pour chaque ligne, et doit inclure toutes les entrées spécifiées dans le paramètre", donc à la fois le titre et la date doit toujours être présent.

Veuillez noter que tout cela est sur le dessus de ma tête. Je n'ai pas réellement testé le code, si vous pouvez très bien rencontrer un caprice ou un bug que vous avez besoin de l'adapter ou de le fixer sur votre chemin.

5voto

iulia Points 1167

Vous devriez avoir une item_list.xml fichier comme ceci:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="6dp" >

    <TextView
        android:id="@+id/page_title"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textColor="#D8000000"
        android:textSize="16sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/page_date"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/page_title"
        android:ellipsize="marquee"
        android:lines="3"
        android:marqueeRepeatLimit="marquee_forever"
        android:textColor="#D8000000"
        android:textSize="12sp" />

</RelativeLayout>

et dans votre listadapter dans la méthode getview :

View row = convertView;
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
row = inflater.inflate(R.layout.item_list, parent, false);

TextView listTitle = (TextView) row.findViewById(R.id.page_title);
 listTitle.setText(title);

TextView date = (TextView) row.findViewById(R.id.page_date); 
date.setText( <here put your date from RSS feed>);

return row;

cela devrait le faire!

1voto

Kurtis Nusbaum Points 16073

Puisque vous voulez mapper plusieurs éléments de données à de multiples points de vue, vous ne pouvez pas utiliser un ArrayAdapter. Vous aurez à utiliser un SimpleAdapter à la place.

Aussi, j'ai remarqué que vous obtenez le flux RSS sur le main thread d'INTERFACE utilisateur. Cela va provoquer votre demande à être fortement non-réactif. Si vous ne savez pas de quoi je parle, jetez un coup d'œil à l' Indolore Filetage de l'article (je considère que c'est une lecture incontournable pour tout développeur android). Ce que vous devez faire est d'utiliser un Chargeur. Ils ont été conçus pour vous exactement le type de situation. Bien qu'ils n'étaient pas introduit jusqu'à ce que API-10, vous pouvez toujours les utiliser à moindre API niveaux via le Support Package.

0voto

Rakon_188 Points 119

0voto

josephus Points 4865

vous devrez peut-être envisager de mettre en œuvre une coutume adaptateur pour remplir votre liste.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X