片段中的同步呼叫在第一次启动时没有运行并且获取错误数据
我正在使用OkHttp获取HTML字符串并在RecyclerView中的片段中列出信息。片段中的同步呼叫在第一次启动时没有运行并且获取错误数据
但是,当应用程序运行时,首次启动时不显示列表信息。
当我点击其他片段页面并返回到这个片段页面后,它显示列表。
但是当我向下滑动以查看更多列表时,该列表重复两次(或更多次?)和项目背景颜色混乱。
我该如何解决?谢谢!
我的适配器
public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.ViewHolder> { private List<NewsModel> mNewsList;
class ViewHolder extends RecyclerView.ViewHolder {
TextView newsNameText;
TextView newsDataText;
View listView;
public ViewHolder(View newsView) {
super(newsView);
newsNameText = (TextView) newsView.findViewById(R.id.news_Name);
newsDataText = (TextView) newsView.findViewById(R.id.news_Data);
listView = newsView;
}
}
public NewsAdapter(List<NewsModel> newsList) {
mNewsList = newsList;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.news_item, parent, false);
final ViewHolder holder = new ViewHolder(view);
return holder;
}
public void setData(List<NewsModel> viewData) {
mNewsList.clear();
mNewsList.addAll(viewData);
notifyDataSetChanged();
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
NewsModel news = mNewsList.get(position);
holder.setIsRecyclable(true);
if(position % 2 == 0){
holder.listView.setBackgroundColor(0x80E0EEEE);
}
holder.newsNameText.setText(news.getName());
holder.newsDataText.setText(news.getData());
}
@Override
public int getItemCount() {
return mNewsList.size();
}
}
我的片段
public class NewsFragment extends Fragment { List<NewsModel> resultList = new ArrayList<>();
List<NewsModel> htmlList = new ArrayList<>();
NewsAdapter adapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View newsView = inflater.inflate(R.layout.fragment_news, container, false);
RecyclerView newsRecyclerView = (RecyclerView) newsView.findViewById(R.id.news_list);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
newsRecyclerView.setLayoutManager(layoutManager);
adapter = new NewsAdapter(getNews());
newsRecyclerView.setAdapter(adapter);
return newsView;
}
private List<NewsModel> getNews() {
new Thread(new Runnable() {
@Override
public void run() {
try {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://www.career.fudan.edu.cn/jsp/career_talk_list.jsp?count=50&list=true")
.build();
Response response = client.newCall(request).execute();
String resultString = response.body().string();
resultList.clear();
resultList.addAll(getResult(resultString));
adapter.notifyDataSetChanged();
/*new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
adapter.setData(resultList);
adapter.notifyDataSetChanged();
}
});//postdelayed (runnable long) cannot be applied to runnable*/
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
return resultList;
}
private List<NewsModel> getResult(final String response) {
XXXXXX
return htmlList;
}
}
回答:
的问题是,也许你正在添加许多条目,因为recyclerview试图重用这些意见,而不是再次重新划分和再次这导致有时看法不一致。这是问题discussed如果您遇到同样的问题,请查看它。 禁用它或者启用它在你的bindViewHolder()
setIsRecyclable(Boolean enable)
使用和你的第二个问题是,onCreateView()从另一个片段回来造成加时被称为第二次再次复制数据,因此您需要在添加任何新条目之前清除列表,并且为什么它在第一次运行时不显示,因为您已经在另一个线程中添加了数据并且没有更新适配器。
List<NewsModel> resultList = new ArrayList<>(); NewsAdapter adapter ;
public class NewsFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View newsView = inflater.inflate(R.layout.fragment_news, container, false);
RecyclerView newsRecyclerView = (RecyclerView) newsView.findViewById(R.id.news_list);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
newsRecyclerView.setLayoutManager(layoutManager);
adapter = new NewsAdapter(resultList);
newsRecyclerView.setAdapter(adapter);
getNews();
return newsView;
}
private void getNews(){
AsyncTask<Void,Void,String> asyncTask = new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(final Void... voids) {
String resultString = null;
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://www.career.fudan.edu.cn/jsp/career_talk_list.jsp?count=50&list=true")
.build();
Response response = null;
try {
response = client.newCall(request).execute();
resultString = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
return resultString;
}
@Override
protected void onPostExecute(final String resultString) {
super.onPostExecute(resultString);
resultList.clear();
resultList.addAll(getResult(resultString));
adapter.notifyDataSetChanged();
}
}.execute();
}
回答:
线程将改变一些延迟resultList,但在此之前,已经通过旧数据。 请尝试以下...
public class NewsFragment extends Fragment { @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View newsView = inflater.inflate(R.layout.fragment_news, container, false);
RecyclerView newsRecyclerView = (RecyclerView) newsView.findViewById(R.id.news_list);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
newsRecyclerView.setLayoutManager(layoutManager);
getNews(newsRecyclerView);
return newsView;
}
private void getNews(final RecyclerView newsRecyclerView){
new Thread(new Runnable() {
@Override
public void run() {
try {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://www.career.fudan.edu.cn/jsp/career_talk_list.jsp?count=50&list=true")
.build();
Response response = client.newCall(request).execute();
String resultString = response.body().string();
List<NewsModel> resultList = getResult(resultString);
NewsAdapter adapter = new NewsAdapter(resultList);
newsRecyclerView.setAdapter(adapter);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
private List<NewsModel> getResult(final String response) {
XXXXXXXXX
return List;
}
回答:
主要模式是坏的。 此代码最简单的方法是在适配器下载并调用notifyDataSetChanged()时设置(不添加)适配器中的项目 - 所有单元格都将重绘。
所以使适配器字段,添加方法适配器使用setData()和:
... Response response = client.newCall(request).execute();
String resultString = response.body().string();
resultList = getResult(resultString);
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
adapter.setData(results);
adapter.notifyDataSetChanged();
}
});
以上是 片段中的同步呼叫在第一次启动时没有运行并且获取错误数据 的全部内容, 来源链接: utcz.com/qa/257430.html