2014-12-09 7 views
0

Я новичок в разработке Android, и я изо всех сил пытаюсь разобрать более одного тега за раз и отображать его в ListView.Может обрабатывать только тег TITLE - LINK, DESCRIPTION, PUBDATE и другие. (RSS/SAX)

Я использую парсер 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, поэтому я могу отображать их, когда я нажимаю элемент в спискеView.

Я создал еще один класс под названием SingleMenuItem, который будет вызываться, когда я нажимаю элемент в ListView, это просто код наполнителя прямо сейчас, он ничего не отображает, потому что элементы не разбираются.

Любая помощь будет оценена по достоинству. 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

Основываясь на количестве закомментированного кода в вашем 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); 
    } 

}