为每个片段更改 QueryUtils 中的值

Change value in QueryUtils for each fragment

如何从 Fragment 中更改 QueryUtils 文件中存在的 json 对象的索引值?

这部分就在这里:JSONObject currentDay = dayArray.getJSONObject(0);

我希望每个片段的索引值都发生变化,但我无法理解它。我尝试过意图并创建构造函数但失败了。

与现在一样,应用 'working' 所有片段都显示星期一的日程安排(JSON对象索引 0)。

QueryUtils.java

import android.text.TextUtils;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;


public final class QueryUtils {

    private static final String LOG_TAG = QueryUtils.class.getSimpleName();

    //makeHttpRequest constants
    private static final int READ_TIMEOUT = 10000 /* milliseconds */;
    private static final int CONNECT_TIMEOUT = 15000 /* milliseconds */;
    private static final int RESPONSE_CODE = 200 /*everything is OK*/;

    public QueryUtils() {
    }

    public static List<Day> fetchDayData(String requestUrl) {

        URL url = createUrl(requestUrl);

        String jsonResponse = null;
        try {
            jsonResponse = makeHttpRequest(url);
        } catch (IOException e) {
            Log.e(LOG_TAG, "Problem making the HTTP request.", e);
        }

        List<Day> days = extractFeatureFromJson(jsonResponse);

        return days;
    }

    private static URL createUrl(String stringUrl) {
        URL url = null;
        try {
            url = new URL(stringUrl);
        } catch (MalformedURLException e) {
            Log.e(LOG_TAG, "Problem building the URL ", e);
        }
        return url;
    }
    private static String makeHttpRequest(URL url) throws IOException {
        String jsonResponse = "";

        if (url == null) {
            return jsonResponse;
        }

        HttpURLConnection urlConnection = null;
        InputStream inputStream = null;

        try {
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setReadTimeout(READ_TIMEOUT);
            urlConnection.setConnectTimeout(CONNECT_TIMEOUT);
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();

            if (urlConnection.getResponseCode() == RESPONSE_CODE) {
                inputStream = urlConnection.getInputStream();
                jsonResponse = readFromStream(inputStream);
            } else {
                Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
            }
        } catch (IOException e) {
            Log.e(LOG_TAG, "Problem retrieving Berceni JSON results.", e);
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
            if (inputStream != null) {
                inputStream.close();
            }
        }
        return jsonResponse;
    }

    private static String readFromStream(InputStream inputStream) throws IOException {
        StringBuilder output = new StringBuilder();
        if (inputStream != null) {
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
            BufferedReader reader = new BufferedReader(inputStreamReader);
            String line = reader.readLine();
            while (line != null) {
                output.append(line);
                line = reader.readLine();
            }
        }
        return output.toString();
    }

    private static List<Day> extractFeatureFromJson(String dayJSON) {

        if (TextUtils.isEmpty(dayJSON)) {
            return null;
        }

        List<Day> days = new ArrayList<>();

        //Try to parse
        try {

            JSONObject baseJsonResponse = new JSONObject(dayJSON);

            JSONArray dayArray = baseJsonResponse.getJSONObject("schedule").getJSONArray("day");

            JSONObject currentDay = dayArray.getJSONObject(0);
            JSONArray getClasses = currentDay.getJSONArray("classes");

                for (int j = 0; j < getClasses.length(); j++) {
                    JSONObject currentClass = getClasses.getJSONObject(j);

                     String retrieveCourseTitle = currentClass.getString("class");
                     String retrieveCourseTime = currentClass.getString("time");
                     String retrieveCourseTrainer = currentClass.getString("trainer");
                     String retrieveCourseCancelState = currentClass.getString("canceled");

                     Day day = new Day(retrieveCourseTitle, retrieveCourseTime, retrieveCourseTrainer, retrieveCourseCancelState);
                     days.add(day);
                }

        } catch (JSONException e) {
            // If an error is thrown when executing any of the above statements in the "try" block,
            // catch the exception here, so the app doesn't crash. Print a log message
            // with the message from the exception.
            Log.e("QueryUtils", "Problem parsing JSON results", e);
        }

        return days;
    }

}

还有我的FragmentAdapter.java

import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

public class FragmentAdapter extends FragmentPagerAdapter {

    private Context mContext;

    public FragmentAdapter(Context context, FragmentManager fm) {
        super(fm);
        mContext = context;
    }

    @Override
    public Fragment getItem(int position) {
        if (position == 0) {
            return new MondayFragment();
        } else if (position == 1) {
            return new ThursdayFragment();
        } else if (position == 2) {
            return new WednesdayFragment();
        } else if (position == 3) {
            return new ThursdayFragment();
        } else if (position == 4) {
            return new FridayFragment();
        } else if (position == 5) {
            return new SaturdayFragment();
        } else {
            return new SundayFragment();
        }
    }

    /**
     * Return the total number of pages.
     */
    @Override
    public int getCount() {
        return 7;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        if (position == 0) {
            return mContext.getString(R.string.monday);
        } else if (position == 1) {
            return mContext.getString(R.string.tuesday);
        } else if (position == 2) {
            return mContext.getString(R.string.wednesday);
        } else if (position == 3) {
            return mContext.getString(R.string.thursday);
        } else if (position == 4) {
            return mContext.getString(R.string.friday);
        } else if (position == 5) {
            return mContext.getString(R.string.saturday);
        }   else {
            return mContext.getString(R.string.sunday);
        }
    }

}

JSON 样本响应

{  
   "schedule":{
      "day":[
         {  
            "id":"Monday",
            "classes":[
                {
                    "class" : "Class",
                    "time" : "00:00",
                    "trainer" : "Teacher",
                    "canceled" : ""
                },
                {
                    "class" : "Class",
                    "time" : "00:00",
                    "trainer" : "Teacher",
                    "canceled" : ""
                }
            ]
         }, 
         {  
            "id":"Tuesday",
            "classes":[
                {
                    "class" : "Class",
                    "time" : "00:00",
                    "trainer" : "Teacher",
                    "canceled" : ""
                },
                {
                    "class" : "Class",
                    "time" : "00:00",
                    "trainer" : "Teacher",
                    "canceled" : ""
                }
            ]
         }, 
         {  
            "id":"Wednesday",
            "classes":[
                {
                    "class" : "Class",
                    "time" : "00:00",
                    "trainer" : "Teacher",
                    "canceled" : ""
                }, 
                {
                    "class" : "Class",
                    "time" : "00:00",
                    "trainer" : "Teacher",
                    "canceled" : ""
                }
            ]
         },
         {  
            "id":"Thursday",
            "classes":[
                {
                    "class" : "Class",
                    "time" : "00:00",
                    "trainer" : "Teacher",
                    "canceled" : ""
                },
                {
                    "class" : "Class",
                    "time" : "00:00",
                    "trainer" : "Teacher",
                    "canceled" : ""
                }
            ]
         }, 
         {  
            "id":"Friday",
            "classes":[
                {
                    "class" : "Class",
                    "time" : "00:00",
                    "trainer" : "Teacher",
                    "canceled" : ""
                },
                {
                    "class" : "Class",
                    "time" : "00:00",
                    "trainer" : "Teacher",
                    "canceled" : ""
                }
            ]
         },
         {  
            "id":"Saturday",
            "classes":[
                {
                    "class" : "Class",
                    "time" : "00:00",
                    "trainer" : "Teacher",
                    "canceled" : ""
                }, 
                {
                    "class" : "Class",
                    "time" : "00:00",
                    "trainer" : "Teacher",
                    "canceled" : ""
                }
            ]
         }, 
         {  
            "id":"Sunday",
            "classes":[]
         }
      ]
   }
}

我不确定这一点,因为我从未使用过 FragmentPagerAdapter,但我想它在概念上可以像任何 Adapter 一样工作。

我在你的代码中注意到的是在你的代码中(见评论)

private static List<Day> extractFeatureFromJson(String dayJSON) {

    if (TextUtils.isEmpty(dayJSON)) {
        return null;
    }

    List<Day> days = new ArrayList<>();

    //Try to parse
    try {

        JSONObject baseJsonResponse = new JSONObject(dayJSON);

        JSONArray dayArray = baseJsonResponse.getJSONObject("schedule").getJSONArray("day");

        JSONObject currentDay = dayArray.getJSONObject(0); //<<<<<<HERE
        JSONArray getClasses = currentDay.getJSONArray("classes");

            for (int j = 0; j < getClasses.length(); j++) {
                JSONObject currentClass = getClasses.getJSONObject(j);

                 String retrieveCourseTitle = currentClass.getString("class");
                 String retrieveCourseTime = currentClass.getString("time");
                 String retrieveCourseTrainer = currentClass.getString("trainer");
                 String retrieveCourseCancelState = currentClass.getString("canceled");

                 Day day = new Day(retrieveCourseTitle, retrieveCourseTime, retrieveCourseTrainer, retrieveCourseCancelState);
                 days.add(day);
            }

    } catch (JSONException e) {
        // If an error is thrown when executing any of the above statements in the "try" block,
        // catch the exception here, so the app doesn't crash. Print a log message
        // with the message from the exception.
        Log.e("QueryUtils", "Problem parsing JSON results", e);
    }

    return days;
}

您正在为 JSONObject currentDay = dayArray.getJSONObject(0);

做 "extraction"

这意味着您的 List<Day> days 中只有一个 Day,即当天。假设您将这个 List 提供给您的适配器,只找到一个 Day,因此没有任何变化。

我建议你遍历所有的日子,将每一天附加到 List 上,像这样:

try{
    JSONObject baseJsonResponse = new JSONObject(dayJSON);
    JSONArray dayArray = baseJsonResponse.getJSONObject("schedule").getJSONArray("day");
    for (int i = 0; i<dayArray.length();i++){
        JSONObject currentDay = dayArray.getJSONObject(i);
        //the rest
    }
}catch(JSONException e){
    //etc
}

查看您的 POJO,这并不明确等于您的 JSON。

一天应声明为:

class Day {
    String id;
    List<ClassDetail> classes;
}

class ClassDetail {
    //all the details
}

我认为你误解了你的函数,下面的签名不太明确。

List<Day> extractFeatureFromJson(String dayJSON)

为了使其更具可读性,我建议改成:
(您可以使用哈希图 ):

HashMap<String, ClassDetail> parseScheduleJson(String scheduleJSON)

然后将每个 ClassDetail 添加到结果中

@Nullable
private static Map<String, List<ClassDetail>> parseScheduleJson(String scheduleJSON) {

    if (TextUtils.isEmpty(scheduleJSON)) {
        return null;
    }

    HashMap<String, List<ClassDetail>> result = new HashMap<>();

    try {
        JSONObject baseJsonResponse = new JSONObject(scheduleJSON);
        JSONArray dayArray = baseJsonResponse.getJSONObject("schedule").getJSONArray("day");

        for (int i = 0; i < dayArray.length(); i++) {
            ArrayList<ClassDetail> classes = new ArrayList<>();
            JSONObject currentDay = dayArray.getJSONObject(i);
            for (int j = 0; j < currentDay.getJSONArray("classes").length(); j++) {
                JSONObject currentClass = currentDay.getJSONArray("classes").getJSONObject(j);

                String retrieveCourseTitle = currentClass.getString("class");
                String retrieveCourseTime = currentClass.getString("time");
                String retrieveCourseTrainer = currentClass.getString("trainer");
                String retrieveCourseCancelState = currentClass.getString("canceled");

                classes.add(new ClassDetail(retrieveCourseTitle, retrieveCourseTime, retrieveCourseTrainer, retrieveCourseCancelState));
            }
            result.put(currentDay.getString("id"), classes);
        }

    } catch (JSONException e) {
        // If an error is thrown when executing any of the above statements in the "try" block,
        // catch the exception here, so the app doesn't crash. Print a log message
        // with the message from the exception.
        Log.e("QueryUtils", "Problem parsing JSON results", e);
        return null;
    }

    return result;
}

在此之后,您可以使用以下方式访问当天 类 的列表:

mymap.get("Monday");
mymap.get("Tuesday");
...
mymap.get("Sunday");

编辑:

恕我直言,您必须在 activity 中调用您的 dayloader,并将地图结果注入您的 FragmentPagerAdapter:

public FragmentAdapter(Context context, FragmentManager fm, Map<String, List<ClassDetail> schedule) {
    super(fm);
    mContext = context;
    mSchedule = schedule;
}

@Override
public Fragment getItem(int position) {
    if (position == 0) {
        return MondayFragment.newInstance(mSchedule.get("Monday"));
    //...
    //same for all conditions
    //...
    } else {
        return SundayFragment.newInstance(mSchedule.get("Sunday"));
    }
}

之后,当使用 newIntance pattern 时,您可以将片段声明为:

private List<ClassDetail> mClasses;

public static MondayClassDetailFragment newInstance(ArrayList<ClassDetail> classes){
    MondayClassDetailFragment myFragment = new MondayClassDetailFragment();

    Bundle args = new Bundle();
    args.putParcelableArrayList("classes", classes);
    myFragment.setArguments(args);

    return myFragment;
}

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mClasses = getArguments().getParcelableArrayList("classes");
}

PS:这几天手动发起http请求和解析一个json很浪费精力。我建议您查看图书馆以执行此操作,尤其是 retrofit 被广泛使用且有据可查的图书馆。

虽然@crgarridos 的答案可行,但我一直在想用最少的代码修改来实现我的目标的更快更简单的方法,因此:

我最终修改了 JSON API 并为 id 键创建了查询 url,这样我就可以查询这个: URL?id=monday.

接下来我只需要为我的每个片段添加一个 URI 构建器和 appendQueryParameter(key, value);