简体   繁体   English

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

[英]Parse Data from XML into List with Custom Adapter

I am getting data from an XML uploaded on a website. 我从网站上上传的XML中获取数据。 I want to display the text from the XML in a custom ListView , which has two TextView s. 我想在具有两个TextView的自定义ListView显示XML中的文本。 The 'title' should go into the upper TextView and the 'guid' into the lower TextView . 'title'应该进入上部TextView ,'guid'应该进入下部TextView I'm not sure how I should go about doing this. 我不确定该怎么做。 I've written the following Custom Adapter. 我编写了以下自定义适配器。

CustomAdapter.java 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
    }

}

I'm currently able to display the two separately in separate ListView s with normal ArrayAdapter s. 目前,我可以使用普通的ArrayAdapter在单独的ListView中分别显示两者。 Here's the code I've written. 这是我编写的代码。

XMLParser.java 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 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;
    }
}

Edit : 编辑:

I've made the above changes. 我进行了上述更改。 Now when the parser runs and calls getDiscourseList() , it throws the following error at discourseItem.setTopText(topText[i]); 现在,当解析器运行并调用getDiscourseList() ,它将在discourseItem.setTopText(topText[i]);引发以下错误discourseItem.setTopText(topText[i]); :

java.lang.ArrayIndexOutOfBoundsException: length=2; index=2

You can create wrapper class for your upper and bottom values ( something like this, consider another name as I don't know the context of your data): 您可以为上限值和下限值创建包装器类(类似这样,请考虑其他名称,因为我不知道数据的上下文):

public class TitleGuidPair {
  private final String title;
  private final String guid;
  public TitleGuidPair(String title, String guid) {
    this.title = title;
    this.guid = guid;
  }
 //getters
}

And then parse your result to ArrayList of TitleGuidPair. 然后将您的结果解析为TitleGuidPair的ArrayList。 If you want to keep your parsing algorithm you can make some post-processing and build your TitleGuidPairs afterwards from the two lists that you have. 如果要保留解析算法,则可以进行一些后处理,然后从已有的两个列表中构建TitleGuidPair。

Having that step behind just pass to your adapter List of TitleGuidPairs and in the getView method set top and bottom text like 落后一步只是传递到您的适配器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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM