如何使用大型 json 数据填充 RecyclerView [重复]

Posted

技术标签:

【中文标题】如何使用大型 json 数据填充 RecyclerView [重复]【英文标题】:How to populate RecyclerView with large json data [duplicate] 【发布时间】:2017-11-17 10:51:09 【问题描述】:

我有一个返回 JSON 对象的 REST 方法,JSON 文件大小几乎重 7MB,并且有将近 4600 个 JSON 对象。我无法一次将整个数据解析到 recyclerView 中,因为它会导致 OutOfMemory 异常。

我尝试以两种方式实现它。一种是使用http://loopj.com/android-async-http/,但这种方法不适用于大块数据。第二种方法是使用 GSON 和 Volley 完成的。使用这种方法,我能够从 REST 方法中更快地获得响应,但我无法将其填充到 recyclerView 中。请检查我使用的代码。

我在这里面临的问题是 recyclerview 显示 ROLL_NUM、CURRENT_CLASS、STUDENT_NAME 的空值

示例 JSON 响应:"RestResult":[""ROLL_NUM":7071,"CURRENT_CLASS":"Grade LKG C","STUDENT_NAME":"A.吠檀迦利阿库拉吠檀迦利"

ListItem.class

String STUDENT_NAME;

String CURRENT_CLASS;

String ROLL_NUMBER;

public String getSTUDENT_NAME() 
    return STUDENT_NAME;


public String getCURRENT_CLASS() 
    return CURRENT_CLASS;


public String getROLL_NUMBER() 
    return ROLL_NUMBER;


public GetSet(String STUDENT_NAME, String CURRENT_CLASS, String ROLL_NUMBER) 
    this.STUDENT_NAME = STUDENT_NAME;
    this.CURRENT_CLASS = CURRENT_CLASS;
    this.ROLL_NUMBER = ROLL_NUMBER;

RecyclerAdapter.class

 private List<GetSet> itemList;
private Context context;

public RecyclerViewAdapter(Context context, List<GetSet> itemList) 
    this.itemList = itemList;
    this.context = context;


@Override
public RecyclerViewHolders onCreateViewHolder(ViewGroup parent, int viewType) 
    View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, null);
    RecyclerViewHolders rcv = new RecyclerViewHolders(layoutView);
    return rcv;


@Override
public void onBindViewHolder(RecyclerViewHolders holder, int position) 
    holder.songTitle.setText("Student Name: " + itemList.get(position).getSTUDENT_NAME());
    holder.songYear.setText("Current Class: " + itemList.get(position).getCURRENT_CLASS());
    holder.songAuthor.setText("Roll Number: " + itemList.get(position).getROLL_NUMBER());


@Override
public int getItemCount() 
    return this.itemList.size();

ActivityMain.class

RequestQueue queue = Volley.newRequestQueue(this);
    String url ="http://webservices.educatemax.com/vidyaMandir.svc/RetrieveStudentsList?iGroupID=1&iSchoolID=1&iBoardID=1&iClassID=1";
    StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() 
        @Override
        public void onResponse(String response) 
            progressDialog.hide();
            Log.d(TAG, "Response " + response);
            GsonBuilder builder = new GsonBuilder();
            Gson mGson = builder.create();
            List<GetSet> posts = new ArrayList<>();


            posts = Arrays.asList(mGson.fromJson(response, GetSet.class));
            adapter = new RecyclerViewAdapter(ActivityMain.this, posts);
            recyclerView.setAdapter(adapter);
        
    , new Response.ErrorListener() 
        @Override
        public void onErrorResponse(VolleyError error) 
            Log.d(TAG, "Error " + error.getMessage());
        
    );
    queue.add(stringRequest);

【问题讨论】:

在recyclerview中使用分页 【参考方案1】:

你可以像这样使用滚动监听器:

public abstract class RecyclerViewOnScrollListener extends RecyclerView.OnScrollListener 
private final int mVisibleThreshold = 1;
private int mPreviousTotal = 0;
private boolean isLoading = true;
private int mFirstVisibleItem;
private int mVisibleItemsCount;
private int mTotalItemsCount;

private int mCurrentPage = 0;
private LinearLayoutManager mLayoutManager;

public RecyclerViewOnScrollListener(LinearLayoutManager manager) 
    this.mLayoutManager = manager;


public void init() 
    this.mPreviousTotal = 0;
    this.isLoading = true;
    this.mCurrentPage = 0;


@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) 
    super.onScrolled(recyclerView, dx, dy);

    mVisibleItemsCount = recyclerView.getChildCount();
    mTotalItemsCount = mLayoutManager.getItemCount();
    mFirstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();

    if (isLoading && mTotalItemsCount > mPreviousTotal) 
        isLoading = false;
        mPreviousTotal = mTotalItemsCount;
    
    if (!isLoading && (mTotalItemsCount - mVisibleItemsCount) <= (mFirstVisibleItem + mVisibleThreshold)) 
        mCurrentPage = mCurrentPage + 10;
        onLoadMore(mCurrentPage);
        isLoading = true;
    


public abstract void onLoadMore(int currentPage);

在你的片段活动中(任何你有你的 recyclerView 的地方):

        mRecyclerOnScrollListener = new RecyclerViewOnScrollListener(new GridLayoutManager(MyActivity.this, getResources().getInteger(R.integer.num_columns))) 
        @Override
        public void onLoadMore(int currentPage) 
            //here you can manage content and add to your adaprer 
        
    ;

【讨论】:

以上是关于如何使用大型 json 数据填充 RecyclerView [重复]的主要内容,如果未能解决你的问题,请参考以下文章

我想使用 GeoFire 在 android 中填充 Firebase Recycler View

动态地向Recycler视图添加多个视图

从大型 JSON 加载核心数据导致应用程序崩溃

如何使用 angularjs 填充 json 数据?

如何在 Fragment 中使用 Recycler View [重复]

如何发送和接收大型 JSON 数据