在Android中添加ListView子项文本
我创建了一个 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 中的样子:
这是运行时的样子:
如何使子项文本显示从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:
This is what it looks like running:
How to make the Sub Item text display the pubDate that was retrieved from the RSS feed?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
最简单的解决方案可能是将您使用的
ArrayAdapter
和android.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
上显示的每个地图中的键名称。new int[] { android.R.id.text1, android.R.id.text2 }
作为此参数。一个粗略的代码示例,只是为了给您一个想法:
文档指出“地图包含每行的数据,并且应该包括 from 参数中指定的所有条目”,因此标题和日期都应该始终存在。
请注意,这都是我的想法。我实际上并没有测试所有代码,因此您很可能会遇到一些需要调整或修复的怪癖或错误。
The simplest solution is probably to substitute the
ArrayAdapter
and theandroid.R.layout.simple_list_item_1
that you are using with aSimpleAdapter
and theandroid.R.layout.simple_list_item_2
predefined layout. This layout is composed by twoTextView
s, with an id ofandroid.R.id.text1
(the "item") andandroid.R.id.text2
(the "sub item") respectively, which you will need as a reference for theSimpleAdapter
to work.By looking at the constructor for
SimpleAdapter
you will notice that, apart from aContext
instance and the id of a layout resource, it takes three parameters that may be new to you:List<? extends Map<String, ?>>
instance where you put the elements you want theListView
to show. Elements are in the form of aMap
, 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.ListView
.new String[] { "title", "date" }
as the array of strings argument, andnew int[] { android.R.id.text1, android.R.id.text2 }
as this argument.A rough code example, just to give you the idea:
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.
您应该有一个像这样的 item_list.xml 文件:
并且在您的列表适配器中的方法 getview 中:
这应该可以做到!
You should have an item_list.xml file like this:
and in your listadapter in the method getview :
this should do it!
由于要将多个数据项映射到多个视图,因此不能使用 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.
创建自定义 listView http://saigeethamn.blogspot.com/2010 /04/custom-listview-android-developer.html
create a custom listView http://saigeethamn.blogspot.com/2010/04/custom-listview-android-developer.html