RecyclerView:没有附加适配器;使用改造跳过应用程序中的布局[重复]
Posted
技术标签:
【中文标题】RecyclerView:没有附加适配器;使用改造跳过应用程序中的布局[重复]【英文标题】:RecyclerView: No adapter attached; skipping layout in app using retrofit [duplicate] 【发布时间】:2019-02-18 23:11:05 【问题描述】:我有一个连接到 API 并从中获取一些数据的简单程序。我使用 Retrofit
库。有两个活动。 MainActivity
包括一个 RecyclerView
,它显示从服务器接收到的数据。如果按任何项目,应用程序转到UserInfoActivity
并显示该项目的详细信息。我的应用程序在转到UserInfoActivity
几秒钟后崩溃并且不显示信息。然而response
正确接收但程序给出错误
在txtId.setText(user.getId)
线上。错误是E/RecyclerView: No adapter attached; skipping layout
事实上,我的问题是在第二个 Activity 中调用 Call<User> getUserInfo(@Path("id") int id);
时开始的。
这是MainActivity
代码。
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
userRequest();
private void userRequest()
APIInterface apiInterface= APIClient.getClient().create(APIInterface.class);
retrofit2.Call<ArrayList<User>> call= apiInterface.getUsers();
call.enqueue(new Callback<ArrayList<User>>()
@Override
public void onResponse(retrofit2.Call<ArrayList<User>> call, Response<ArrayList<User>> response)
if(response.isSuccessful())
ArrayList<User> users = response.body();
setupRecycelerView(users);
@Override
public void onFailure(retrofit2.Call<ArrayList<User>> call, Throwable t)
Log.i("RETROFIT","response not successful");
);
private void setupRecycelerView(ArrayList<User> users)
recyclerView=findViewById(R.id.RcyView);
adapter=new RecycelerAdapter(this,users);
linearLayoutManager=new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
recyclerView.setAdapter(adapter);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
这是RecycelerAdapter
的onBindViewHolder
函数。
public void onBindViewHolder(@NonNull UserViewHolder holder, int position)
final User user=values.get(position);
holder.txtName.setText(user.getName());
holder.txtPhone.setText(user.getPhone());
final Intent intent=new Intent(context, UserInfoActivity.class);
intent.putExtra("user",user);
holder.root.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
context.startActivity(intent);
);
这是UserInfoActivity
代码。
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_info);
txtId=findViewById(R.id.txtId);
txtName=findViewById(R.id.txtName);
txtPhone=findViewById(R.id.txtPhone);
Intent intent=getIntent();
User user=(User)intent.getSerializableExtra("user");
id=user.getId();
userInfoRequest();
private void userInfoRequest()
APIInterface apiInterface= APIClient.getClient().create(APIInterface.class);
retrofit2.Call<User> call= apiInterface.getUserInfo(id);
call.enqueue(new Callback<User>()
@Override
public void onResponse(Call<User> call, Response<User> response)
if(response.isSuccessful())
User user=response.body();
Log.e("MF","ON Response");
Log.e("MF",user.getName());
Log.e("MF",user.getPhone());
txtId.setText(user.getId());
txtName.setText(user.getName());
txtPhone.setText(user.getPhone());
@Override
public void onFailure(Call<User> call, Throwable t)
Log.e("MF","on failure");
);
【问题讨论】:
请发布完整的错误堆栈跟踪@sarina 【参考方案1】:试试这个:
linearLayoutManager=new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
recyclerView.setLayoutManager(linearLayoutManager);
adapter=new RecycelerAdapter(this,users);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
recyclerView.setHasFixedSize(true);
recyclerView.setItemAnimator(new DefaultItemAnimator());
使用notifyDataSetChanged()
告诉RecyclerView
数据已更改-添加并在setLayoutManager
之后设置Adapter
。
如果这没有帮助,请在 onCreate
方法中初始化 RecyclerView
并在 onResponse
中设置 Adapter
和 runOnUiThread
,如下所示:
runOnUiThread(new Runnable()
@Override
public void run()
//Do something on UiThread
ArrayList<User> users = response.body();
adapter=new RecycelerAdapter(this,users);
recyclerView.setAdapter(users);
);
然后调用notifyDataSetChanged()
,它应该可以工作。
【讨论】:
我每四个答案做一次,但我的问题还没有解决! 因此,在onCreate
方法中初始化RecyclerView
,并在ArrayList<User> users = response.body();
之后将Adapter
设置为ArrayList<User> users = response.body();
和runOnUiThread
。那时它会起作用的。我已经更新了答案。
不幸的是,同样的错误重复出现。
E/androidRuntime: FATAL EXCEPTION: main Process: com.example.np.retrofitarcademy, PID: 14983 android.content.res.Resources$NotFoundException: String resource ID #0x4 at android.content.res.Resources.getText(Resources.java:1468) at android.widget.TextView.setText(TextView.java:5051) at com.example.np.retrofitarcademy.UserInfoActivity$1.onResponse(UserInfoActivity.java:50)
哦,这实际上是另一个问题,你会在你的问题中添加 logcat,我会投票打开这个问题吗?请使用以下日志编辑标题和内容。我想问题来自模型中的 SetText gettext。我们可能也需要检查一下【参考方案2】:
您在 Retrofit api 调用的响应中调用 setupRecycelerView
,问题是在响应到来之前,RecyclerView
本身没有附加适配器或 layoutManager,因此出现错误。
相反,您可以在onCreate
本身内部调用setupRecycelerView
,然后创建Users
列表的全局对象。像这样的:
private final ArrayList<Users> users = new ArrayList();
此列表将为空,适配器将使用相同的空列表初始化,然后当您从改造 api 获得响应时,使用:
users.addAll(response.getBody());
这将填充内容,然后调用adapter.notifyDataSetChanged();
以使适配器反映更新的内容。
【讨论】:
【参考方案3】:发生这种情况是因为您在/如果来自服务器的响应成功时初始化 RecyclerView。
在onCreate()
中初始化它(调用 setupRecycelerView() )。并将adapter=new RecycelerAdapter(this,users);
更改为adapter=new RecycelerAdapter(this);
让你的 RecyclerAdapter 的构造函数只接受一个参数(可能是上下文) 在您的适配器中,创建一个设置用户的公共方法。
public setUserData(ArrayList<User> users)
this.values = users;
notifyDataSetChanged();
Retrofit 的调用RecycelerAdapter.setUserData(users);
响应成功。
【讨论】:
我每四个答案做一次,但我的问题还没有解决! 将recyclerView.setAdapter(adapter);
移动到 setupRecycelerView()
方法的底部【参考方案4】:
只需在您的setupRecycelerView()
中的setLayoutManager()
之后调用setAdapter()
【讨论】:
以上是关于RecyclerView:没有附加适配器;使用改造跳过应用程序中的布局[重复]的主要内容,如果未能解决你的问题,请参考以下文章
Fragment,RecyclerView:没有附加适配器;跳过布局
Firebase:Recyclerview 没有附加适配器,跳过布局
Firebase:Recyclerview 没有附加适配器,跳过布局