Извлечение определенных объектов JSON из определенного массива для добавления другого действия с помощью намерения в Android - PullRequest
0 голосов
/ 21 декабря 2018

Я создаю приложение новостной ленты и хочу, чтобы можно было извлекать информацию из определенного списка в другой макет, который отображает заголовок, источник, изображение и содержание списка новостей.На главной странице JSON заполнит представление списка заголовком, источником и изображением.Я отправил onItemClickListener, и когда я нажимаю на каждую запись, я хочу, чтобы она открыла эту запись в новом макете для отображения всего содержимого.У меня есть класс, созданный только для извлечения информации JSON, поэтому я не уверен, как использовать это в классе со слушателем onItemClick.Я понимаю putExtra, но я полностью потерян для ввода кода, чтобы передать то, что мне нужно.Ниже приведен код со страницы со списком, а также класс JsonQuery.Спасибо за любую помощь!

TopHeadlinesFragment.java

public class TopHeadlinesFragment extends Fragment
        implements LoaderManager.LoaderCallbacks<List<News>> {

    public static final String NEWS_FEED_URL =
            "https://newsapi.org/v2/top-headlines?country=us&apiKey=a3f791903c1a4163b223dd033563084b";

    private static final int NEWS_LOADER_ID = 1;
    private NewsAdapter mNewsAdapter;
    private NewsAdapterListing mNewsAdapterListing;


    public TopHeadlinesFragment(){
        // Required empty public constructor
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.news_list, container, false);

        mNewsAdapter = new NewsAdapter(getActivity(), new ArrayList<News>());

        ListView listView = rootView.findViewById(R.id.list);

        listView.setAdapter(mNewsAdapter);

        final LoaderManager loaderManager = getLoaderManager();
        loaderManager.initLoader(NEWS_LOADER_ID, null, this);

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                mNewsAdapterListing = new NewsAdapterListing(getActivity(), new ArrayList<News>());
                News currentNews = mNewsAdapterListing.getItem(position);
                Intent newsArticleDisplayIntent = new Intent(getActivity(), FullArticleListing.class);

                startActivity(newsArticleDisplayIntent);

            }
        });

        return rootView;
    }


    @Override
    public Loader<List<News>> onCreateLoader(int id, Bundle args) {
        return new NewsLoader(getActivity(), NEWS_FEED_URL);
    }

    @Override
    public void onLoadFinished(Loader<List<News>> loader, List<News> data) {
        mNewsAdapter.clear();

        if (data != null && !data.isEmpty()){
            mNewsAdapter.addAll(data);
        }
    }

    @Override
    public void onLoaderReset(Loader<List<News>> loader) {
        mNewsAdapter.clear();
    }

    public static class NewsLoader extends AsyncTaskLoader<List<News>> {
        private String[] mUrl;

        public NewsLoader(Context context, String... url) {
            super(context);
            mUrl = url;
        }

        @Override
        protected void onStartLoading() {
            forceLoad();
        }

        @Override
        public List<News> loadInBackground() {
            if (mUrl.length < 1 || mUrl[0] == null) {
                return null;
            }
            return JsonQueryUtils.fetchNewsData(mUrl[0]);
        }
    }
}

JsonQueryUtils.java

public class JsonQueryUtils {

    /** Contains networking and JSON parsing code **/

    private static final String LOG_TAG = "JsonQueryUtils";

    private JsonQueryUtils(){
    }

    /** Helper method to fetch news data and call networking code within method **/

    public static List<News> fetchNewsData(String requestUrl){
        URL url = createUrl(requestUrl);
        String jsonResponse = null;
        try{
            jsonResponse = makeHttpRequest(url);
        } catch (IOException e){
            Log.e(LOG_TAG, "Error closing input stream", e);
        }

        List<News> news = extractNews(jsonResponse);
        Log.i(LOG_TAG, "fetchNewsData initialized");
        return news;
    }

    private static List<News> extractNews (final String newsJSON) {
        if (TextUtils.isEmpty(newsJSON)) {
            return null;
        }

        List<News> news = new ArrayList<>();

        try {
            JSONObject jsonNewsObject = new JSONObject(newsJSON);
            JSONArray newsArray = jsonNewsObject.getJSONArray("articles");

            for (int i = 0; i < newsArray.length(); i++) {
                JSONObject currentNews = newsArray.getJSONObject(i);
                JSONObject source = currentNews.optJSONObject("source");

                String imageUrl = currentNews.getString("urlToImage");
                Bitmap newsImage = makeHttpRequest(imageUrl);

                String title = currentNews.getString("title");
                String sourceName = source.getString("name");
                String content = currentNews.getString("content");

                news.add(new News(newsImage, title, sourceName));

            }
        } catch (JSONException e) {
            e.printStackTrace();
            Log.e(LOG_TAG, "problem with parsing", e);
        } catch (IOException e){
            e.printStackTrace();
        }
        return news;
    }

    /**
     * Make an HTTP request to the given imageURL and return a Bitmap as the response.
     */
    private static Bitmap makeHttpRequest (String imageUrl) throws IOException {
        Bitmap newsImage = null;
        if (imageUrl == null){
            return newsImage;
        }

        URL url = createUrl(imageUrl);
        HttpURLConnection urlConnection = null;
        InputStream inputStream = null;
        try {
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.setDoInput(true);
            urlConnection.connect();
            if (urlConnection.getResponseCode() == 200) {
                inputStream = urlConnection.getInputStream();
                newsImage = BitmapFactory.decodeStream(inputStream);
            }

        } catch (IOException e) {
            Log.e(LOG_TAG, "Error reading bitmap input stream");
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
            if (inputStream != null) {
                inputStream.close();
            }
        }
        return newsImage;
    }



    /**
     * Make an HTTP request to the given URL and return a String as the response.
     */
    private static String makeHttpRequest(URL url) throws IOException {
        String jsonResponse = "";

        // If the URL is null, then return early.
        if (url == null) {
            return jsonResponse;
        }

        HttpURLConnection urlConnection = null;
        InputStream inputStream = null;
        try {
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setReadTimeout(10000 /* milliseconds */);
            urlConnection.setConnectTimeout(15000 /* milliseconds */);
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();

            // If the request was successful (response code 200),
            // then read the input stream and parse the response.
            if (urlConnection.getResponseCode() == 200) {
                inputStream = urlConnection.getInputStream();
                jsonResponse = readFromStream(inputStream);
            } else {
                Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
            }
        } catch (IOException e) {
            Log.e(LOG_TAG, "Problem reading input stream.", e);
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
            if (inputStream != null) {
                inputStream.close();
            }
        }
        return jsonResponse;
    }

    /**
     * Convert the {@link InputStream} into a String which contains the
     * whole JSON response from the server.
     */
    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();
    }

    /** Helper method to create {@link} URL object **/
    private static final URL createUrl(String stringUrl) {
        URL url = null;
        try {
            url = new URL(stringUrl);
        } catch (MalformedURLException e) {
            Log.e(LOG_TAG, "createUrl: error", e);
        }
        return url;
    }


}

1 Ответ

0 голосов
/ 21 декабря 2018

Я заметил, что вы извлекли 'content' из ответа JSON, но я нигде не вижу, чтобы переменная 'content' использовалась для создания объекта News ... Есть ли причина, по которой вы не включаете его в объект News?

Относительно отправки объекта News к следующему действию, есть несколько способов достичь этого.

  1. Используйте Parcelable, чтобы отправить новости для вашего следующего действия / фрагмента.Для более подробной информации, нажмите здесь .

  2. Установите библиотеку GSON и просто преобразуйте ваш объект News в строку Json.Поместите эту строку в ваше намерение в качестве дополнительного и начните следующее действие.Получите данные, вызвав new Gson (). FromJson ().Однако, поскольку ваш объект имеет поле Bitmap, это не будет подходящим подходом.Для получения более подробной информации нажмите здесь

  3. Это то, что я бы сделал, если бы API позволял: просто позвоните в запрос API еще раз для получения дополнительной информации о текущем канале.,Например, вы можете выполнить другой запрос API в вашей FullArticleActivity вместе с идентификатором, который связан с выбранным каналом.(т. е. пользователь щелкает канал с идентификатором № 3 -> передать идентификатор (целое число) следующей операции в качестве дополнительного -> получить идентификатор из дополнительных данных и сделать еще один запрос API, используя идентификатор для получения полной информации о статье.) Однакоэто возможно только тогда, когда ваш API предоставляет такой метод GET.

  4. Создайте синглтон и дайте ему временно удерживать ваш объект.Получите объект в следующем действии, просто вызвав что-то вроде YourSingletonClass.getInstance (). GetNews ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...