苦苦挣扎!
我创建了一个包含2个页面的viewpager,一个是完美运行的音频播放器,第二个页面是新闻列表。它是一个带有回收者视图的片段。
摇篮
dependencies {
implementation 'com.android.support.constraint:constraint-layout:1.1.1'
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation project(':library')
implementation 'com.android.support:support-v4:27.1.1'
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:recyclerview-v7:27.1.1'
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'com.android.volley:volley:1.1.0'
}
ViewPager适配器
private class mPagerAdapter extends FragmentStatePagerAdapter {
public mPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int pos) {
switch(pos) {
case 0: return PlayerPage.newInstance();
case 1: return News.newInstance();
default: return PlayerPage.newInstance();
}
}
@Override
public int getCount() {
return 2;
}
}
新闻片段
public class News extends Fragment {
private List<NewsBlueprint> newsList = new ArrayList<>();
private RecyclerView recyclerView;
private NewsAdapter newsAdapter;
private ProgressBar progressBar;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_news, container, false);
progressBar = (ProgressBar) v.findViewById(R.id.progress_bar);
recyclerView = (RecyclerView) v.findViewById(R.id.news_recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getBaseContext()));
recyclerView.setHasFixedSize(true);
recyclerView.setItemViewCacheSize(View.DRAWING_CACHE_QUALITY_HIGH);
// Fill with test
newsList.add(new NewsBlueprint("hi", "hi", "hi", "hi"));
try {
new Thread(new Runnable() {
@Override
public void run() {
newsAdapter = new NewsAdapter(newsList);
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
recyclerView.setAdapter(newsAdapter);
}
});
}
}).start();
} catch (Exception ex) {
ex.printStackTrace();
}
getNews();
return v;
}
public static News newInstance() {
return new News();
}
public void getNews() {
newsList.clear();
progressBar.setVisibility(View.VISIBLE);
String url = "I removed link for privacy on StackOverflow";
RequestQueue mRequestQueue;
Cache cache = new DiskBasedCache(getActivity().getCacheDir(), 1024 * 1024); // 1MB cap
Network network = new BasicNetwork(new HurlStack());
mRequestQueue = new RequestQueue(cache, network);
mRequestQueue.start();
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
try {
JSONObject current = null;
for (int i = 0; i < response.length(); i++) {
current = response.getJSONObject(i);
// Get the topStory's title from the volume information
String topStoryTitle = current.getJSONObject("title").getString("rendered");
// Get the current topStory's section information
// The appropriate section that the story belongs to is contained in the subsection
String topStorySection = current.getJSONObject("content").getString("rendered");
// Get the date on which the news was published
// Extract date information from the JSON response
String topStoryDateTime = current.getString("date");
// Get the story url
String storyUrl = current.getString("link");
JSONObject res = current.getJSONObject("_links");
JSONArray multimedia = res.getJSONArray("wp:featuredmedia");
String href = multimedia.getJSONObject(0).getString("href");
newsList.add(new NewsBlueprint(topStoryTitle, topStorySection, topStoryDateTime, href));
Toast.makeText(getContext(), "Looping " + topStoryTitle, Toast.LENGTH_SHORT).show();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getContext(), "Make sure you are connected to the internet", Toast.LENGTH_SHORT).show();
}
});
mRequestQueue.add(jsonArrayRequest);
newsAdapter.notifyDataSetChanged();
progressBar.setVisibility(View.INVISIBLE);
}
}
新闻适配器
public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.MyViewHolder>{
private List<NewsBlueprint> news;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView title;
public ImageView thumbnail;
public MyViewHolder(View view) {
super(view);
title = view.findViewById(R.id.title);
thumbnail = view.findViewById(R.id.thumbnail);
}
}
public NewsAdapter(List<NewsBlueprint> newsList) {
this.news = newsList;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.news_row, parent, false);
return new MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
NewsBlueprint newsBlueprint = news.get(position);
holder.title.setText(newsBlueprint.getTitle());
// Set thumbnail
//Picasso.get().load(newsBlueprint.getImageURL()).into(holder.thumbnail);
}
public int getItemCount() {
return news.size();
}
}
新闻蓝图
只是一个代表新闻项目的类
结果是一个空的RecyclerView
我确保从JSON返回的数据是正确的,因为我在Toast中显示了新闻的标题。
答案 0 :(得分:3)
newsAdapter.notifyDataSetChanged();
(jsonArrayRequest在后台运行,调用它的函数直接继续而不等待响应),而不是在你开始获得新闻。此外,从另一个线程修改适配器数组并不是一个好主意,在后台线程上创建适配器是完全错误的。