使用自定义适配器将数据从XML解析到列表
问题描述:
我从上载到网站的XML获取数据。我想在自定义ListView
中显示来自XML的文本,该文本有两个TextView
。 '标题'应该进入上面的TextView
,'guid'进入下面的TextView
。我不知道我该如何去做这件事。我写了下面的自定义适配器。使用自定义适配器将数据从XML解析到列表
CustomAdapter.java
public class CustomAdapter extends BaseAdapter {
private ArrayList list;
private LayoutInflater layoutInflater;
public CustomAdapter(Context context, ArrayList list) {
this.list= list;
layoutInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.layout_list_row, null);
holder = new ViewHolder();
holder.backgroundImage = (ImageView) convertView.findViewById(R.id.backgroundImage);
holder.topText = (TextView) convertView.findViewById(R.id.topText);
holder.bottomText = (TextView) convertView.findViewById(R.id.bottomText);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
DiscourseItem discourseItem = (DiscourseItem) discourseList.get(position);
holder.topText.setText(discourseItem.getTopText());
holder.bottomText.setText(discourseItem.getBottomText());
return convertView;
}
static class ViewHolder {
ImageView backgroundImage;
TextView topText; //This should display the text in the 'title' field
TextView bottomText; //This should display the text in the 'guid' field
}
}
我目前能正常ArrayAdapter
小号分别显示两个在分开的ListView
秒。这是我写的代码。
XMLParser.java
public class XMLParser extends AsyncTask {
private URL url;
public ArrayList<String> title = new ArrayList<>();
public ArrayList<String> guid = new ArrayList<>();
@Override
protected Object doInBackground(Object[] objects) {
try {
url = new URL(removed);
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(false);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput(getInputStream(url), null);
boolean insideItem = false;
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG) {
if (xpp.getName().equalsIgnoreCase("item")){
insideItem = true;
} else if (xpp.getName().equalsIgnoreCase("title")){
if (insideItem)
title.add(xpp.nextText());
} else if (xpp.getName().equalsIgnoreCase("guid")){
if (insideItem)
guid.add(xpp.nextText());
}
} else if (eventType == XmlPullParser.END_TAG && xpp.getName().equalsIgnoreCase("item")){
insideItem = false;
}
eventType = xpp.next();
}
} catch (MalformedURLException e){
e.printStackTrace();
} catch (XmlPullParserException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return title;
}
public InputStream getInputStream(URL url){
try {
return url.openConnection().getInputStream();
} catch (IOException e){
e.printStackTrace();
}
return null;
}
public ArrayList<String> titles(){
return title;
}
public ArrayList<String> guids(){
return guid;
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
parser = new XMLParser();
parser.execute();
title = parser.titles();
guid = parser.guids();
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
discourseList = getDiscourseList();
}
}, 2000);
}
});
ListView listView = (ListView) findViewById(R.id.discourseList);
listView.setAdapter(new CustomAdapter(this, discourseList));
}
private ArrayList<DiscourseItem> getDiscourseList() {
ArrayList<DiscourseItem> listData = new ArrayList<DiscourseItem>();
String[] topText = new String[title.size()];
topText = title.toArray(topText);
String[] bottomText = new String[guid.size()];
bottomText = guid.toArray(bottomText);
for (int i = 0; i <= title.size(); i++) {
try {
DiscourseItem discourseItem = new DiscourseItem();
discourseItem.setTopText(topText[i]);
discourseItem.setBottomText(bottomText[i]);
listData.add(discourseItem);
} catch (ArrayIndexOutOfBoundsException e){
e.printStackTrace();
}
}
return listData;
}
}
编辑:
我做了上述变化。现在,当分析器运行,并调用getDiscourseList()
,它引发以下错误在discourseItem.setTopText(topText[i]);
:
java.lang.ArrayIndexOutOfBoundsException: length=2; index=2
答
您可以创建包装类为你的上和下的值(这样的事情,考虑的另一个名字,因为我不知道你的数据的上下文):
public class TitleGuidPair {
private final String title;
private final String guid;
public TitleGuidPair(String title, String guid) {
this.title = title;
this.guid = guid;
}
//getters
}
然后解析你的结果到TitleGuidPair的ArrayList。如果你想保留你的解析算法,你可以进行一些后期处理,然后从你拥有的两个列表中构建TitleGuidPairs。
已经只落后传递给TitleGuidPairs的适配器列表,并在getView方法步骤设置顶部和底部的文字像
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.layout_list_row, null);
holder = new ViewHolder();
holder.backgroundImage = (ImageView) convertView.findViewById(R.id.backgroundImage);
holder.topText = (TextView) convertView.findViewById(R.id.topText);
holder.bottomText = (TextView) convertView.findViewById(R.id.bottomText);
TitleGuidPair titleGuidPair = list.get(position);
holder.topText.setText(titleGuidPair.getTitle());
holder.bottomText.setText(titleGuidPair.getGuid());
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
return convertView;
}
所以,我做了修改,使利用一个'ListView'的展现数据,但它会抛出一个'ArrayIndexOutOfBoundsException'。我更新了OP以反映代码和错误。 – Devansh
你声明你的数组的大小是title.size()。所以你可以访问从0到大小-1的索引。在你的循环中,你通过从0到大小的索引闪烁。请将您的循环从for(int i = 0; i Bari
是的,非常感谢。就在我发布这里之后,我再次检查了我的代码并注意到了这一点。是的,每个标题都有一个指导,这不会成为一个问题。非常感谢! – Devansh