我是Android开发的新手,我一直在努力解析多个标签并将其显示在ListView
中。
我使用的是SAX解析器,这是我的RssParseHandler
代码。
public class RssParseHandler extends DefaultHandler {
private List<RssItem> rssItems;
private RssItem currentMessage;
//private StringBuilder builder;
private boolean parseLink;
private boolean parseTitle;
private boolean parseDate;
private boolean parseDes;
public RssParseHandler() {
rssItems = new ArrayList();
}
public List<RssItem> getItems() {
return this.rssItems;
}
@Override
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
super.startElement(uri, localName, name, attributes);
if (localName.equalsIgnoreCase("item")) {
this.currentMessage = new RssItem();
} else if (localName.equalsIgnoreCase("title")) {
//currentMessage.setTitle(builder.toString());
parseTitle = true;
} else if (localName.equalsIgnoreCase("link")) {
//currentMessage.setLink(builder.toString());
parseLink = true;
} else if (localName.equalsIgnoreCase("description")) {
//currentMessage.setDescription(builder.toString());
parseDes = true;
} else if (localName.equalsIgnoreCase("pubDate")) {
//currentMessage.setDate(builder.toString());
parseDate = true;
}
//parsing enclosure tag
else if ("enclosure".equals(localName)) {
// Get tags attributes number
int attrsLength = attributes.getLength();
for (int i = 0; i < attrsLength; i++) {
String attrName = attributes.getQName(i); // attribute name
if ("url".equals(attrName)) // This tag has only one attribute but it is better to check it name is correct
currentMessage.getLink();
}
}
}
@Override
public void endElement(String uri, String localName, String name)
throws SAXException {
super.endElement(uri, localName, name);
if (this.currentMessage != null) {
if (localName.equalsIgnoreCase("item")) {
rssItems.add(currentMessage);
//currentMessage = null;
} else if (localName.equalsIgnoreCase("link")) {
//currentMessage.setLink(builder.toString());
//parseLink = false;
} else if (localName.equalsIgnoreCase("description")) {
//currentMessage.setDescription(builder.toString());
//parseDes = false;
} else if (localName.equalsIgnoreCase("pubDate")){
//currentMessage.setDate(builder.toString());
parseDate = false;
} else if (localName.equalsIgnoreCase("title")) {
//currentMessage.setTitle(builder.toString());
parseTitle = false;
}
//builder.setLength(0);
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
super.characters(ch, start, length);
//builder.append(ch, start, length);
if (parseTitle) {
if (currentMessage != null)
currentMessage.setTitle(new String(ch, start, length));
} else if (parseLink) {
if (currentMessage != null) {
currentMessage.setLink(new String(ch, start, length));
//parseLink = false;
}
} else if (parseDes) {
if (currentMessage != null)
currentMessage.setDescription(new String(ch, start, length));
//parseLink = false;
} else if (parseDate) {
if (currentMessage != null) {
currentMessage.setDate(new String(ch, start, length));
//currentMessage.setDate(new String(ch, start, length));
//parseDesc = false;
}
}
}
}
以下是Listview的代码:
public class ReaderAppActivity extends Fragment {
private ReaderAppActivity local;
private ListView mList;
/**
* This method creates main application view
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//super.onCreate(savedInstanceState);
// Set view
//setContentView(R.layout.fragment_rss);
local = this;
//int position = getArguments().getInt("position");
// String url = getArguments().getString("url");
// List of rivers
String[] menus = getResources().getStringArray(R.array.menus);
// Creating view corresponding to the fragment
View v = inflater.inflate(R.layout.fragment_rss, container, false);
// Set reference to this activity
//local = this;
GetRSSDataTask task = new GetRSSDataTask();
// Start download RSS task
task.execute("http://thechurchofwhatshappeningnow.libsyn.com/rss");
//task.execute(url);
// Debug the thread name
Log.d("ITCRssReader", Thread.currentThread().getName());
//mList = (ListView) findViewById(R.id.rssListMainView);
return v;
}
private class GetRSSDataTask extends AsyncTask<String, Void, List<RssItem> > {
@Override
protected List<RssItem> doInBackground(String... urls) {
// Debug the task thread name
Log.d("ITCRssReader", Thread.currentThread().getName());
try {
// Create RSS reader
RssReader rssReader = new RssReader(urls[0]);
// Parse RSS, get items
return rssReader.getItems();
} catch (Exception e) {
Log.e("ITCRssReader", e.getMessage());
}
return null;
}
@Override
protected void onPostExecute(List<RssItem> result) {
// Get a ListView from main view
ListView mList = (ListView) getView().findViewById(R.id.rssListMainView);
// Create a list adapter
ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem>(getActivity(),R.layout.rss_text, result);
//ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem>(getActivity(),R.layout.fragment_rss, result);
// Set list adapter for the ListView
mList.setAdapter(adapter);
// Set list view item click listener
mList.setOnItemClickListener(new ListListener(result, getActivity()));
}
}
}
我做错了什么?我无法弄明白。我想解析,链接,描述,pubDate,并将它们传递给ListView。理想情况下,我只会在列表视图中显示标题和剧集编号,并将其他标记传递给String,因此当我单击listView中的项目时,我可以显示它们。
当我点击ListView中的某个项目时,我已经创建了另一个名为SingleMenuItem的类,它现在只是填充代码,它没有显示任何内容,因为项目没有被解析
任何帮助将不胜感激。 Here is a RSS link to the feed:
public class SingleMenuItem extends Activity {
// XML node keys
static final String KEY_NAME = "name";
static final String KEY_DATE = "pubdate";
static final String KEY_DESC = "description";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.single_list_item);
// getting intent data
Intent in = getIntent();
// Get XML values from previous intent
String name = in.getStringExtra(KEY_NAME);
String date = in.getStringExtra(KEY_DATE);
String description = in.getStringExtra(KEY_DESC);
// Displaying all values on the screen
TextView lblName = (TextView) findViewById(R.id.name_label);
TextView lblDate = (TextView) findViewById(R.id.date_label);
TextView lblDesc = (TextView) findViewById(R.id.description_label);
lblName.setText(name);
lblDate.setText(date);
lblDesc.setText(description);
}
}
以下是我的ReaderAppActivty的代码,它将解析的结果放入ListView:
public class ReaderAppActivity extends Fragment {
private ReaderAppActivity local;
private ListView mList;
/**
* This method creates main application view
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//super.onCreate(savedInstanceState);
// Set view
//setContentView(R.layout.fragment_rss);
local = this;
//int position = getArguments().getInt("position");
// String url = getArguments().getString("url");
// List of rivers
String[] menus = getResources().getStringArray(R.array.menus);
// Creating view corresponding to the fragment
View v = inflater.inflate(R.layout.fragment_rss, container, false);
// Set reference to this activity
//local = this;
GetRSSDataTask task = new GetRSSDataTask();
// Start download RSS task
task.execute("http://thechurchofwhatshappeningnow.libsyn.com/rss");
//task.execute(url);
// Debug the thread name
Log.d("ITCRssReader", Thread.currentThread().getName());
//mList = (ListView) findViewById(R.id.rssListMainView);
return v;
}
private class GetRSSDataTask extends AsyncTask<String, Void, List<RssItem> > {
@Override
protected List<RssItem> doInBackground(String... urls) {
// Debug the task thread name
Log.d("ITCRssReader", Thread.currentThread().getName());
try {
// Create RSS reader
RssReader rssReader = new RssReader(urls[0]);
// Parse RSS, get items
return rssReader.getItems();
} catch (Exception e) {
Log.e("ITCRssReader", e.getMessage());
}
return null;
}
@Override
protected void onPostExecute(List<RssItem> result) {
// Get a ListView from main view
ListView mList = (ListView) getView().findViewById(R.id.rssListMainView);
// Create a list adapter
ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem>(getActivity(),R.layout.rss_text, result);
//ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem>(getActivity(),R.layout.fragment_rss, result);
// Set list adapter for the ListView
mList.setAdapter(adapter);
// Set list view item click listener
mList.setOnItemClickListener(new ListListener(result, getActivity()));
}
}
}
答案 0 :(得分:0)
根据您RssParseHandler
中已注释掉的代码数量,您显然已经在努力解决这个问题了,而且一些早期尝试比您现在所做的更接近正确。
您当前代码的问题似乎是您没有始终重置驱动您正在设置项目的哪一部分的布尔值。通过它进行调试,我看到它在某个时刻在链接字段中设置了一个日期。
但是你实际上是在错误的方法中做了一些设置,因为characters
方法不一定会给你标签的全部内容。您需要使用Stringbuilder
,我可以在注释掉的代码中看到您在某些时候尝试过这种情况。
如果您在stringbuilder中收集文本并执行endElement
方法中的所有设置,则根本不需要布尔值,因为endElement
方法知道您使用哪个标记'结束。
这是一个工作版本,可能与你在某些时候所拥有的东西相距甚远,但它摆脱了所有这些旗帜领域。
public class RssParseHandler extends DefaultHandler {
private List<RssItem> rssItems;
private RssItem currentMessage;
private StringBuilder builder;
public RssParseHandler() {
rssItems = new ArrayList<>();
builder = new StringBuilder();
}
public List<RssItem> getItems() {
return this.rssItems;
}
@Override
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
super.startElement(uri, localName, name, attributes);
builder.setLength(0);
if (localName.equalsIgnoreCase("item")) {
this.currentMessage = new RssItem();
}
}
@Override
public void endElement(String uri, String localName, String name)
throws SAXException {
super.endElement(uri, localName, name);
if (this.currentMessage != null) {
if (localName.equalsIgnoreCase("item")) {
rssItems.add(currentMessage);
currentMessage = null;
} else if (localName.equalsIgnoreCase("link")) {
currentMessage.setLink(builder.toString());
} else if (localName.equalsIgnoreCase("description")) {
currentMessage.setDescription(builder.toString());
} else if (localName.equalsIgnoreCase("pubDate")){
currentMessage.setDate(builder.toString());
} else if (localName.equalsIgnoreCase("title")) {
currentMessage.setTitle(builder.toString());
}
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
super.characters(ch, start, length);
builder.append(ch, start, length);
}
}