簡體   English   中英

如何發送多個Json請求並使用數據填充ReyclerView

[英]How to send multiple Json request and populate ReyclerView with the data

我正在練習為wordpress博客構建一個android應用程序,而我基本上想要做的是fetech帖子標題及其作者。 我能夠毫不費力地獲得並顯示帖子標題,但令人頭痛的是帖子作者。

這是json https://hmn.md/wp-json/wp/v2/posts的鏈接

這是我的密碼

PostItems

public class PostItems implements Parcelable {
    private String post_title;
    private String post_author;

    public String getPost_title() {
        return post_title;
    }

    public void setPost_title(String post_title) {
        this.post_title = post_title;
    }



    public String getPost_author() {
        return post_author;
    }

    public void setPost_author(String post_author) {
        this.post_author = post_author;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.post_title);
        dest.writeString(this.post_author);
    }

    public PostItems() {
    }

    protected PostItems(Parcel in) {
        this.post_title = in.readString();
        this.post_author = in.readString();
    }

    public static final Parcelable.Creator<PostItems> CREATOR = new Parcelable.Creator<PostItems>() {
        @Override
        public PostItems createFromParcel(Parcel source) {
            return new PostItems(source);
        }

        @Override
        public PostItems[] newArray(int size) {
            return new PostItems[size];
        }
    };
}

帖子列表的一部分

...
private void getData(){
         Log.d(TAG, "getData called");
         final ProDialoFrag dialoFrag = ProDialoFrag.newInstance();
         dialoFrag.show(getFragmentManager(), "fragmentDialog");


         //Creating a json request
         jsonArrayRequest = new JsonArrayRequest(GET_URL,
                 new Response.Listener<JSONArray>() {
                     @Override
                     public void onResponse(JSONArray response) {
                         Log.d(TAG, "onResponse called");
                         //Dismissing the progress dialog
                         if (dialoFrag != null ) {
                             dialoFrag.dismiss();
                         }
                         //calling method to parse json array
                         parseData(response);

                     }
                 },
                 new Response.ErrorListener() {
                     @Override
                     public void onErrorResponse(VolleyError error) {
                         if (dialoFrag != null) {
                             dialoFrag.dismiss();
                         }
                         if (sthWrongAlert != null) {
                             sthWrongAlert.show();
                         }

                     }
                 }) {

         };

         //Creating request queue
         RequestQueue requestQueue = Volley.newRequestQueue(getActivity());

         //Adding request to the queue
         requestQueue.add(jsonArrayRequest);

     }

     //This method will parse json data
     private void parseData(JSONArray array){
         Log.d(TAG, "Parsing array");

         mPostItemsList.clear();


         for(int i = 0; i<array.length(); i++) {
             PostItems postItem = new PostItems();
             JSONObject jsonObject = null;
             try {
                 jsonObject = array.getJSONObject(i);

                 JSONObject postTitle = jsonObject.getJSONObject("title");
                 postItem.setPost_title(postTitle.getString("rendered"));

                 JSONObject links = jsonObject.getJSONObject("_links");
                 JSONArray authorLink = links.getJSONArray("author");
                 String authorhref = authorLink.getJSONObject(0).getString("name")



                 postItem.setPostId(jsonObject.getString("link"));
             } catch (JSONException w) {
                 w.printStackTrace();
                 //Toast.makeText(this, "Error in parsing Json", Toast.LENGTH_LONG).show();
             }

             mPostItemsList.add(postItem);

         }
         adapter.notifyItemRangeChanged(0, adapter.getItemCount());


     }

PostAdapter

      public class PostAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{


     private static Context mContext;


     //List of posts
     private List<PostItems> mPostItems;

     private final int VIEW_ITEM = 0;
     private final int VIEW_PROG = 1;

     private int lastPosition = -1;


    public PostAdapter(List<PostItems> postItems, Context context) {
        super();

        //Getting all posts
        this.mPostItems = postItems;
        this.mContext = context;
    }


     @Override
     public int getItemViewType(int position) {
         if (isPositionItem(position))
             return VIEW_ITEM;
         return VIEW_PROG;
     }

     private boolean isPositionItem(int position) {
        return position != getItemCount()-1;
     }



     @Override
     public RecyclerView.ViewHolder  onCreateViewHolder (ViewGroup parent, int viewType) {
         if (viewType == VIEW_ITEM) {
             View v =  LayoutInflater.from(parent.getContext())
                     .inflate(R.layout.post_summ, parent, false);
             return new CardDetails(v);
         } else if (viewType == VIEW_PROG){
             View v = LayoutInflater.from(parent.getContext())
                     .inflate(R.layout.recyclerfooter, parent, false);
             return new ProgressViewHolder(v);
         }

         return null;
     }



     @Override
     public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

         if (holder instanceof CardDetails) {
             final PostItems postList = mPostItems.get(position);

             ((CardDetails) holder).postTitle.setText(Html.fromHtml(postList.getPost_title()));
             ((CardDetails) holder).postAuthor.setText(postList.getPost_author());


         } else {
             ((ProgressViewHolder) holder).progressBar.setIndeterminate(true);
         }


     }

     @Override
     public int getItemCount(){
         //Return the number of items in the data set
         return mPostItems.size();
     }


     public class CardDetails extends RecyclerView.ViewHolder implements View.OnClickListener {
         public TextView postTitle, postAuthor;

         public CardDetails (final View postView) {
             super(postView);
             postTitle = (TextView) postView.findViewById(R.id.post_title);
             postAuthor = (TextView) postView.findViewById(R.id.post_author);
         }

     }

     public  class ProgressViewHolder extends RecyclerView.ViewHolder{
         ProgressBar progressBar;
         public ProgressViewHolder(View footerView){
             super(footerView);
             progressBar = (ProgressBar) footerView.findViewById(R.id.progress_load);
             progressBar.setVisibility(View.VISIBLE);
         }

     }


 }

我當前的解決方案

 private void parseData(JSONArray array){
         Log.d(TAG, "Parsing array");


         for(int i = 0; i<array.length(); i++) {
             JSONObject jsonObject;
             try {
                 jsonObject = array.getJSONObject(i);

                 JSONObject postTitle = jsonObject.getJSONObject("title");
                 String postT = postTitle.getString("rendered");
                 mPostTitle = postT;


                 JSONObject links = jsonObject.getJSONObject("_links");
                 JSONArray authorLink = links.getJSONArray("author");
                 authorhref = authorLink.getJSONObject(0).getString("href");


                 getAuthor();

             } catch (JSONException w) {
                 w.printStackTrace();
                 //Toast.makeText(this, "Error in parsing Json", Toast.LENGTH_LONG).show();
             }

         }


     }

     private void getAuthor() {
         Log.d(TAG, "getAuthor called");

         JsonObjectRequest authorRequest = new JsonObjectRequest(authorhref, null,
                 new Response.Listener<JSONObject>() {
                     @Override
                     public void onResponse(JSONObject response) {
                         Log.d(TAG, "onResponse called");
                         parseAuthor(response);
                     }
                 },
                 new Response.ErrorListener() {

                     @Override
                     public void onErrorResponse(VolleyError error) {

                     }
                 });

         authorRequest.setShouldCache(false);

         RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
         requestQueue.add(authorRequest);

     }

     private void parseAuthor (JSONObject object) {
         Log.d(TAG, "Parsing author");
         PostItems postItem = new PostItems();

         try {
             String authorname = object.getString("name");
             postItem.setPost_author(authorname);
             postItem.setPost_title(mPostTitle);
         } catch (JSONException w) {
             w.printStackTrace();
         }
         mPostItemsList.add(postItem);
         adapter.notifyItemRangeChanged(0, adapter.getItemCount());
     }

我的解決方案存在的問題是所有帖子標題都相同。 為了進一步說明,作者名稱是他們應該使用的名稱,但是所有帖子標題都是最后一篇帖子的標題。

請知道我該如何解決?


應用克里斯·拉森的答案后

PostFragment的一部分

public class PostFragment extends Fragment{

    private List<PostItems> mPostItemsList = new ArrayList<>();
    ...
    // Nothing changed here, just added it so you will understand my code better
    ObservableRecyclerView recyclerView;
        private RecyclerView.Adapter adapter;
        LinearLayoutManager mLayoutManager;


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


        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            String title = getArguments().getString("title");
            // Inflate the layout for this fragment
            view = inflater.inflate(R.layout.fragment_post, container, false);
            //Initializing Views
            recyclerView = (ObservableRecyclerView) view.findViewById(R.id.post_recycler);
            recyclerView.setScrollViewCallbacks(this);
            mLayoutManager = new LinearLayoutManager(getActivity());
            recyclerView.setLayoutManager( mLayoutManager);
            ...

    //This method will get data from the web api
        private void getData(){
            Log.d(TAG, "getData called");
            final ProDialoFrag dialoFrag = ProDialoFrag.newInstance();
            dialoFrag.show(getFragmentManager(), "fragmentDialog");


            //Creating a json request
            jsonArrayRequest = new JsonArrayRequest(GET_URL,
                    new Response.Listener<JSONArray>() {
                        @Override
                        public void onResponse(JSONArray response) {
                            Log.d(TAG, "onResponse called");
                            //Dismissing the progress dialog
                            if (dialoFrag == null ) {
                                dialoFrag.dismiss();
                            }
                            //calling method to parse json array
                            parseData(response);

                        }
                    },
                    new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            if (dialoFrag != null) {
                                dialoFrag.dismiss();
                            }
                            if (sthWrongAlert != null) {
                                sthWrongAlert.show();
                            }

                        }
                    }) {
                n Response.success(resp.result, entry);
                }
            };

            //Creating request queue
            RequestQueue requestQueue = Volley.newRequestQueue(getActivity());

            //Adding request to the queue
            requestQueue.add(jsonArrayRequest);

        }

        //This method will parse json data
        private void parseData(JSONArray array){
            Log.d(TAG, "Parsing array");

            for(int i = 0; i<array.length(); i++) {

                JSONObject jsonObject;
                try {
                    jsonObject = array.getJSONObject(i);

                    JSONObject postTitle = jsonObject.getJSONObject("title");
                    String title = postTitle.getString("rendered"));

                    JSONObject links = jsonObject.getJSONObject("_links");
                    JSONArray authorLink = links.getJSONArray("author");
                    String authorhref = authorLink.getJSONObject(0).getString("href");

                    PostItems postItem = new PostItems();
                    postItem.setPost_title(title);
                    postItem.setPostAuthorUrl(authorhref);
                    mPostItemsList.add(postItem);

                    if (adapter.getAuthor(authorhref) == null) {
                        getAuthor(authorhref);
                    }
                } catch (JSONException w) {
                    w.printStackTrace();
                    //Toast.makeText(this, "Error in parsing Json", Toast.LENGTH_LONG).show();
                }



            }
            adapter.setPostItems(mPostItemsList);


        }

        private void getAuthor (String authorhref) {
            Log.d(TAG, "getAuthor called");

            JsonObjectRequest authorRequest = new JsonObjectRequest(authorhref, null,
                    new Response.Listener<JSONObject>() {
                        @Override
                        public void onResponse(JSONObject response) {
                            Log.d(TAG, "onResponse called");
                            parseAuthor(response);
                        }
                    },
                    new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            //Do nothing
                        }
                    });
            authorRequest.setShouldCache(false);
            RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
            requestQueue.add(authorRequest);
        }
        private void parseAuthor (JSONObject object) {
            Log.d(TAG, "Parsing auhor");
            try {
                JSONObject links = object.getJSONObject("_links");
                JSONArray self = links.getJSONArray("self");
                String href = self.getJSONObject(0).getString("href");

                String authorname = object.getString("name");
                adapter.putAuthor(href, authorname);
            } catch (JSONException w) {
                w.printStackTrace();
            }
        }

}

PostAdapter

public class PostAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{



    private ImageLoader imageLoader;
    private static Context mContext;


    //List of posts
    private List<PostItems> mPostItems;

    //authors by url
    private Map<String, String> mAuthorMap;

    //don't forget to initialoze in adapter constructor
    mAuthorMap = new HashMap<>();

    private final int VIEW_ITEM = 0;
    private final int VIEW_PROG = 1;

    private int lastPosition = -1;

    public void setPostItems(List<PostItems> postItems) {
        mPostItems = postItems;
        notifyDataSetChanged();
    }

    public void putAuthor(String url, String name) {
        mAuthorMap.put(url, name);
        notifyDataSetChanged();
    }

    public String getAuthor(String url) {
        return mAuthorMap.get(url);
    }


   public PostAdapter(List<PostItems> postItems, Context context) {
       super();

       //Getting all posts
       this.mPostItems = postItems;
       this.mContext = context;
   }


    @Override
    public int getItemViewType(int position) {
        if (isPositionItem(position))
            return VIEW_ITEM;
        return VIEW_PROG;
    }

    private boolean isPositionItem(int position) {
       return position != getItemCount()-1;
    }



    @Override
    public RecyclerView.ViewHolder  onCreateViewHolder (ViewGroup parent, int viewType) {
        if (viewType == VIEW_ITEM) {
            View v =  LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.post_summ, parent, false);
            return new CardDetails(v);
        } else if (viewType == VIEW_PROG){
            View v = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.recyclerfooter, parent, false);
            return new ProgressViewHolder(v);
        }

        return null;
    }



    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

        if (holder instanceof CardDetails) {
            final PostItems postList = mPostItems.get(position);
            ((CardDetails) holder).postTitle.setText(Html.fromHtml(postList.getPost_title()));

            String name = mAuthorMap.get(postList.getPostAuthorUrl());
            if (name != null) {
                ((CardDetails) holder).postAuthor.setText(name);
            }

        } else {
            ((ProgressViewHolder) holder).progressBar.setIndeterminate(true);
        }


    }


    @Override
    public int getItemCount(){
        //Return the number of items in the data set
        return mPostItems.size();
    }





    public class CardDetails extends RecyclerView.ViewHolder implements View.OnClickListener {
        public TextView postTitle, postAuthor;
        public ImageButton imageButton;

        public CardDetails (final View postView) {
            super(postView);
            postTitle = (TextView) postView

            .findViewById(R.id.post_title);
            postAuthor = (TextView) postView.findViewById(R.id.post_author);
        }


    }

    public  class ProgressViewHolder extends RecyclerView.ViewHolder{
        ProgressBar progressBar;
        public ProgressViewHolder(View footerView){
            super(footerView);
            progressBar = (ProgressBar) footerView.findViewById(R.id.progress_load);
            progressBar.setVisibility(View.VISIBLE);
        }

    }


}

我目前遇到的問題

  1. 在PostFragment中

    從行開始, if (adapter.getAuthor(authorhref) == null) { AS抱怨“無法解析方法getAuthor(Java.lang.String)

    adapter.setPostItems(mPostItemsList);adapter.setPostItems(mPostItemsList); 無法解析method'setPostItems(java.util.List.com.example.postapp.PostItems>)'

    adapter.putAuthor(href, authorname); 無法解析方法'putAuthor(java.lang.String)'

  2. 在PostAdapter中

mAuthorMap = new HashMap<>(); “未知類mAuthorMap”,以及在>位置中應有的 Identifier expected

方法setPostItemsputAuthorgetAuthor都說*方法從未使用過。

parseAuthor方法中,我並不太了解您要執行的操作,就好像您要獲取"self"數組一樣。 雖然我想要的是author數組。

如果您使用的是HttpURLConnectionAsyncTask ,則可以在一個后台操作中發出兩個請求,並且沒有問題。

但是,由於您似乎決心使用Volley,因此我建議您使用兩階段方法。 在階段1中,您分析帖子並保存帖子的作者url。 在階段2中,您將作者姓名添加到由url索引的地圖中。

  • PostItem包含作者網址而不是作者名稱:

     public class PostItem implements Parcelable { private String post_title; private String post_author_url; // also change all the getters/setters/parceling etc. } 

    (我將其設為PostItem(單數),因為它不是任何種類的同質集合。)

  • Map添加到適配器以包含作者名稱:

      /** posts, which contain author url */ private List<PostItem> mPostItems; /** authors by url */ private Map<String, String> mAuthorMap; 

    不要忘記在適配器構造函數中初始化作者映射

     public PostAdapter(List<PostItems> postItems, Context context) { super(); //Getting all posts this.mPostItems = postItems; this.mContext = context; this.mAuthorMap = new HashMap<>(); } 
  • 當您收到帖子時:

    1. 解析發布項目
    2. 使用標題和作者網址制作一個PostItem
    3. PostItem添加到適配器
    4. 向適配器詢問作者
    5. 如果找不到作者,請發起新的作者請求

        private void parseData(JSONArray array){ Log.d(TAG, "Parsing array"); // Collect all the PostItems and add to adapter all at once List<PostItem> postItems = new ArrayList<>(); for (int i = 0; i<array.length(); i++) { JSONObject jsonObject; try { jsonObject = array.getJSONObject(i); JSONObject postTitle = jsonObject.getJSONObject("title"); String title = postTitle.getString("rendered"); JSONObject links = jsonObject.getJSONObject("_links"); JSONArray authorLink = links.getJSONArray("author"); String authorhref = authorLink.getJSONObject(0).getString("href"); PostItem postItem = new PostItem(); postItem.setPostTitle(title); postItem.setPostAuthorUrl(authorhref); postItems.add(postItem); if (mAdapter.getAuthor(authorhref) == null) { getAuthor(authorhref); } } catch (JSONException w) { w.printStackTrace(); //Toast.makeText(this, "Error in parsing Json", Toast.LENGTH_LONG).show(); } } mAdapter.setPostItems(postItems); } 
  • 注意,我將您的getAuthor方法更改為采用一個參數(而不使用成員變量):

      private void getAuthor(String authorhref) { ... 
  • 收到作者后,將其添加到適配器

      private void parseAuthor (JSONObject object) { Log.d(TAG, "Parsing author"); try { JSONObject links = jsonObject.getJSONObject("_links"); JSONArray self = links.getJSONArray("self"); String href = authorLink.getJSONObject(0).getString("href"); String authorname = object.getString("name"); mAdapter.putAuthor(href, name); } catch (JSONException w) { w.printStackTrace(); } } 
  • 現在,這里是新的適配器方法:

      public void setPostItems(List<PostItem> postItems) { mPostItems = postItems; notifyDataSetChanged(); } public void putAuthor(String url, String name) { mAuthorMap.put(url, name); notifyDataSetChanged(); } public String getAuthor(String url) { return mAuthorMap.get(url); } 
  • onBindViewHolder就是它們的結合之處:

      @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder instanceof CardDetails) { final PostItem postItem = mPostItems.get(position); ((CardDetails) holder).postTitle.setText(Html.fromHtml(postItem.getPostTitle())); String name = mAuthorMap.get(postItem.getPostAuthorUrl()); if (name != null) { ((CardDetails) holder).postAuthor.setText(name); } // don't worry if author name is null, when it's retrieved // the adapter will be notified to refresh the list } else { ((ProgressViewHolder) holder).progressBar.setIndeterminate(true); } } 

編輯:以多種方式獲取作者網址,而無需解析作者JSON-> _links-> self [0]-> href

        // notice that authorhref is final
        private void getAuthor (final String authorhref) {
            Log.d(TAG, "getAuthor called");

            JsonObjectRequest authorRequest = new JsonObjectRequest(authorhref, null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        Log.d(TAG, "onResponse called");
                        parseAuthor(authorhref, response);  // pass authorhref with response
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        //Do nothing
                    }
                });
                authorRequest.setShouldCache(false);
                RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
                requestQueue.add(authorRequest);
            }

            private void parseAuthor (String authorhref, JSONObject object) {

                Log.d(TAG, "Parsing author");
                try {
                    String authorname = object.getString("name");
                    mAdapter.putAuthor(authorhref, name);

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

            }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM