没有连接适配器,跳过 Fragment 上的布局
No Adapter Attached, Skipping Layout on Fragment
我已经尝试了几种不同的方法来解决这个问题,但它似乎并不想工作。我附上了相关的片段。当我使用搜索功能时,recyclerview 工作;但是,当我第一次加载页面时,出现
错误
E/RecyclerView: No adapter attached; skipping layout
我认为这可能是 onCreate 与 onCreateView 的问题,但我不确定将什么放在哪里。
NewsFragment.java
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
v = inflater.inflate(R.layout.fragment_news, container, false);
swipeRefreshLayout = v.findViewById(R.id.swipeRefresh);
recyclerView = v.findViewById(R.id.news_recyclerView);
etQuery = v.findViewById(R.id.etQuery);
btnSearch = v.findViewById(R.id.btnSearch);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
final String country = getCountry();
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
retrieveJson("", country, API_KEY);
}
});
retrieveJson("", country, API_KEY);
btnSearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!etQuery.getText().toString().equals("")) {
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
retrieveJson(etQuery.getText().toString(), country, API_KEY);
}
});
retrieveJson(etQuery.getText().toString(), country, API_KEY);
} else {
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
retrieveJson("", country, API_KEY);
}
});
retrieveJson("", country, API_KEY);
}
}
});
return v;
}
public void retrieveJson(String query ,String country, String apiKey){
swipeRefreshLayout.setRefreshing(true);
Call<Headlines> call;
if (!etQuery.getText().toString().equals("")){
call=NewsApiClient.getInstance().getApi().getSpecificData(query,apiKey);
}else{
call=NewsApiClient.getInstance().getApi().getHeadlines(country,apiKey);
}
call.enqueue(new Callback<Headlines>() {
@Override
public void onResponse(Call<Headlines> call, Response<Headlines> response) {
if (response.isSuccessful() && response.body().getArticles() != null ){
swipeRefreshLayout.setRefreshing(false);
articles.clear();
articles = response.body().getArticles();
newsAdapter = new NewsAdapter(getContext(), articles);
recyclerView.setAdapter(newsAdapter);
}
}
@Override
public void onFailure(Call<Headlines> call, Throwable t) {
swipeRefreshLayout.setRefreshing(false);
Toast.makeText(getContext(), t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
});
}
public String getCountry(){
Locale locale = Locale.getDefault();
String country = locale.getCountry();
return country.toLowerCase();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
在 onCreateView 上,您实际上没有设置任何适配器。您改为在 call.enqueue 回调中检索 json 数据时设置它,此回调是异步调用的,因此第一次调用 onCreateView 时没有适配器设置到 RecyclerView。为避免这种情况,请在 onCreateView 函数的开头设置一个空数据适配器,如下所示(使 newsAdapter 成为当前片段的变量)
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
newsAdapter = new NewsAdapter(getContext(), articles);
recyclerView.setAdapter(newsAdapter);
使文章成为当前片段的变量
并在 retriveJson 函数的回调中安装设置和适配器,只需用数据更新文章数组,然后像这样
调用 RecycleView 的 notifydatasetchanged 函数
public void onResponse(Call<Headlines> call, Response<Headlines> response) {
if (response.isSuccessful() && response.body().getArticles() != null ){
swipeRefreshLayout.setRefreshing(false);
articles.clear();
articles = response.body().getArticles();
newsAdapter.setData(articles);
newsAdapter.notifyDataSetChanged()
}
}
setData 是您必须在 NewsAdapter class 中创建的函数。
希望它有所帮助!
看看这个 brief guide 如何使用 RecycleViews
我已经尝试了几种不同的方法来解决这个问题,但它似乎并不想工作。我附上了相关的片段。当我使用搜索功能时,recyclerview 工作;但是,当我第一次加载页面时,出现
错误E/RecyclerView: No adapter attached; skipping layout
我认为这可能是 onCreate 与 onCreateView 的问题,但我不确定将什么放在哪里。
NewsFragment.java
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
v = inflater.inflate(R.layout.fragment_news, container, false);
swipeRefreshLayout = v.findViewById(R.id.swipeRefresh);
recyclerView = v.findViewById(R.id.news_recyclerView);
etQuery = v.findViewById(R.id.etQuery);
btnSearch = v.findViewById(R.id.btnSearch);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
final String country = getCountry();
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
retrieveJson("", country, API_KEY);
}
});
retrieveJson("", country, API_KEY);
btnSearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!etQuery.getText().toString().equals("")) {
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
retrieveJson(etQuery.getText().toString(), country, API_KEY);
}
});
retrieveJson(etQuery.getText().toString(), country, API_KEY);
} else {
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
retrieveJson("", country, API_KEY);
}
});
retrieveJson("", country, API_KEY);
}
}
});
return v;
}
public void retrieveJson(String query ,String country, String apiKey){
swipeRefreshLayout.setRefreshing(true);
Call<Headlines> call;
if (!etQuery.getText().toString().equals("")){
call=NewsApiClient.getInstance().getApi().getSpecificData(query,apiKey);
}else{
call=NewsApiClient.getInstance().getApi().getHeadlines(country,apiKey);
}
call.enqueue(new Callback<Headlines>() {
@Override
public void onResponse(Call<Headlines> call, Response<Headlines> response) {
if (response.isSuccessful() && response.body().getArticles() != null ){
swipeRefreshLayout.setRefreshing(false);
articles.clear();
articles = response.body().getArticles();
newsAdapter = new NewsAdapter(getContext(), articles);
recyclerView.setAdapter(newsAdapter);
}
}
@Override
public void onFailure(Call<Headlines> call, Throwable t) {
swipeRefreshLayout.setRefreshing(false);
Toast.makeText(getContext(), t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
});
}
public String getCountry(){
Locale locale = Locale.getDefault();
String country = locale.getCountry();
return country.toLowerCase();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
在 onCreateView 上,您实际上没有设置任何适配器。您改为在 call.enqueue 回调中检索 json 数据时设置它,此回调是异步调用的,因此第一次调用 onCreateView 时没有适配器设置到 RecyclerView。为避免这种情况,请在 onCreateView 函数的开头设置一个空数据适配器,如下所示(使 newsAdapter 成为当前片段的变量)
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
newsAdapter = new NewsAdapter(getContext(), articles);
recyclerView.setAdapter(newsAdapter);
使文章成为当前片段的变量 并在 retriveJson 函数的回调中安装设置和适配器,只需用数据更新文章数组,然后像这样
调用 RecycleView 的 notifydatasetchanged 函数public void onResponse(Call<Headlines> call, Response<Headlines> response) {
if (response.isSuccessful() && response.body().getArticles() != null ){
swipeRefreshLayout.setRefreshing(false);
articles.clear();
articles = response.body().getArticles();
newsAdapter.setData(articles);
newsAdapter.notifyDataSetChanged()
}
}
setData 是您必须在 NewsAdapter class 中创建的函数。 希望它有所帮助! 看看这个 brief guide 如何使用 RecycleViews