您好,我很难理解如何使用我的JSON解析器做我想做的事情。我正在解析位于http://api.pathofexile.com/leagues?type=all的数据以取出联盟ID(目前它们是“默认”,“Hardcore”,“2月12日Solo HC Race”等)。我的解析器目前将这些ID放入列表视图。
我遇到的问题是这些ID会随着时间而改变。他们也有自己的JSON网址,我需要根据联盟ID进行解析。例如,如果联盟ID是“默认”,我需要获取该ID并将其放入网址:
“api.pathofexile.com/leagues /”+ id +“?ladder = 1& ladderOffset = 1& ladderLimit = 2”获取http://api.pathofexile.com/leagues/Default?ladder=1&ladderOffset=1&ladderLimit=2
基本上,我希望能够点击listview中的id并让它更新url并将新数据解析为单独的列表。
以下是我的JSON解析器的内容:
public class Leagues extends ListActivity {
public static String url = "http://api.pathofexile.com/leagues?type=all";
private static final String TAG_ID = "id";
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
JSONArray leagues = null;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.list_item);
new GetJSONTask().execute("");
}
protected class GetJSONTask extends AsyncTask<String, Integer, ArrayList<HashMap<String, String>>> {
protected ArrayList<HashMap<String, String>> leaguesList;
private final ProgressDialog dialog = new ProgressDialog(Leagues.this);
// onPreExecute method
protected void onPreExecute() {
this.dialog.setMessage("Loading, Please Wait..");
this.dialog.setCancelable(false);
this.dialog.show();
}
// doInBackground method
@Override
protected ArrayList<HashMap<String, String>> doInBackground(String... params) {
leaguesList = new ArrayList<HashMap<String, String>>();
// defaultHttpClient
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet HttpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(HttpGet);
json = EntityUtils.toString(httpResponse.getEntity());
// getting array of entries
JSONArray leagues = new JSONArray(json);
// looping through entries
for (int i = 0; i < leagues.length(); i++) {
JSONObject league = leagues.getJSONObject(i);
String id = league.getString(TAG_ID);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_ID, id);
//map.put(TAG_EVENT, event);
// adding HashList to ArrayList
leaguesList.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return leaguesList;
}
// onPostExecute method
protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
ListAdapter adapter = new SimpleAdapter(getApplicationContext(), leaguesList, R.layout.league, new String[] { TAG_ID }, new int[] { R.id.id });
// selecting single ListView item
ListView lv = getListView();
lv.setAdapter(adapter);
if (this.dialog.isShowing()) {
this.dialog.dismiss();
}
}
}
}
此时我很丢失。即使我现在设置解析器,我正在努力做什么?任何人都可以指出我正确的方向吗?
感谢。
编辑以进一步澄清:
现在我的解析器会将联盟ID从网址“api.pathofexile.com/leagues?type=all”放入ListView,如下所示:
(这些项目会随着时间的推移而改变)
我希望能够点击“默认”,这会将网址更改为“api.pathofexile.com/leagues/Default?ladder=1&ladderOffset=1&ladderLimit=2”并将其解析为新的的ListView。
更新 使用Darwind提供的项目,我改变它(使用我的一些其他代码)来显示我在点击联盟ID后想要的JSON数据。
public class LeagueView extends ListActivity {
//private TextView leagueId, leagueDescription;
private static final String TAG_LADDER = "ladder";
private static final String TAG_ENTRIES = "entries";
private static final String TAG_ONLINE = "online";
private static final String TAG_RANK = "rank";
private static final String TAG_CHARACTER = "character";
private static final String TAG_CHARNAME = "name";
private static final String TAG_LEVEL = "level";
private static final String TAG_CLASS = "class";
private static final String TAG_EXPERIENCE = "experience";
private static final String TAG_ACCOUNT = "account";
private static final String TAG_ACCNAME = "name";
private static final String TAG_ACCNAME2 = "name2";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.league_layout);
//leagueId = (TextView) findViewById(R.id.leagueId);
//leagueDescription = (TextView) findViewById(R.id.leagueDescription);
String urlToJson = getIntent().getExtras().getString("leagueUrl");
if (urlToJson == null) {
Toast.makeText(this, "Url was null!", Toast.LENGTH_LONG).show();
} else {
new LeagueTask().execute(urlToJson.replaceAll(" ", "%20"));
}
}
protected class LeagueTask extends AsyncTask<String, Integer, League> {
private final ProgressDialog dialog = new ProgressDialog(LeagueView.this);
protected ArrayList<HashMap<String, String>> entriesList;
// onPreExecute method
protected void onPreExecute() {
this.dialog.setMessage("Retrieving Ladder Information...");
this.dialog.setCancelable(false);
this.dialog.show();
}
// doInBackground method
@Override
protected League doInBackground(String... params) {
League aLeague = new League();
entriesList = new ArrayList<HashMap<String, String>>();
// defaultHttpClient
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet HttpGet = new HttpGet(params[0]);
HttpResponse httpResponse = httpClient.execute(HttpGet);
String json = EntityUtils.toString(httpResponse.getEntity());
// Getting a JSONObject filled.
JSONObject leagueObject = new JSONObject(json);
//String id = leagueObject.getString("id");
//String description = leagueObject.getString("description");
JSONObject ladder = leagueObject.getJSONObject(TAG_LADDER);
JSONArray entries = ladder.getJSONArray(TAG_ENTRIES);
// looping through entries
for (int i = 0; i < entries.length(); i++) {
JSONObject ent = entries.getJSONObject(i);
// storing each JSON item in a variable
String online = ent.getString(TAG_ONLINE);
if (online == "false")
online = "Offline";
else online = "Online";
String rank = ent.getString(TAG_RANK);
// pull out character object
JSONObject character = ent.getJSONObject(TAG_CHARACTER);
String chName = character.getString(TAG_CHARNAME);
String lvl = character.getString(TAG_LEVEL);
String cl = character.getString(TAG_CLASS);
String xp = character.getString(TAG_EXPERIENCE);
// pull out account object
JSONObject account = ent.getJSONObject(TAG_ACCOUNT);
String accName = account.getString(TAG_ACCNAME);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_ONLINE, online);
map.put(TAG_CHARNAME, chName);
map.put(TAG_ACCNAME2, accName);
map.put(TAG_RANK, rank);
map.put(TAG_LEVEL, lvl);
map.put(TAG_EXPERIENCE, xp);
map.put(TAG_CLASS, cl);
entriesList.add(map);
}
// creating a league to display
aLeague = new League();
//aLeague.setLeagueId(id);
//aLeague.setDescription(description);
} catch (JSONException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return aLeague;
}
// onPostExecute method
protected void onPostExecute(League result) {
//leagueId.setText(result.getLeagueId());
//leagueDescription.setText(result.getDescription());
ListAdapter adapter = new SimpleAdapter(getApplicationContext(), entriesList, R.layout.league_layout, new String[] { TAG_RANK, TAG_CHARNAME, TAG_LEVEL, TAG_EXPERIENCE, TAG_CLASS }, new int[] { R.id.rank, R.id.chName, R.id.lvl, R.id.experience, R.id.cl });
// selecting single ListView item
ListView lv = getListView();
lv.setAdapter(adapter);
if (this.dialog.isShowing()) {
this.dialog.dismiss();
}
}
}
}
答案 0 :(得分:0)
我建议不要自己编写解析器但使用JSON开发的解析器http://json.org/java/
答案 1 :(得分:0)
所以我嘲笑你的代码并在本地运行它。现在我明白你要做什么了。你的问题分为两部分。我认为问题描述名称不详,您的描述似乎集中在可点击的列表视图项目上,但您的摘要似乎是围绕解析json。
还要注意http://api.pathofexile.com/leagues/Hardcore?ladder=1&ladderOffset=1&ladderLimit=2没有给出格式正确的json文本,缺少开头和结尾的方括号。这不正确,它返回的是单个JSONObject而不是数组
第一部分:使列表视图项可单击,使用ListView.setOnItemClickListener使项目可单击。例如请参阅本教程:http://www.ezzylearning.com/tutorial.aspx?tid=1351248
第二部分单击时应该发生什么。其中一部分将用于setOnItemClickListener的实现,第二部分是构建新链接并单击并返回内容的JSON。您正在返回ArrayList&lt; HashMap&lt; String,String&gt;&gt; leaguesList;这看起来非常有限,你为什么不返回JSONArray本身或者ArrayList&lt; HashMap&lt; String,JSONObject&gt;&gt;其中地图有ID作为关键字以及JSONObject中您以后可以使用的所有元素,除非ID是您唯一感兴趣的内容?
我没有Android模拟器,但如果你需要任何有关JSON解析器的帮助,请告诉我。
这就是我想象它的工作方式,onclick事件将构建一个来自
的新网址 public static String PATTERN =
"http://api.pathofexile.com/leagues/" + ID_TOKEN +
"?ladder=1&ladderOffset=1&ladderLimit=2";
使用传入的Url编码ID,例如默认情况下,2月15日Solo HC Race并将调用GetJSONTask.doInBackGround任务以获取新的JSON数组。
答案 2 :(得分:0)
好的,基本上因为vsnyc指出你的头衔可能有点误导。
我看到它的方式是:
我基本上把你所有的代码都搞定了并改了一下。例如,我在评论中提到,您应该使用一个类来表示每个联盟,然后覆盖这种新类型对象的toString
方法,以便可以在ListView
中直接使用此类
作为您使用的第一个网址:http://api.pathofexile.com/leagues?type=all
返回一个JSON数组而不是单个对象,此数组中的对象与选择特定联盟时返回的数据不同,我不会# 39;建议使用相同的AsyncTask获取联赛列表和单个联赛。
相反,在您使用联盟填充第一个ListView
后,我会创建第二个视图,通过从特定联盟获取数据来填充。
要进入代表一个联盟的第二个视图,您需要为第一个视图的OnItemClickListener
实施ListView
。在OnItemClickListener
中,您将获得所选的联赛名称并将其传递给下一个视图,然后该视图将联系服务器并获取代表给定联盟的JSON
对象并解析数据。
我已经创建了一个小项目,因为这里有很多代码要添加到答案中,我需要花费更多时间来删除所有不必要的代码,而不仅仅是为了给你一个完整的工作项目。 ; - )
这是拉链文件中的项目:
https://dl.dropbox.com/u/27724371/AndroidListViews.zip
如果这不是您想要的,请告诉我。