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

使用自定义适配器将数据从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; 
} 
+0

所以,我做了修改,使利用一个'ListView'的展现数据,但它会抛出一个'ArrayIndexOutOfBoundsException'。我更新了OP以反映代码和错误。 – Devansh

+0

你声明你的数组的大小是title.size()。所以你可以访问从0到大小-1的索引。在你的循环中,你通过从0到大小的索引闪烁。请将您的循环从for(int i = 0; i Bari

+0

是的,非常感谢。就在我发布这里之后,我再次检查了我的代码并注意到了这一点。是的,每个标题都有一个指导,这不会成为一个问题。非常感谢! – Devansh