【问题标题】:Put JSON array data in Hashmap and pass it through Intent Extra将 JSON 数组数据放入 Hashmap 中,通过 Intent Extra 传递
【发布时间】:2014-08-26 12:39:39
【问题描述】:

在我的应用程序中,我通过查找“findviewByid”成功实现了通过 Intent 将 JSON 对象传递给新活动。

现在这是一款餐厅查找器应用,每家餐厅都有几张菜单照片。我在 stackoverflow 上到处寻找类似的东西,但无法实现。

这是我的 JSON 文件的一部分:

[
{
login_id: "6",

name: "Urban Spice",

location: "banani",

latitude: "23.790327",

longitude: "90.409007",

address: "House- 119, Road-11, Block-E, Banani",
rating: "4.00",

costfortwopeople: "0",

openingclosingtime: "",

type: "restaurant,ice cream parlour",

perks: "kids zone,home delivery,catering",

cuisine: "indian,indonesian",

phone: "01777899901,2,3,9862672",

image: - [

"http://www.petuuk.com/restaurant_images/img_2146.jpg",

"http://www.petuuk.com/restaurant_images/img_2147.jpg"
],

menu: - [

"http://www.petuuk.com/restaurant_images/.jpg",
"http://www.petuuk.com/restaurant_images/.jpg",
"http://www.petuuk.com/restaurant_images/.jpg",
"http://www.petuuk.com/restaurant_images/.jpg",
"http://www.petuuk.com/restaurant_images/.jpg",
"http://www.petuuk.com/restaurant_images/.jpg",
"http://www.petuuk.com/restaurant_images/.jpg",
"http://www.petuuk.com/restaurant_images/.jpg"
]
},

 {

login_id: "7",

name: "The Sky Room Dining",

location: "banani",

latitude: "23.793972",

longitude: "90.403190",

address: "ABC House, 12th Floor, 8 Kemal Ataturk Avenue, Banani",

rating: "4.00",

costfortwopeople: "0",

openingclosingtime: "",

type: "restaurant",

perks: "rooftop view,catering",

cuisine: "thai,indian",

phone: "01675019211,9822017",

image: - [
"http://www.petuuk.com/restaurant_images/img_2204.jpg",
"http://www.petuuk.com/restaurant_images/img_2205.jpg",
"http://www.petuuk.com/restaurant_images/img_2206.jpg"
],  etc..................................................................

我很难从上面的 JSON 输出中检索 JSON 数组“菜单”和“图像”。我能够检索其他 JSON 对象,例如 login_id、名称、位置等。

我在这里尝试实现的主要目标是,在 Listview 中加载所有数据,用户可以在其中搜索餐厅,然后当用户点击特定餐厅时,所有加载的数据都应该进入“Intent .putExtra" 用于在新活动的完整餐厅资料视图中查看。

这些是我需要帮助的“SeachAll”活动的一部分。这是用于从 JSON 文件中检索数据的 for 循环。我需要帮助从“图像”和“菜单”中检索数据,然后将其放入我的哈希图中。

 protected String doInBackground(String... arg) {
        //building parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();

        //Getting JSON from URL
        String json = jsonParser.makeHttpRequest(URL_RESTAURANT_LIST, "GET", params);

        //Log Cat Response Check
        Log.d("Areas JSON: ", "> " + json);

        try {
            restaurants = new JSONArray(json);

            if (restaurants != null) {
                //loop through all restaurants
                for (int i = 0; i < restaurants.length(); i++) {
                    JSONObject c = restaurants.getJSONObject(i);

                    //Storing each json  object in the variable.
                    String id = c.getString(TAG_ID);
                    String name = c.getString(TAG_NAME);
                    String location = c.getString(TAG_LOCATION);
                    String rating = c.getString(TAG_RATING);`  HashMap<String, String>  map = new HashMap<String, String>();

                    //adding each child node to Hashmap key
                    map.put(TAG_ID, id);
                    map.put(TAG_NAME, name);
                    map.put(TAG_LOCATION, location);
                    map.put(TAG_RATING, rating);


                    //adding HashList to ArrayList
                    restaurant_list.add(map);
                }

            }
        } catch (JSONException e) {
            e.printStackTrace();
        }`

这是我的 onItemClick。在放置数组时需要帮助,我不知道是否可以像我在下面做的 json 对象一样传递 json 数组。

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

            Intent intent = new Intent(getApplicationContext(), RestaurantProfile.class);
            String loginId = ((TextView) view.
                    findViewById(R.id.login_id)).
                    getText().toString();

            String res_name = ((TextView) view.
                    findViewById(R.id.restaurant_name)).
                    getText().toString();


            intent.putExtra(TAG_ID, loginId);
            intent.putExtra(TAG_NAME, res_name);

            startActivity(intent);


        }
    });

简而言之,我需要两件事上的帮助,

1.从 JSON 文件中检索 JSON 数组“图像”和“菜单”URL,并将其放入 Hashmap 中。

2。将此数据放入我的 Intent 以传递给新活动。

这是我的“SearchAll”活动的完整代码。

public class SearchAll extends ListActivity {

ConnectionDetector cd;
AlertDialogManager alert = new AlertDialogManager();

//Progress Dialog
private ProgressDialog pDialog;

//make json parser Object
JSONParser jsonParser = new JSONParser();

ArrayList<HashMap<String, String>> restaurant_list;

//Restaurant Json array
JSONArray restaurants = null;

private static final String URL_RESTAURANT_LIST 
  = "http://www.petuuk.com/android/allRestaurantList2.php";

//all JSON Node Names
private static final String TAG_ID = "login_id";
private static final String TAG_NAME = "name";
private static final String TAG_LOCATION = "location";
private static final String TAG_LAT = "lattitude";
private static final String TAG_LONG = "longitude";
private static final String TAG_ADDRESS = "address";
private static final String TAG_COST_2 = "costfortwopeople";
private static final String TAG_TYPE = "type";
private static final String TAG_PERKS = "perks";
private static final String TAG_CUISINE = "cuisne";
private static final String TAG_PHONE = "phone";
private static final String TAG_RATING = "rating";
private static final String TAG_IMAGE = "image";
private static final String TAG_MENU = "menu";
private static final String TAG_TIMING = "openingclosingtime";

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

    cd = new ConnectionDetector(getApplicationContext());

    //Check for Internet Connection
    if (!cd.isConnectingToInternet()) {
        //Internet connection not present
        alert.showAlertDialog(SearchAll.this, "Internet Connection Error",
                "Please Check Your Internet Connection", false);
        //stop executing code by return
        return;
    }

    restaurant_list = new ArrayList<HashMap<String, String>>();



    //get ListView
    ListView lv = getListView();
    lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
   public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

      Intent intent = new Intent(getApplicationContext(), RestaurantProfile.class);
            String loginId = ((TextView) view.
                    findViewById(R.id.login_id)).
                    getText().toString();

            String res_name = ((TextView) view.
                    findViewById(R.id.restaurant_name)).
                    getText().toString();


            intent.putExtra(TAG_ID, loginId);
            intent.putExtra(TAG_NAME, res_name);

            startActivity(intent);


        }
    });

    lv.setOnScrollListener(new EndlessScrollListener() {
        @Override
        public void onLoadMore(int page, int totalItemsCount) {

        }
    });

    new LoadRestaurants().execute();



}


class LoadRestaurants extends AsyncTask<String, String, String> {

    //Show Progress Dialog
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(SearchAll.this);
        pDialog.setMessage("Loading All Restaurants...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(false);
        pDialog.show();
    }

    protected String doInBackground(String... arg) {
        //building parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();

        //Getting JSON from URL
        String json = jsonParser.makeHttpRequest(URL_RESTAURANT_LIST, "GET", params);

        //Log Cat Response Check
        Log.d("Areas JSON: ", "> " + json);

        try {
            restaurants = new JSONArray(json);

            if (restaurants != null) {
                //loop through all restaurants
                for (int i = 0; i < restaurants.length(); i++) {
                    JSONObject c = restaurants.getJSONObject(i);

                    //Storing each json  object in the variable.
                    String id = c.getString(TAG_ID);
                    String name = c.getString(TAG_NAME);
                    String location = c.getString(TAG_LOCATION);
                    String rating = c.getString(TAG_RATING);
                    String address = c.getString(TAG_ADDRESS);
                    String latitude = c.getString(TAG_LAT);
                    String longitude = c.getString(TAG_LONG);
                    String costfor2 = c.getString(TAG_COST_2);
                    String timing = c.getString(TAG_TIMING);
                    String type = c.getString(TAG_TYPE);
                    String perks = c.getString(TAG_PERKS);
                    String cuisine = c.getString(TAG_CUISINE);
                    String phone = c.getString(TAG_PHONE);


                    JSONArray menuArray = c.getJSONArray("menu");
                    JSONArray imagesArray = c.getJSONArray("image");


                    //Creating New Hashmap
                    HashMap<String, String>  map = new HashMap<String, String>();

                    //adding each child node to Hashmap key
                    map.put(TAG_ID, id);
                    map.put(TAG_NAME, name);
                    map.put(TAG_LOCATION, location);
                    map.put(TAG_RATING, rating);
                    for(int m=0;m<menuArray.length();++m){
                        map.put("MENU_" + m,menuArray.getString(m));
                    }//menu for loop
                    map.put("TOTAL_MENU", menuArray.length());


              //      map.put(TAG_MENU, String.valueOf(menu));

                    //adding HashList to ArrayList
                    restaurant_list.add(map);
                }

            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;
    }

    protected void onPostExecute(String file_url) {

        //dismiss the dialog
        pDialog.dismiss();


        //Updating UI from the Background Thread
        runOnUiThread(new Runnable() {
            @Override
            public void run() {

                ListAdapter adapter = new SimpleAdapter(
                        SearchAll.this, restaurant_list,
                        R.layout.listview_restaurants, new String[]{
                        TAG_ID, TAG_NAME, TAG_LOCATION, TAG_RATING}, new int[]{
                  R.id.login_id, R.id.restaurant_name, R.id.location,  R.id.rating});

                setListAdapter(adapter);


            }
        });


    }
}

}

【问题讨论】:

  • 那么你在哪里有困难?解析时还是传递时?
  • 不知道要在“doInBackground”方法中解析什么代码,然后将其放入hashmap,然后再放入Intent extra。

标签: java android json android-intent arrays


【解决方案1】:

简而言之,您不会将所有数据从一个活动传递到另一个活动。您只需将餐厅 ID 传递给新的 Activity,它就会使用该 ID 来提取餐厅的数据。

您应该将您的餐厅列表视为 MVC 架构中的模型(一部分)。它应该与您的活动(即控制器)分开。模型是您的数据专家,它将您的数据保存在内存、文件或数据库中,并且它存在于任何特定活动的生命周期之外。您不会将模型从一个活动传递到另一个活动。创建 Activity 后,它会抓取 Model(如果 Model 是 Singleton)或将 Model 注入到该 Activity 中(依赖注入,我更喜欢的框架是 Dagger)。然后 Activity 可以从模型中请求任何特定数据并呈现其视图。它还可以观察模型中的任何进一步变化并相应地更新其视图。

【讨论】:

  • 但是这不会花费很多时间来加载餐厅吗?因为有很多餐厅 ID,它必须搜索它们?
  • 如果您能指出一些真正有帮助的教程,也请参考您的建议。
  • 将您的餐厅存储在 Map 中,键是餐厅 ID,值是 Restaurant 对象。使用 ID 从 Map 中获取 Restaurant 速度很快。
  • Google 可以为您提供大量 MVC 教程 :) 如果您喜欢阅读代码,这可能会有所帮助:github.com/github/android/blob/…
【解决方案2】:

不确定这是否正是您需要的,但您可能会从中得到一些想法

首先,从餐厅获取图像和菜单数组,你需要这个

在 for 循环中,您可以在其中获取 json 对象 (c)

JSONObject c = restaurants.getJSONObject(i);
JsonArray menuArray = c.getJsonArray("menu");
JsonArray imagesArray = c.getJsonArray("image");

您可以使用 for 循环在 menuArray 和 imagesArray 项之间循环

imagesArray.getString(index);

现在,由于您已将地图声明为 &lt; String, String &gt;,因此您不能在一个字符串中分配多个值(图像或菜单项),

所以要么你找到另一种方式来构建你的数据, 或创建另外 2 个地图,menuPam,imageMap,其中餐厅 ID 作为键,字符串作为菜单和图像条目的值。

在读取餐厅对象的 for 循环中:

for (int i = 0; i < restaurants.length(); i++) {
    :
    :
    map.put(TAG_ID, id);
    map.put(TAG_NAME, name);
    :
    :

    JsonArray menuArray = c.getJsonArray("menu");
    for(int m=0;m<menuArray.length();++m){
        menuMap.add(id,menuArray.getString(m));
    }//menu for loop

    //another for loop for imageArray...
}//end of restaurants loop

但是你必须将 menuMap 和 imageMap 添加到一个数组列表中,称为 menus、images...

为什么不创建一个对象来保存有关餐厅的所有信息

class restaurant{
private String name="", id =""....
//setters and getters ...

String menuItems[] = null;
String imageItems[] = null;

//setters getters for the arrays.
}

}

编辑: 此溶胶不需要新地图,只需将图像和菜单添加到同一张地图 使用动态键名

for(int m=0;m<menuArray.length();++m){
    map.add("MENU_" + m,menuArray.getString(m));
}//menu for loop
map.add("TOTAL_MENU", Integer.toString(menuArray.length()));

您可以使用上面的代码向地图添加菜单项 和图像一样,“IMAGE_”+m 和 TOTAL_IMAGES

现在在目标活动中,循环读取所有 IMAGE_n 和 MENU_n 从 0 到 TOTAL_IMAGES 和 TOTAL_MENU

【讨论】:

  • 所以我照你说的做了。你能编辑不需要的代码吗?我按照您在顶部所说的那样启动了 JSONArray,然后在地图中我按照编辑中的说明使用了您的代码。但我在最后一行“map.add(“TOTAL_MENU”,menuArray.length());“中遇到错误。它说在 hashmap 中放置 (String, java.lang.String) 不能应用于 (String, int)。我发布了我的完整搜索活动代码。请检查并提供帮助。
  • 是的,这是因为在 String 参数中添加了 Int,请将 menuArray.length() 替换为这个 Integer.toString(menuArray.length())
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 2012-12-29
  • 1970-01-01
  • 1970-01-01
  • 2014-12-27
  • 2013-02-18
  • 1970-01-01
相关资源
最近更新 更多