0

こんにちは、JSON パーサーでやりたいことを行う方法を理解するのに苦労しています。現在、 http://api.pathofexile.com/leagues?type =all にあるデータを解析してリーグ ID を取得しています (現在、それらは「デフォルト」、「ハードコア」、「2 月 12 日のソロ HC レース」です。など) 私のパーサーは現在、これらの ID をリストビューに入れています。

私が抱えている問題は、これらの ID が時間の経過とともに変化することです。また、リーグ ID に基づいて解析する必要がある独自の JSON URL もあります。たとえば、リーグ ID が「デフォルト」の場合、その ID を取得して URL に入れる必要があります。

"api.pathofexile.com/leagues/"+ id +"?ladder=1&ladderOffset=1&ladderLimit=2" を取得してhttp://api.pathofexile.com/leagues/Default?ladder=1&ladderOffset=1&ladderLimit=2

基本的に、リストビューで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();
            }

        }
    }

}

この時点でかなり迷っています。私がやろうとしていることは、パーサーを今セットアップした方法でも可能ですか? 誰かが私を正しい方向に向けることができますか?

ありがとう。

さらに明確にするために編集:

現在、私のパーサーは、以下のように「api.pathofexile.com/leagues?type=all」という URL からリーグ ID を ListView に入れます。

  1. デフォルト
  2. ハードコア
  3. 2月12日 ソロHCレース

(これらの項目は時間の経過とともに変化します)

「デフォルト」をクリックして、URL を「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();
        }
    }
}
}
4

3 に答える 3

0

基本的に vsnyc が指摘したように、あなたのタイトルはおそらく少し誤解を招くものです。

私がそれを見る方法は、これです:

  1. JSON 配列の解析からすべてのリーグのリストを取得する
  2. リスト内のリーグをクリックして、JSON オブジェクトを解析することにより、選択したリーグに関する情報を提供するビューを取得できます。

私は基本的にあなたのすべてのコードを変更し、少し変更しました。たとえば、コメントで述べたように、クラスを使用してすべてのリーグを表し、toStringこの新しい種類のオブジェクトのメソッドをオーバーライドして、このクラスを で直接使用できるようにする必要がありますListView

使用している最初の URL:http://api.pathofexile.com/leagues?type=allは単一のオブジェクトではなく JSON 配列を返し、この配列内のオブジェクトは特定のリーグを選択したときに返されるデータとは異なるため、両方を取得するために同じ AsyncTask を使用することはお勧めしません。リーグのリストと単一のリーグ。

代わりに、最初のListViewビューにリーグを入力した後、特定のリーグからデータを取得することによって入力される 2 番目のビューを作成します。

1 つのリーグを表す 2 番目のビューに到達するには、最初のビューのOnItemClickListenerを実装する必要があります。ListViewでは、OnItemClickListener選択したリーグ名を取得し、それを次のビューに渡します。次のビューはサーバーに接続しJSON、指定されたリーグを表すオブジェクトを取得してデータを解析します。

これは答えに追加するコードが非常に多く、完全に機能するプロジェクトを提供するだけでなく、不要なコードをすべて削除するのに時間がかかるため、小さなプロジェクトを作成しました。;-)

zip ファイルのプロジェクトは次のとおりです。

https://dl.dropbox.com/u/27724371/AndroidListViews.zip

これがあなたが探していたものではない場合はお知らせください。

于 2013-02-12T19:17:19.313 に答える
0

自分でパーサーを作成するのではなく、JSON が開発したものを使用することをお勧めします
http://json.org/java/

于 2013-02-11T22:49:31.933 に答える
0

Jophess、私は自分の答えを編集しています。

だから私はあなたのコードを嘲笑し、ローカルで実行しました。今、私はあなたがやろうとしていることを見ています。あなたの質問には2つの部分があります。質問の説明の名前が不適切だと思います。説明はクリック可能なリストビュー項目に焦点を当てているようですが、要約は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

2 番目の部分をクリックするとどうなるか。その一部は setOnItemClickListener の実装に送られ、2 番目の部分は新しいリンクを作成してクリックするとコンテンツが返される JSON です。ArrayList<HashMap<String, String>> LeaguesList; を返しています。これは非常に制限されているようですが、JSONArray 自体または ArrayList<HashMap<String,JSONObject>> を返さないのはなぜですか。ここで、ID が唯一のものでない限り、キーとして ID と後で使用できる JSONObject のすべての要素がマップに含まれています。に興味がある?

Android シミュレーターは手元にありませんが、JSON パーサーについて何か助けが必要な場合はお知らせください。

これは私がそれが機能していると想像する方法です.onclickイベントはから新しいURLを構築します

        public static String PATTERN =
          "http://api.pathofexile.com/leagues/" + ID_TOKEN +
          "?ladder=1&ladderOffset=1&ladderLimit=2";

渡された URL でエンコードされた ID (例: Default, Feb 15 Solo HC Race) を使用し、GetJSONTask.doInBackGround タスクを呼び出して新しい JSON 配列を取得します。

于 2013-02-12T00:03:08.403 に答える