📜  Android 中的二维 RecyclerView 示例

📅  最后修改于: 2022-05-13 01:54:27.876000             🧑  作者: Mango

Android 中的二维 RecyclerView 示例

在许多情况下,我们必须以这样的方式显示可水平滚动的列表,即我们还必须在其上显示标题以指示列表属于哪个类别。因此,为此,我们必须在我们的应用程序中创建一个二维 RecyclerView。在本文中,我们将看看在我们的应用程序中创建一个 2 维 RecyclerView。

我们将在本文中构建什么?

我们将构建一个简单的应用程序,我们将在其中显示两个 RecyclerView。一种是垂直的,一种是水平的。在我们的垂直 RecyclerView 中,我们将显示新闻类别,在该类别中,我们将以水平滚动格式显示属于该类别的不同新闻。下面给出了一个示例 GIF,以了解我们将在本文中做什么。请注意,我们将使用Java语言来实现这个项目。

Android 中的二维 RecyclerView 示例示例 GIF

分步实施

第 1 步:创建一个新项目

要在 Android Studio 中创建新项目,请参阅如何在 Android Studio 中创建/启动新项目。请注意,选择Java作为编程语言。



第 2 步:在 build.gradle 文件中添加以下依赖项并在清单文件中添加 Internet 权限

下面是我们将用来从 API 获取数据的 Volley 的依赖项。要添加此依赖项,请导航到app > Gradle Scripts > build.gradle(app)并在依赖项部分添加以下依赖项。我们已经使用 Picasso 依赖项从 URL 加载图像。

// below line is used for volley library
implementation ‘com.android.volley:volley:1.1.1’

// below line is used for image loading library
implementation ‘com.squareup.picasso:picasso:2.71828’

此外,在清单文件中添加互联网权限

 

步骤 3:使用 activity_main.xml 文件

导航到app > res > layout > activity_main.xml并将以下代码添加到该文件中。下面是activity_main.xml文件的代码。

XML


  
    
    
  


Java
public class NewsModal {
      
    // string for news title,image and description.
    private String newsTitle;
    private String newsDesc;
    private String newsImg;
  
    // on below line we have created a constructor.
    public NewsModal(String newsTitle, String newsDesc, String newsImg) {
        this.newsTitle = newsTitle;
        this.newsDesc = newsDesc;
        this.newsImg = newsImg;
    }
  
    public String getNewsImg() {
        return newsImg;
    }
  
    public void setNewsImg(String newsImg) {
        this.newsImg = newsImg;
    }
  
    // creating a getter and setter.
    public String getNewsTitle() {
        return newsTitle;
    }
  
    public void setNewsTitle(String newsTitle) {
        this.newsTitle = newsTitle;
    }
  
    public String getNewsDesc() {
        return newsDesc;
    }
  
    public void setNewsDesc(String newsDesc) {
        this.newsDesc = newsDesc;
    }
  
}


Java
import java.util.ArrayList;
  
public class CategoriesModal {
    // creating variable for our category, 
    // news array list and expanded boolean.
    private String newsCategory;
    private ArrayList newsModalArrayList;
  
    // creating a constructor.
    public CategoriesModal(String newsCategory, ArrayList newsModalArrayList) {
        this.newsCategory = newsCategory;
        this.newsModalArrayList = newsModalArrayList;
  
    }
  
    public String getNewsCategory() {
        return newsCategory;
    }
  
    public void setNewsCategory(String newsCategory) {
        this.newsCategory = newsCategory;
    }
  
    public ArrayList getNewsModalArrayList() {
        return newsModalArrayList;
    }
  
    public void setNewsModalArrayList(ArrayList newsModalArrayList) {
        this.newsModalArrayList = newsModalArrayList;
    }
}


XML


  
    
  
        
        
  
        
        
  
        
        
          
    
      


XML


  
    
  
        
        
  
        
  
            
            
  
        
  
    
      


Java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
  
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
  
import com.squareup.picasso.Picasso;
  
import java.util.ArrayList;
  
public class NewsRVAdapter extends RecyclerView.Adapter {
     
    // variables for array list and context.
    private ArrayList newsModalArrayList;
    private Context context;
  
    // creating a constructor.
    public NewsRVAdapter(ArrayList newsModalArrayList, Context context) {
        this.newsModalArrayList = newsModalArrayList;
        this.context = context;
    }
  
    @NonNull
    @Override
    public NewsRVAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        // passing our layout file for displaying our card item
        return new NewsRVAdapter.ViewHolder(LayoutInflater.from(context).inflate(R.layout.news_rv_item, parent, false));
  
    }
  
    @Override
    public void onBindViewHolder(@NonNull NewsRVAdapter.ViewHolder holder, int position) {
        // on below line we are setting data to our ui components.
        NewsModal modal = newsModalArrayList.get(position);
        holder.newsDescTV.setText(modal.getNewsDesc());
        holder.newsTitleTV.setText(modal.getNewsTitle());
        Picasso.get().load(modal.getNewsImg()).into(holder.newsIV);
    }
  
    @Override
    public int getItemCount() {
        // returning the size of array list
        return newsModalArrayList.size();
    }
  
    public class ViewHolder extends RecyclerView.ViewHolder {
        // creating variables for our text view.
        private TextView newsTitleTV, newsDescTV;
        private ImageView newsIV;
  
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            // initializing our text view
            newsIV = itemView.findViewById(R.id.idIVnews);
            newsTitleTV = itemView.findViewById(R.id.idTVNewsTitle);
            newsDescTV = itemView.findViewById(R.id.idTVNewsDesc);
        }
    }
}


Java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
  
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
  
import java.util.ArrayList;
  
public class CategoriesRVAdapter extends RecyclerView.Adapter {
      
    // variables for array list and context.
    private ArrayList categoriesModalArrayList;
    private Context context;
  
    // creating a constructor
    public CategoriesRVAdapter(ArrayList categoriesModalArrayList, Context context) {
        this.categoriesModalArrayList = categoriesModalArrayList;
        this.context = context;
    }
  
    @NonNull
    @Override
    public CategoriesRVAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        // passing our layout file for displaying our card item
        return new CategoriesRVAdapter.ViewHolder(LayoutInflater.from(context).inflate(R.layout.news_categories_rv_item, parent, false));
    }
  
    @Override
    public void onBindViewHolder(@NonNull CategoriesRVAdapter.ViewHolder holder, int position) {
        // setting data to our views on below line.
        CategoriesModal modal = categoriesModalArrayList.get(position);
        holder.categoryTV.setText(modal.getNewsCategory());
        NewsRVAdapter adapter = new NewsRVAdapter(modal.getNewsModalArrayList(), context);
        // below line is for setting a layout manager for our recycler view.
        // here we are creating horizontal list so we will provide orientation as vertical
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
        holder.newsRV.setLayoutManager(linearLayoutManager);
        holder.newsRV.setAdapter(adapter);
    }
  
    @Override
    public int getItemCount() {
        // returning the size of array list on below line.
        return categoriesModalArrayList.size();
    }
  
    public class ViewHolder extends RecyclerView.ViewHolder {
        // creating new variables for our views.
        private RecyclerView newsRV;
        private TextView categoryTV;
  
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            // initializing our views.
            categoryTV = itemView.findViewById(R.id.idTVCategory);
            newsRV = itemView.findViewById(R.id.idRVNews);
        }
    }
}


Java
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
  
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
  
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
  
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
  
import java.util.ArrayList;
  
public class MainActivity extends AppCompatActivity {
  
    // creating array list for our categories,
    // different news and category recycler view.
    private RecyclerView categoriesRV;
    private ArrayList categoriesModalArrayList;
    private ArrayList popularNewsArrayList, sportsNews, techNews;
    private CategoriesRVAdapter adapter;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        categoriesRV = findViewById(R.id.idRVCategories);
        LinearLayoutManager manager = new LinearLayoutManager(this);
        categoriesRV.setLayoutManager(manager);
        categoriesModalArrayList = new ArrayList<>();
        sportsNews = new ArrayList<>();
        techNews = new ArrayList<>();
        popularNewsArrayList = new ArrayList<>();
        adapter = new CategoriesRVAdapter(categoriesModalArrayList, this);
        categoriesRV.setAdapter(adapter);
        getPopularNews(popularNewsArrayList, categoriesModalArrayList);
        getSportsNews(categoriesModalArrayList, sportsNews);
        getTechnews(categoriesModalArrayList, techNews);
        adapter.notifyDataSetChanged();
  
    }
  
    private void getSportsNews(ArrayList categoriesModals, ArrayList sportsNews) {
        Log.e("TAG", "SIZE IS " + categoriesModalArrayList.size());
        String url = "https://jsonkeeper.com/b/U1BV";
        // creating a new variable for our request queue
        RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
        // in this case the data we are getting is in the form
        // of array so we are making a json array request.
        // below is the line where we are making an json array
        // request and then extracting data from each json object.
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener() {
            @Override
            public void onResponse(JSONObject response) {
                Log.e("TAG", "SPORTS RESPONSE IS " + response);
                try {
                    String category = response.getString("newsCategory");
                    JSONArray newsArray = response.getJSONArray("news");
                    for (int i = 0; i < newsArray.length(); i++) {
                        JSONObject newsObj = newsArray.getJSONObject(i);
                        String newsTitle = newsObj.getString("newsTitle");
                        String newsDesc = newsObj.getString("newsDesc");
                        String newsImg = newsObj.getString("newsImg");
                        sportsNews.add(new NewsModal(newsTitle, newsDesc, newsImg));
                    }
                    categoriesModals.add(new CategoriesModal(category, sportsNews));
                    Log.e("TAG", "MODALS = " + sportsNews.size() + "\n" + categoriesModals.size());
                    adapter.notifyDataSetChanged();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(MainActivity.this, "Fail to get Data", Toast.LENGTH_SHORT).show();
            }
        });
        queue.add(jsonObjectRequest);
    }
  
    private void getTechnews(ArrayList categoriesModals, ArrayList techNews) {
        // ArrayList categoriesModals = null;
        String url = "https://jsonkeeper.com/b/ZCWD";
        // creating a new variable for our request queue
        RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
        // in this case the data we are getting is in the form
        // of array so we are making a json array request.
        // below is the line where we are making an json array
        // request and then extracting data from each json object.
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener() {
            @Override
            public void onResponse(JSONObject response) {
                Log.e("TAG", "TECH RESPONSE IS " + response);
                try {
                    String category = response.getString("newsCategory");
                    JSONArray newsArray = response.getJSONArray("news");
                    for (int i = 0; i < newsArray.length(); i++) {
                        JSONObject newsObj = newsArray.getJSONObject(i);
                        String newsTitle = newsObj.getString("newsTitle");
                        String newsDesc = newsObj.getString("newsDesc");
                        String newsImg = newsObj.getString("newsImg");
                        techNews.add(new NewsModal(newsTitle, newsDesc, newsImg));
                    }
                    categoriesModals.add(new CategoriesModal(category, techNews));
                    adapter.notifyDataSetChanged();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(MainActivity.this, "Fail to get Data", Toast.LENGTH_SHORT).show();
            }
        });
        queue.add(jsonObjectRequest);
    }
  
    private void getPopularNews(ArrayList popularNewsArrayList, ArrayList categoriesModals) {
        String url = "https://jsonkeeper.com/b/ZCWD";
        // creating a new variable for our request queue
        RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
        // in this case the data we are getting is in the form
        // of array so we are making a json array request.
        // below is the line where we are making an json array
        // request and then extracting data from each json object.
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener() {
            @Override
            public void onResponse(JSONObject response) {
                Log.e("TAG", "POPULAR NEWS RESPONSE IS " + response);
                try {
                    String category = response.getString("newsCategory");
                    JSONArray newsArray = response.getJSONArray("news");
                    for (int i = 0; i < newsArray.length(); i++) {
                        JSONObject newsObj = newsArray.getJSONObject(i);
                        String newsTitle = newsObj.getString("newsTitle");
                        String newsDesc = newsObj.getString("newsDesc");
                        String newsImg = newsObj.getString("newsImg");
                        popularNewsArrayList.add(new NewsModal(newsTitle, newsDesc, newsImg));
                    }
                    categoriesModals.add(new CategoriesModal(category, popularNewsArrayList));
                    adapter.notifyDataSetChanged();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(MainActivity.this, "Fail to get Data", Toast.LENGTH_SHORT).show();
            }
        });
        queue.add(jsonObjectRequest);
    }
}


第 4 步:创建一个模态类来存储我们的新闻

导航到应用程序 > Java > 您应用程序的包名称 > 右键单击它 > 新建 > Java类并将其命名为NewsModal并将以下代码添加到其中。下面是NewsModal的代码。 Java文件。代码中添加了注释以更详细地理解代码。



Java

public class NewsModal {
      
    // string for news title,image and description.
    private String newsTitle;
    private String newsDesc;
    private String newsImg;
  
    // on below line we have created a constructor.
    public NewsModal(String newsTitle, String newsDesc, String newsImg) {
        this.newsTitle = newsTitle;
        this.newsDesc = newsDesc;
        this.newsImg = newsImg;
    }
  
    public String getNewsImg() {
        return newsImg;
    }
  
    public void setNewsImg(String newsImg) {
        this.newsImg = newsImg;
    }
  
    // creating a getter and setter.
    public String getNewsTitle() {
        return newsTitle;
    }
  
    public void setNewsTitle(String newsTitle) {
        this.newsTitle = newsTitle;
    }
  
    public String getNewsDesc() {
        return newsDesc;
    }
  
    public void setNewsDesc(String newsDesc) {
        this.newsDesc = newsDesc;
    }
  
}

第 5 步:创建一个模态类来存储我们的新闻类别

同样,创建另一个Java类并将其命名为CategoriesModal并向其添加以下代码。下面是CategoriesModal的代码。 Java文件。代码中添加了注释以更详细地理解代码。

Java

import java.util.ArrayList;
  
public class CategoriesModal {
    // creating variable for our category, 
    // news array list and expanded boolean.
    private String newsCategory;
    private ArrayList newsModalArrayList;
  
    // creating a constructor.
    public CategoriesModal(String newsCategory, ArrayList newsModalArrayList) {
        this.newsCategory = newsCategory;
        this.newsModalArrayList = newsModalArrayList;
  
    }
  
    public String getNewsCategory() {
        return newsCategory;
    }
  
    public void setNewsCategory(String newsCategory) {
        this.newsCategory = newsCategory;
    }
  
    public ArrayList getNewsModalArrayList() {
        return newsModalArrayList;
    }
  
    public void setNewsModalArrayList(ArrayList newsModalArrayList) {
        this.newsModalArrayList = newsModalArrayList;
    }
}

第 6 步:为我们的新闻项目创建布局文件

导航到应用程序 > res > 布局 > 右键单击它 > 新建 > 布局资源文件并将其命名为news_rv_item并将以下代码添加到其中。下面是news_rv_item.xml文件的代码

XML



  
    
  
        
        
  
        
        
  
        
        
          
    
      

步骤 7:为新闻类别创建新的布局文件

同样,创建另一个布局资源文件并将其命名为news_categories_rv_item并将以下代码添加到其中。下面是news_categories_rv_item.xml文件的代码

XML





  
    
  
        
        
  
        
  
            
            
  
        
  
    
      

第八步:新建一个Adapter类,用于在新闻RecyclerView中设置数据

创建另一个新的Java类并将其命名为NewsRVAdapter并向其添加以下代码。下面是NewsRVAdapter的代码。 Java文件。代码中添加了注释以更详细地理解代码。

Java

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
  
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
  
import com.squareup.picasso.Picasso;
  
import java.util.ArrayList;
  
public class NewsRVAdapter extends RecyclerView.Adapter {
     
    // variables for array list and context.
    private ArrayList newsModalArrayList;
    private Context context;
  
    // creating a constructor.
    public NewsRVAdapter(ArrayList newsModalArrayList, Context context) {
        this.newsModalArrayList = newsModalArrayList;
        this.context = context;
    }
  
    @NonNull
    @Override
    public NewsRVAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        // passing our layout file for displaying our card item
        return new NewsRVAdapter.ViewHolder(LayoutInflater.from(context).inflate(R.layout.news_rv_item, parent, false));
  
    }
  
    @Override
    public void onBindViewHolder(@NonNull NewsRVAdapter.ViewHolder holder, int position) {
        // on below line we are setting data to our ui components.
        NewsModal modal = newsModalArrayList.get(position);
        holder.newsDescTV.setText(modal.getNewsDesc());
        holder.newsTitleTV.setText(modal.getNewsTitle());
        Picasso.get().load(modal.getNewsImg()).into(holder.newsIV);
    }
  
    @Override
    public int getItemCount() {
        // returning the size of array list
        return newsModalArrayList.size();
    }
  
    public class ViewHolder extends RecyclerView.ViewHolder {
        // creating variables for our text view.
        private TextView newsTitleTV, newsDescTV;
        private ImageView newsIV;
  
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            // initializing our text view
            newsIV = itemView.findViewById(R.id.idIVnews);
            newsTitleTV = itemView.findViewById(R.id.idTVNewsTitle);
            newsDescTV = itemView.findViewById(R.id.idTVNewsDesc);
        }
    }
}

第 9 步:为我们的类别 RecyclerView 创建一个适配器类

同样,创建另一个Java类,将其命名为CategoriesRVAdapter 并将以下代码添加到其中。下面是CategoriesRVAdapter的代码。 Java文件。代码中添加了注释以更详细地理解代码。

Java

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
  
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
  
import java.util.ArrayList;
  
public class CategoriesRVAdapter extends RecyclerView.Adapter {
      
    // variables for array list and context.
    private ArrayList categoriesModalArrayList;
    private Context context;
  
    // creating a constructor
    public CategoriesRVAdapter(ArrayList categoriesModalArrayList, Context context) {
        this.categoriesModalArrayList = categoriesModalArrayList;
        this.context = context;
    }
  
    @NonNull
    @Override
    public CategoriesRVAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        // passing our layout file for displaying our card item
        return new CategoriesRVAdapter.ViewHolder(LayoutInflater.from(context).inflate(R.layout.news_categories_rv_item, parent, false));
    }
  
    @Override
    public void onBindViewHolder(@NonNull CategoriesRVAdapter.ViewHolder holder, int position) {
        // setting data to our views on below line.
        CategoriesModal modal = categoriesModalArrayList.get(position);
        holder.categoryTV.setText(modal.getNewsCategory());
        NewsRVAdapter adapter = new NewsRVAdapter(modal.getNewsModalArrayList(), context);
        // below line is for setting a layout manager for our recycler view.
        // here we are creating horizontal list so we will provide orientation as vertical
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
        holder.newsRV.setLayoutManager(linearLayoutManager);
        holder.newsRV.setAdapter(adapter);
    }
  
    @Override
    public int getItemCount() {
        // returning the size of array list on below line.
        return categoriesModalArrayList.size();
    }
  
    public class ViewHolder extends RecyclerView.ViewHolder {
        // creating new variables for our views.
        private RecyclerView newsRV;
        private TextView categoryTV;
  
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            // initializing our views.
            categoryTV = itemView.findViewById(R.id.idTVCategory);
            newsRV = itemView.findViewById(R.id.idRVNews);
        }
    }
}

第 10 步:使用MainActivity。 Java文件

转到主活动。 Java文件,参考如下代码。下面是MainActivity的代码。 Java文件。代码中添加了注释以更详细地理解代码。

Java

import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
  
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
  
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
  
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
  
import java.util.ArrayList;
  
public class MainActivity extends AppCompatActivity {
  
    // creating array list for our categories,
    // different news and category recycler view.
    private RecyclerView categoriesRV;
    private ArrayList categoriesModalArrayList;
    private ArrayList popularNewsArrayList, sportsNews, techNews;
    private CategoriesRVAdapter adapter;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        categoriesRV = findViewById(R.id.idRVCategories);
        LinearLayoutManager manager = new LinearLayoutManager(this);
        categoriesRV.setLayoutManager(manager);
        categoriesModalArrayList = new ArrayList<>();
        sportsNews = new ArrayList<>();
        techNews = new ArrayList<>();
        popularNewsArrayList = new ArrayList<>();
        adapter = new CategoriesRVAdapter(categoriesModalArrayList, this);
        categoriesRV.setAdapter(adapter);
        getPopularNews(popularNewsArrayList, categoriesModalArrayList);
        getSportsNews(categoriesModalArrayList, sportsNews);
        getTechnews(categoriesModalArrayList, techNews);
        adapter.notifyDataSetChanged();
  
    }
  
    private void getSportsNews(ArrayList categoriesModals, ArrayList sportsNews) {
        Log.e("TAG", "SIZE IS " + categoriesModalArrayList.size());
        String url = "https://jsonkeeper.com/b/U1BV";
        // creating a new variable for our request queue
        RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
        // in this case the data we are getting is in the form
        // of array so we are making a json array request.
        // below is the line where we are making an json array
        // request and then extracting data from each json object.
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener() {
            @Override
            public void onResponse(JSONObject response) {
                Log.e("TAG", "SPORTS RESPONSE IS " + response);
                try {
                    String category = response.getString("newsCategory");
                    JSONArray newsArray = response.getJSONArray("news");
                    for (int i = 0; i < newsArray.length(); i++) {
                        JSONObject newsObj = newsArray.getJSONObject(i);
                        String newsTitle = newsObj.getString("newsTitle");
                        String newsDesc = newsObj.getString("newsDesc");
                        String newsImg = newsObj.getString("newsImg");
                        sportsNews.add(new NewsModal(newsTitle, newsDesc, newsImg));
                    }
                    categoriesModals.add(new CategoriesModal(category, sportsNews));
                    Log.e("TAG", "MODALS = " + sportsNews.size() + "\n" + categoriesModals.size());
                    adapter.notifyDataSetChanged();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(MainActivity.this, "Fail to get Data", Toast.LENGTH_SHORT).show();
            }
        });
        queue.add(jsonObjectRequest);
    }
  
    private void getTechnews(ArrayList categoriesModals, ArrayList techNews) {
        // ArrayList categoriesModals = null;
        String url = "https://jsonkeeper.com/b/ZCWD";
        // creating a new variable for our request queue
        RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
        // in this case the data we are getting is in the form
        // of array so we are making a json array request.
        // below is the line where we are making an json array
        // request and then extracting data from each json object.
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener() {
            @Override
            public void onResponse(JSONObject response) {
                Log.e("TAG", "TECH RESPONSE IS " + response);
                try {
                    String category = response.getString("newsCategory");
                    JSONArray newsArray = response.getJSONArray("news");
                    for (int i = 0; i < newsArray.length(); i++) {
                        JSONObject newsObj = newsArray.getJSONObject(i);
                        String newsTitle = newsObj.getString("newsTitle");
                        String newsDesc = newsObj.getString("newsDesc");
                        String newsImg = newsObj.getString("newsImg");
                        techNews.add(new NewsModal(newsTitle, newsDesc, newsImg));
                    }
                    categoriesModals.add(new CategoriesModal(category, techNews));
                    adapter.notifyDataSetChanged();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(MainActivity.this, "Fail to get Data", Toast.LENGTH_SHORT).show();
            }
        });
        queue.add(jsonObjectRequest);
    }
  
    private void getPopularNews(ArrayList popularNewsArrayList, ArrayList categoriesModals) {
        String url = "https://jsonkeeper.com/b/ZCWD";
        // creating a new variable for our request queue
        RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
        // in this case the data we are getting is in the form
        // of array so we are making a json array request.
        // below is the line where we are making an json array
        // request and then extracting data from each json object.
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener() {
            @Override
            public void onResponse(JSONObject response) {
                Log.e("TAG", "POPULAR NEWS RESPONSE IS " + response);
                try {
                    String category = response.getString("newsCategory");
                    JSONArray newsArray = response.getJSONArray("news");
                    for (int i = 0; i < newsArray.length(); i++) {
                        JSONObject newsObj = newsArray.getJSONObject(i);
                        String newsTitle = newsObj.getString("newsTitle");
                        String newsDesc = newsObj.getString("newsDesc");
                        String newsImg = newsObj.getString("newsImg");
                        popularNewsArrayList.add(new NewsModal(newsTitle, newsDesc, newsImg));
                    }
                    categoriesModals.add(new CategoriesModal(category, popularNewsArrayList));
                    adapter.notifyDataSetChanged();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(MainActivity.this, "Fail to get Data", Toast.LENGTH_SHORT).show();
            }
        });
        queue.add(jsonObjectRequest);
    }
}

现在运行您的应用程序并查看应用程序的输出。

输出: