显示xml浮动数据

时间:2019-03-05 11:46:00

标签: android xml

我正在尝试创建一个地震观察器应用程序,但是在加载项目时,我似乎无法从XML URL中获取坐标和其他部分以显示在我的活动中,我知道它们的类型为float。我尝试了不同的方法,但控制台上没有错误,因此它一定与我调用它的方式相同? 我添加了一些输出和图像

package ja.example.mpd1starterearth;

import android.app.ProgressDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    ListView lvRss;
    ArrayList<String> titles;
    ArrayList<String> links;
    ArrayList<Double> lat;
    ArrayList<Double> lon;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        lvRss = (ListView) findViewById(R.id.lvRss);

        titles = new ArrayList<String>();
        links = new ArrayList<String>();
        lat = new ArrayList<Double>();
        lon = new ArrayList<Double>();

        lvRss.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                Uri uri = Uri.parse(links.get(position));
                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                startActivity(intent);

            }
        });

        new ProcessInBackground().execute();
    }

    public InputStream getInputStream(URL url)
    {
        try
        {
            //openConnection() returns instance that represents a connection to the remote object referred to by the URL
            //getInputStream() returns a stream that reads from the open connection
            return url.openConnection().getInputStream();
        }
        catch (IOException e)
        {
            return null;
        }
    }

    public class ProcessInBackground extends AsyncTask<Integer, Void, Exception>
    {
        ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);

        Exception exception = null;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            progressDialog.setMessage("Busy loading rss feed...please wait...");
            progressDialog.show();
        }

        @Override
        protected Exception doInBackground(Integer... params) {

            try
            {
                URL url = new URL("http://quakes.bgs.ac.uk/feeds/MhSeismology.xml");

                //creates new instance of PullParserFactory that can be used to create XML pull parsers
                XmlPullParserFactory factory = XmlPullParserFactory.newInstance();

                //Specifies whether the parser produced by this factory will provide support
                //for XML namespaces
                factory.setNamespaceAware(false);

                //creates a new instance of a XML pull parser using the currently configured
                //factory features
                XmlPullParser xpp = factory.newPullParser();

                // We will get the XML from an input stream
                xpp.setInput(getInputStream(url), "UTF_8");

                /* We will parse the XML content looking for the "<title>" tag which appears inside the "<item>" tag.
                 * We should take into consideration that the rss feed name is also enclosed in a "<title>" tag.
                 * Every feed begins with these lines: "<channel><title>Feed_Name</title> etc."
                 * We should skip the "<title>" tag which is a child of "<channel>" tag,
                 * and take into consideration only the "<title>" tag which is a child of the "<item>" tag
                 *
                 * In order to achieve this, we will make use of a boolean variable called "insideItem".
                 */
                boolean insideItem = false;

                // Returns the type of current event: START_TAG, END_TAG, START_DOCUMENT, END_DOCUMENT etc..
                int eventType = xpp.getEventType(); //loop control variable

                while (eventType != XmlPullParser.END_DOCUMENT)
                {
                    //if we are at a START_TAG (opening tag)
                    if (eventType == XmlPullParser.START_TAG)
                    {
                        //if the tag is called "item"
                        if (xpp.getName().equalsIgnoreCase("item"))
                        {
                            insideItem = true;
                        }
                        //if the tag is called "title"
                        else if (xpp.getName().equalsIgnoreCase("title"))
                        {
                            if (insideItem)
                            {
                                // extract the text between <title> and </title>
                                titles.add(xpp.nextText());
                            }
                        }
                        //if the tag is called "link"
                        else if (xpp.getName().equalsIgnoreCase("link"))
                        {
                            if (insideItem)
                            {
                                // extract the text between <link> and </link>
                                links.add(xpp.nextText());
                            }
                        }
                        else if(xpp.getName().equalsIgnoreCase("geo:lat")){
                            if(insideItem){
                                //extract the text between <geo:lat> and </geo:lat>
                                lat.add(Double.valueOf(xpp.nextText()));
                            }
                        }
                        else if(xpp.getName().equalsIgnoreCase("geo:long")){
                            if(insideItem) {
                                //extract the text between <geo:lat> and </geo:lat>
                                lon.add(Double.valueOf(xpp.nextText()));;
                            }  }
                    }
                    //if we are at an END_TAG and the END_TAG is called "item"
                    else if (eventType == XmlPullParser.END_TAG && xpp.getName().equalsIgnoreCase("item"))
                    {
                        insideItem = false;
                    }

                    eventType = xpp.next(); //move to next element
                }


            }
            catch (MalformedURLException e)
            {
                exception = e;
            }
            catch (XmlPullParserException e)
            {
                exception = e;
            }
            catch (IOException e)
            {
                exception = e;
            }

            return exception;
        }

        @Override
        protected void onPostExecute(Exception s) {
            super.onPostExecute(s);

            ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, titles);

            lvRss.setAdapter(adapter);


            progressDialog.dismiss();
        }
    }
}

enter image description here

enter image description here

2 个答案:

答案 0 :(得分:0)

您正在比较标记名称和其中的空格,因此equalsIgnoreCase()将始终返回false,因为geo:lang将不等于geo :lat

只需测试此代码。

String s = "geo:lang";
System.out.println(""+s.equalsIgnoreCase("geo :long"));

对于两种情况,您都需要删除o:之间的空格。equalsIgnoreCase("geo:long")

答案 1 :(得分:0)

您用于解析URL中数据的代码是完全正确的。您不会看到所有活动的所有数据,因为这行代码。

ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, titles);

您将titles数组列表传递给适配器,这就是为什么您仅在活动中看到所有标题xml的原因。

解决方案::简单的方法是格式化从4个数组列表titleslinkslatlon连接的数据的格式。 / p>

/**
 * This method will format data from titles, links, lat, lon arraylist.
 */
private List<String> formatDataBeforeDisplayOnListView(){
    List<String> list = new ArrayList<>();

    StringBuilder sb = new StringBuilder();
    int size = titles.size();
    for (int i = 0; i < size; ++i) {
        String title = titles.get(i);
        String link = links.get(i);
        Double geoLat = lat.get(i);
        Double getLon = lon.get(i);

        sb.append("title: ").append(title).append("\n")
          .append("link: ").append(link).append("\n")
          .append("geo-lat: ").append(geoLat).append("\n")
          .append("geo-lon: ").append(getLon);

        list.add(sb.toString());
    }

    return list;
}

然后将代码更改为

// Comment-out this line
// ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, titles);

List<String> items = formatDataBeforeDisplayOnListView();
ArrayAdapter<String> adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, items);

注意::如果要在更好的设计/ UI中显示每个项目列表视图,则应编写自定义适配器类,而不要编写ArrayAdapter

更新:基于Jase的评论

首先,声明一个名为Item的新类

public class Item {
    private String title;
    private String link;
    private Double lat;
    private Double lon;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getLink() {
        return link;
    }

    public void setLink(String link) {
        this.link = link;
    }

    public Double getLat() {
        return lat;
    }

    public void setLat(Double lat) {
        this.lat = lat;
    }

    public Double getLon() {
        return lon;
    }

    public void setLon(Double lon) {
        this.lon = lon;
    }

    @Override
    public String toString() {
        return (new StringBuilder()).append("title: ").append(title).append("\n")
                .append("link: ").append(link).append("\n")
                .append("geo-lat: ").append(lat).append("\n")
                .append("geo-lon: ").append(lon).toString();
    }
}

然后,将您的活动代码更改为

public class MainActivity extends AppCompatActivity {

    ListView lvRss;
    ArrayList<Item> mItems = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        lvRss = (ListView) findViewById(R.id.lvRss);
        lvRss.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                // TODO: Process clicked item here
                Item item = (Item) parent.getItemAtPosition(position);

                Uri uri = Uri.parse(item.getLink());
                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                startActivity(intent);
            }
        });

        new ProcessInBackground().execute();
    }

    public InputStream getInputStream(URL url) {
        try {
            //openConnection() returns instance that represents a connection to the remote object referred to by the URL
            //getInputStream() returns a stream that reads from the open connection
            return url.openConnection().getInputStream();
        } catch (IOException e) {
            return null;
        }
    }

    public class ProcessInBackground extends AsyncTask<Integer, Void, Exception> {
        ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);

        Exception exception = null;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            progressDialog.setMessage("Busy loading rss feed...please wait...");
            progressDialog.show();
        }

        @Override
        protected Exception doInBackground(Integer... params) {

            try {
                URL url = new URL("http://quakes.bgs.ac.uk/feeds/MhSeismology.xml");

                //creates new instance of PullParserFactory that can be used to create XML pull parsers
                XmlPullParserFactory factory = XmlPullParserFactory.newInstance();

                //Specifies whether the parser produced by this factory will provide support
                //for XML namespaces
                factory.setNamespaceAware(false);

                //creates a new instance of a XML pull parser using the currently configured
                //factory features
                XmlPullParser xpp = factory.newPullParser();

                // We will get the XML from an input stream
                xpp.setInput(getInputStream(url), "UTF_8");

                /* We will parse the XML content looking for the "<title>" tag which appears inside the "<item>" tag.
                 * We should take into consideration that the rss feed name is also enclosed in a "<title>" tag.
                 * Every feed begins with these lines: "<channel><title>Feed_Name</title> etc."
                 * We should skip the "<title>" tag which is a child of "<channel>" tag,
                 * and take into consideration only the "<title>" tag which is a child of the "<item>" tag
                 *
                 * In order to achieve this, we will make use of a boolean variable called "insideItem".
                 */
                boolean insideItem = false;

                // Returns the type of current event: START_TAG, END_TAG, START_DOCUMENT, END_DOCUMENT etc..
                int eventType = xpp.getEventType(); //loop control variable

                Item item = null;
                while (eventType != XmlPullParser.END_DOCUMENT) {
                    //if we are at a START_TAG (opening tag)
                    if (eventType == XmlPullParser.START_TAG) {
                        //if the tag is called "item"
                        if (xpp.getName().equalsIgnoreCase("item")) {
                            insideItem = true;
                            item = new Item();
                        }
                        //if the tag is called "title"
                        else if (xpp.getName().equalsIgnoreCase("title")) {
                            if (insideItem) {
                                // extract the text between <title> and </title>
                                item.setTitle(xpp.nextText());
                            }
                        }
                        //if the tag is called "link"
                        else if (xpp.getName().equalsIgnoreCase("link")) {
                            if (insideItem) {
                                // extract the text between <link> and </link>
                                item.setLink(xpp.nextText());
                            }
                        } else if (xpp.getName().equalsIgnoreCase("geo:lat")) {
                            if (insideItem) {
                                //extract the text between <geo:lat> and </geo:lat>
                                item.setLat(Double.valueOf(xpp.nextText()));
                            }
                        } else if (xpp.getName().equalsIgnoreCase("geo:long")) {
                            if (insideItem) {
                                //extract the text between <geo:lat> and </geo:lat>
                                item.setLon(Double.valueOf(xpp.nextText()));
                            }
                        }
                    }
                    //if we are at an END_TAG and the END_TAG is called "item"
                    else if (eventType == XmlPullParser.END_TAG && xpp.getName().equalsIgnoreCase("item")) {
                        insideItem = false;
                        mItems.add(item);
                    }

                    eventType = xpp.next(); //move to next element
                }

            } catch (MalformedURLException e) {
                exception = e;
            } catch (XmlPullParserException e) {
                exception = e;
            } catch (IOException e) {
                exception = e;
            }

            return exception;
        }

        @Override
        protected void onPostExecute(Exception s) {
            super.onPostExecute(s);

            ArrayAdapter<Item> adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, mItems);
            lvRss.setAdapter(adapter);

            progressDialog.dismiss();
        }
    }
}