Fragment,RecyclerView:没有附加适配器;跳过布局
Posted
技术标签:
【中文标题】Fragment,RecyclerView:没有附加适配器;跳过布局【英文标题】:Fragment, RecyclerView: No adapter attached; skipping layout 【发布时间】:2019-04-07 18:36:25 【问题描述】:我正在使用 Fragment 来查看 RecyclerView。但我总是得到这个错误
E/RecyclerView:没有附加适配器;跳过布局
我为我的 recyclerview 创建了一个适配器,但布局没有显示。 php后端工作正常。有人可以帮忙吗?这是我的片段和适配器代码
Tips.java
public class Tips extends Fragment
Configuration config = new Configuration();
String HttpUrl = config.viewtips_url;
List<TipModel> tipList;
RecyclerView recyclerView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_tips, container, false);
recyclerView = view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
tipList = new ArrayList<>();
loadTips();
return view;
private void loadTips()
StringRequest stringRequest = new StringRequest(Request.Method.GET, HttpUrl,
new Response.Listener<String>()
@Override
public void onResponse(String response)
try
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++)
JSONObject jsonObject = jsonArray.getJSONObject(i);
tipList.add(new TipModel(
jsonObject.getInt("id"),
jsonObject.getString("tip")
));
TipAdapter tipAdapter = new TipAdapter(getActivity(), tipList);
recyclerView.setAdapter(tipAdapter);
catch (JSONException e)
e.printStackTrace();
,
new Response.ErrorListener()
@Override
public void onErrorResponse(VolleyError error)
);
Volley.newRequestQueue(getActivity()).add(stringRequest);
TipAdapter.java
public class TipAdapter extends RecyclerView.Adapter<TipAdapter.TipViewHolder>
private Context context;
private List<TipModel> tipList;
public TipAdapter(Context context, List<TipModel> tipList)
this.context = context;
this.tipList = tipList;
@Override
public TipViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.itemlayout, null);
return new TipViewHolder(view);
@Override
public void onBindViewHolder(TipViewHolder holder, int position)
TipModel tipModel = tipList.get(position);
holder.textViewTip.setText(tipModel.getTip());
@Override
public int getItemCount()
return tipList.size();
class TipViewHolder extends RecyclerView.ViewHolder
TextView textViewTip;
public TipViewHolder(View view)
super(view);
textViewTip = view.findViewById(R.id.textViewTip);
【问题讨论】:
你在哪里打电话loadTips()
?
虽然,你最好 1. 将 adapter
分配给 onCreateViewHolder()
内的 recyclerView
,2. 添加一个 adapter.updateWith(List<TipModel> tipList)
3. 并使用从中获取的tipList更新适配器StringRequest
@SumitAnantwar 什么?为什么要将适配器分配给适配器 inside 的 RecyclerView?
@SumitAnantwar 我已经编辑了上面的代码。尽管 RecyclerView: 没有附加适配器,但布局已经显示;跳过布局错误仍在我的日志中。这是我应该担心的事情吗?
您必须在 Fragment 的onCreateViewHolder()
中分配适配器。您收到此错误是因为在第一个布局周期中,回收器没有附加任何适配器。这主要是错误的。回收器应该附加一个适配器,并且在 StringRequest 之前,适配器的数据存储应该是空的。当StringRequest
完成时,您将传入获取的数据并调用notifyDataSetChanged()
。这将使用新数据重新加载回收器。
【参考方案1】:
这是因为RecyclerView
在创建视图时调度布局时需要一个适配器,所以如果创建视图时没有适配器也没关系,它会跳过布局部分。
如果您担心错误,那么您可以在创建视图时设置一个空适配器:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
return inflater.inflate(R.layout.fragment_tips, container, false);
@Override
public void onViewCreated(View view, Bundle savedInstanceState)
recyclerView = view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
tipList = new ArrayList<>();
recyclerView.setAdapter(new TipAdapter(getActivity(), tipList));
然后在响应回调中调整你的代码:
@Override
public void onResponse(String response)
// Instead of setting adapter here...
// TipAdapter tipAdapter = new TipAdapter(getActivity(), tipList);
// recyclerView.setAdapter(tipAdapter);
// Just notify the adapter that tipList has changed.
recyclerView.getAdapter().notifyDataSetChanged();
// ...
【讨论】:
此解决方案有效,布局显示完美。虽然我收到了一个新错误“E/ImageInMemoryGraph: PFD pipe transfer failed java.io.IOException: Broken pipe” 对不起,我不确定新错误来自哪里,我在您的代码中看不到任何与图像相关的问题,您可能需要在其他地方寻找错误的来源。跨度> 【参考方案2】:TipList是Adapter的datastore,属于Adapter,不属于Fragment
我已经编辑了你的代码(无权访问 android Studio,在文本编辑器中进行,请检查语法错误)
片段
public class Tips extends Fragment
Configuration config = new Configuration();
String HttpUrl = config.viewtips_url;
RecyclerView recyclerView;
TipAdapter tipAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
// Initialize the Tip Adapter
tipAdapter = new TipAdapter(getActivity());
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_tips, container, false);
recyclerView = view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
// Assign the Adapter to recyclerView
recyclerView.setAdapter(tipAdapter);
return view;
private void loadTips()
StringRequest stringRequest = new StringRequest(Request.Method.GET, HttpUrl,
new Response.Listener<String>()
@Override
public void onResponse(String response)
try
JSONArray jsonArray = new JSONArray(response);
// Create a new TipList
List<TipModel> tipList = new ArrayList<>();
for (int i = 0; i < jsonArray.length(); i++)
JSONObject jsonObject = jsonArray.getJSONObject(i);
tipList.add(new TipModel(
jsonObject.getInt("id"),
jsonObject.getString("tip")
));
tipAdapter.updateWith(tipList)
catch (JSONException e)
e.printStackTrace();
,
new Response.ErrorListener()
@Override
public void onErrorResponse(VolleyError error)
);
Volley.newRequestQueue(getActivity()).add(stringRequest);
提示适配器
public class TipAdapter extends RecyclerView.Adapter<TipAdapter.TipViewHolder>
private Context context;
private List<TipModel> tipList = new ArrayList<>();
public TipAdapter(Context context)
this.context = context;
@Override
public TipViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.itemlayout, null);
return new TipViewHolder(view);
@Override
public void onBindViewHolder(TipViewHolder holder, int position)
TipModel tipModel = tipList.get(position);
holder.textViewTip.setText(tipModel.getTip());
@Override
public int getItemCount()
return tipList.size();
class TipViewHolder extends RecyclerView.ViewHolder
TextView textViewTip;
public TipViewHolder(View view)
super(view);
textViewTip = view.findViewById(R.id.textViewTip);
public updateWith(List<TipModel> tipList)
this.tipList = tipList;
notifyDataSetChanged();
【讨论】:
【参考方案3】:当我在片段中膨胀回收站视图时遇到类似问题时,我就是这样做的。这段代码非常适合我:
附: - 这是我在应用程序中使用的代码补丁。给您带来的不便,我深表歉意。
首先,在 Display Fragment 的 onCreateView() 中:
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState)
View root = inflater.inflate(R.layout.fragment_home, container, false);
Firebase.setAndroidContext(getActivity());
((Home_Drawer) getActivity())
.setActionBarTitle("Home");
recyclerView = (RecyclerView) root.findViewById(R.id.recycler_view_home_frag);
progressBar = (ProgressBar) root.findViewById(R.id.mainPageProgressBar);
// Log.i("inside", "rv initiated" +mLayoutManager.toString());
// Assign activity this to progress dialog.
progressDialog = new ProgressDialog(getActivity());
// Setting up message in Progress dialog.
progressDialog.setMessage("Loading Images From Firebase.");
// Showing progress dialog.
progressDialog.show();
// The path is already defined in MainActivity.
databaseReference = FirebaseDatabase.getInstance().getReference().child("productDisplay");
Log.i("inside", databaseReference.toString());
return root;
然后,我们调用 onStart()。这是因为回收器视图通常不会膨胀,在 onCreateView() 中设置适配器。
@Override
public void onStart()
super.onStart();
FirebaseRecyclerOptions<DisplayItemsModel> item_info =
new FirebaseRecyclerOptions.Builder<DisplayItemsModel>()
.setQuery(databaseReference, DisplayItemsModel.class)
.build();
final FirebaseRecyclerAdapter<DisplayItemsModel, ViewHolder> info_adapter =
new FirebaseRecyclerAdapter<DisplayItemsModel, ViewHolder>(item_info)
@Override
protected void onBindViewHolder(final ViewHolder holder, final int position, final DisplayItemsModel model)
mContext = getContext();
final DatabaseReference dref = getRef(position).getRef();
Log.i("dref", dref.toString());
// Adding Add Value Event Listener to databaseReference.
dref.addValueEventListener(new ValueEventListener()
@Override
public void onDataChange(final DataSnapshot snapshot)
holder.item_name_single_card.setText(snapshot.child("name").getValue().toString());
holder.price_single_card.setText(snapshot.child("price").getValue().toString());
String image_url = snapshot.child("image").getValue().toString();
Picasso.get().load(image_url).into(holder.thumbnail);
// Continue with your code.
这对我来说非常有效。希望它能解决你的问题。
【讨论】:
以上是关于Fragment,RecyclerView:没有附加适配器;跳过布局的主要内容,如果未能解决你的问题,请参考以下文章
E/RecyclerView:没有附加适配器;在片段内的recyclerview上跳过布局
带有 RecyclerView 的 DialogFragment 比带有 Recyclerview 的 Fragment 慢
Fragment、Volley 和 RecyclerView