使用自定义适配器将数据从XML解析为列表

时间:2017-02-19 16:49:18

标签: java android arrays listview xml-parsing

我从网站上传的XML中获取数据。我想在自定义ListView中显示XML中的文本,其中包含两个TextView个。 '标题'应该进入上层TextView和#guid'进入较低的TextView。我不知道该怎么办呢。我已经编写了以下自定义适配器。

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
    }

}

我目前能够在具有正常ListView s的单独ArrayAdapter中单独显示两者。这是我编写的代码。

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

1 个答案:

答案 0 :(得分:1)

您可以为上下值创建包装类(类似这样,考虑另一个名称,因为我不知道您的数据的上下文):

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