[英]My RecyclerView in fragment stays blank even when it's populated
I have the following problem with RecyclerView on Android: 我在Android上使用RecyclerView存在以下问题:
Whenever I try to open the fragment with the RecyclerView, it stays blank. 每当我尝试使用RecyclerView打开片段时,它都保持空白。 My ArrayList mList isn't empty, it contains data (I tested it).
我的ArrayList mList不为空,它包含数据(我对其进行了测试)。
I tried many things to fix this problem, but I'm a beginner, so I don't really know where the problem is. 我尝试了很多方法来解决此问题,但是我是一个初学者,所以我真的不知道问题出在哪里。
The RecyclerView should display a list of products. RecyclerView应该显示产品列表。 I think there is a problem with my adapter or maybe the xml file fragment_list doesn't show up properly?
我认为我的适配器有问题,或者xml文件fragment_list无法正确显示? I don't really know.
我真的不知道
My ListAdaper class: 我的ListAdaper类:
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.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class ListAdapter extends
RecyclerView.Adapter<ListAdapter.ListViewHolder> {
private Context mContext;
private ArrayList<Item> mList;
public ListAdapter(Context context, ArrayList<Item> list) {
mContext = context;
mList = list;
}
@NonNull
@Override
public ListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mContext).inflate(R.layout.list_item, parent, false);
return new ListViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull ListViewHolder holder, int position) {
Item currentItem = mList.get(position);
holder.textViewName.setText(currentItem.getName());
holder.textViewRegion.setText(currentItem.getRegion());
}
@Override
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
public static class ListViewHolder extends RecyclerView.ViewHolder {
public CardView cardView;
public TextView textViewName;
public TextView textViewRegion;
public ListViewHolder(@NonNull View itemView) {
super(itemView);
cardView = itemView.findViewById(R.id.cardview);
textViewName = itemView.findViewById(R.id.item_name);
textViewRegion = itemView.findViewById(R.id.item_region);
}
}
@Override
public int getItemCount() {
return mList.size();
}
}
...my ListFragment class: ...我的ListFragment类:
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
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.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Iterator;
public class ListFragment extends Fragment {
private RecyclerView mRecyclerView;
private ListAdapter mListAdapter;
private ArrayList<Item> mList;
private RequestQueue mRequestQueue;
private Context mContext;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootview = inflater.inflate(R.layout.fragment_list, container, false);
mRecyclerView = rootview.findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerView.setHasFixedSize(true);
parseJSON();
mRecyclerView.setAdapter(mListAdapter);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
return rootview;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mContext = context;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mList = new ArrayList<>();
mListAdapter = new ListAdapter(mContext, mList);
mRequestQueue = Volley.newRequestQueue(mContext);
}
private void parseJSON() {
JsonObjectRequest request = new JsonObjectRequest("http://my_ip/sestavsisvujsvetweb/api/seznammagnetek", null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
JSONObject magnetky = response;
try {
Iterator keys = magnetky.keys();
while (keys.hasNext()) {
Object key = keys.next();
JSONObject value = magnetky.getJSONObject((String) key);
String monumentnumber = value.getString("monumentid");
String monumentname = value.getString("name");
String monumentregion = value.getString("region");
mList.add(new Item(monumentnumber, monumentname, monumentregion));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
if (request != null) {
mRequestQueue.add(request);
}
}
}
.....and my Item model class: .....和我的Item模型类:
public class Item {
private String name;
private String number;
private String region;
public Item(String number, String name, String region) {
this.name = name;
this.number = number;
this.region = region;
}
public String getName() {
return name;
}
public String getRegion() {
return region;
}
public String getNumber() { return number; }
}
Thanks for help, if I didn't include something important please do let me know :) 感谢您的帮助,如果我没有提供重要信息,请告诉我:)
Update: I tried adding mListAdapter.notifyDataSetChanged(); 更新:我尝试添加mListAdapter.notifyDataSetChanged(); and it seems so work, but I get this error in the log:
似乎很有效,但我在日志中收到此错误:
2019-08-21 19:46:16.947 5542-5542/com.example.app E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.app, PID: 5542
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at com.example.app.ListAdapter.onBindViewHolder(ListAdapter.java:38)
at com.example.app.ListAdapter.onBindViewHolder(ListAdapter.java:15)
........and some other stuff
Remove this line: 删除此行:
mRecyclerView.setHasFixedSize(true);
Since you are loading data asynchronously, your data size is 0 when you set the adapter. 由于要异步加载数据,因此在设置适配器时,数据大小为0。 Because you are setting it to fixed size, RecyclerView won't update its size when items change.
因为您将其设置为固定大小,所以RecyclerView不会在项目更改时更新其大小。
From documentation on setHasFixedSize()
: 从
setHasFixedSize()
文档中 :
RecyclerView can still change its size based on other factors (eg its parent's size) but this size calculation cannot depend on the size of its children or contents of its adapter (except the number of items in the adapter).
RecyclerView仍然可以基于其他因素(例如其父级的大小)来更改其大小,但是此大小计算不能取决于其子级的大小或适配器的内容(适配器中的项目数除外)。
You can also set the adapter after loading the data . 您还可以在加载数据后设置适配器。 It should work as well.
它也应该工作。
您需要通知适配器有关数据集更改的信息。请在onResponse()
中onResponse()
以下代码
mListAdapter.notifyDataSetChanged();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.