在Android中添加ListView子项文本

发布于 2024-12-12 08:24:41 字数 4887 浏览 0 评论 0原文

我创建了一个 RSS 阅读器,可以在列表视图中列出项目。我还想在每个项目下面都有一个日期,但我不知道该怎么做。我需要某人的帮助才能使子项文本显示从 RSS 提要检索到的 pubDate。

这是我的类的代码:

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);
    }
}

这是我的 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>

这是现在在 Eclipse 中的样子:

ListView Currents

这是运行时的样子:

In Process

如何使子项文本显示从RSS 源?

I have created an RSS reader that lists items in a listview. I also want a date below each item, but I have no idea how to do that. I need someone's help to make the Sub Item text display the pubDate that was retrieved from the RSS feed.

This is the code I have for my class:

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);
    }
}

This is my 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>

This is what it looks like now in Eclipse:

ListView Currently

This is what it looks like running:

In Process

How to make the Sub Item text display the pubDate that was retrieved from the RSS feed?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

鱼窥荷 2024-12-19 08:24:41

最简单的解决方案可能是将您使用的 ArrayAdapterandroid.R.layout.simple_list_item_1 替换为 SimpleAdapter>android.R.layout.simple_list_item_2 预定义布局。该布局由两个 TextView 组成,id 为 android.R.id.text1(“item”)和 android.R.id。 text2(“子项”),您需要将其作为 SimpleAdapter 工作的参考。

通过 查看 SimpleAdapter 的构造函数,您会注意到,除了 Context 实例和布局资源的 id 之外,它还需要三个对您来说可能是新的参数:

  • List> 实例,您可以在其中放置希望 ListView 显示的元素。元素采用Map 的形式,即类似于由名称/值对形式的属性组成的结构。例如,您可以使用 "title""date" 分别作为每个 RSS 项目的标题和日期的键。
  • 一个字符串数组,用于放置要在 ListView 上显示的每个地图中的键名称。
  • 一个整数数组,您需要将部件的 id 放入列表项视图中,您希望在其中显示由前面的字符串数组中的键引用的单个元素。例如,如果您想分别在“item”和“sub item”视图中显示 RSS 项目的标题和日期,则可以使用 new String[] { "title", "date" } 作为字符串数组参数,new int[] { android.R.id.text1, android.R.id.text2 } 作为此参数。

一个粗略的代码示例,只是为了给您一个想法:

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);

文档指出“地图包含每行的数据,并且应该包括 from 参数中指定的所有条目”,因此标题和日期都应该始终存在。

请注意,这都是我的想法。我实际上并没有测试所有代码,因此您很可能会遇到一些需要调整或修复的怪癖或错误。

The simplest solution is probably to substitute the ArrayAdapter and the android.R.layout.simple_list_item_1 that you are using with a SimpleAdapter and the android.R.layout.simple_list_item_2 predefined layout. This layout is composed by two TextViews, with an id of android.R.id.text1 (the "item") and android.R.id.text2 (the "sub item") respectively, which you will need as a reference for the SimpleAdapter to work.

By looking at the constructor for SimpleAdapter you will notice that, apart from a Context instance and the id of a layout resource, it takes three parameters that may be new to you:

  • a List<? extends Map<String, ?>> instance where you put the elements you want the ListView to show. Elements are in the form of a Map, i.e. something akin to a struct composed by properties in form of name/value pairs. For example, you may use "title" and "date" as keys for the title and date of each RSS item, respectively.
  • an array of strings, where to put the names of the keys in each map that you want to show on the ListView.
  • an array of integers where you need to put the ids of the parts in the list item view where you want the single elements referenced by the keys in the preceding array of strings to be shown. For example, if you want to show the title and date of a RSS item in the "item" and "sub item" views respectively, you use new String[] { "title", "date" } as the array of strings argument, and new int[] { android.R.id.text1, android.R.id.text2 } as this argument.

A rough code example, just to give you the idea:

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);

The documentation states that "the maps contain the data for each row, and should include all the entries specified in the from parameter", so both title and date should always be present.

Please note that this is all off the top of my head. I haven't actually tested all the code, so you may very well encounter some quirk or bug that you need to adjust or fix on your way up.

真心难拥有 2024-12-19 08:24:41

您应该有一个像这样的 item_list.xml 文件:

    <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>

并且在您的列表适配器中的方法 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;

这应该可以做到!

You should have an item_list.xml file like this:

    <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>

and in your listadapter in the method 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;

this should do it!

怪我闹别瞎闹 2024-12-19 08:24:41

由于要将多个数据项映射到多个视图,因此不能使用 ArrayAdapter。您必须使用 SimpleAdapter 代替。

另外,我注意到您正在主 UI 线程上获取 RSS 提要。这将导致您的应用程序高度无响应。如果您不知道我在说什么,请看一下 Painless Threading 文章(我认为这是任何 Android 开发人员必读的文章)。您应该做的是使用 Loader。它们是专为您的情况而设计的。尽管它们直到 API-10 才引入,您仍然可以通过 在较低的 API 级别上使用它们支持包

Since you want to map multiple data items to multiple views, you can't use an ArrayAdapter. You'll have to use a SimpleAdapter instead.

Also, I noticed you're getting the RSS feed on the main UI thread. This is going to cause your application to be highly non-responsive. If you don't know what I'm talking about, take a gander at the Painless Threading article (I consider it a must read for any android developer). What you should do instead is use a Loader. They were designed for exactly you type of situation. Although they weren't introduced until API-10 you can still use them on lesser API levels via the Support Package.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文