【发布时间】:2017-09-13 11:51:08
【问题描述】:
我正在制作一个新闻应用程序,其中有 3 个标签,分别是趋势、最新和流行。我已经实现了选项卡布局。现在我必须在选择每个片段时显示列表。我在下面使用谷歌新闻 API
https://newsapi.org/v1/articles?source=google-news&sortBy=top
现在我想根据选择的标签过滤来自 API 的数据,例如如果选择了流行标签,那么 URL 应该是 https://newsapi.org/v1/articles?source=google-news&sortBy=popular,它将显示在相应的片段中。
我在第一个选项卡中进行了网络调用,它的工作正常。但是当我切换标签时它崩溃了。所以我很困惑如何根据选择的标签进行网络调用。
这是我的主要活动:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initializeViews();
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayUseLogoEnabled(true);
setupViewPager(viewPager);
tabLayout.setupWithViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new TopStories(), "top stories");
adapter.addFragment(new Trending(), "trending");
adapter.addFragment(new Latest(), "latest");
adapter.addFragment(new Popular(), "popular");
viewPager.setAdapter(adapter);
}
private void initializeViews() {
toolbar = (Toolbar) findViewById(R.id.toolbar);
viewPager = (ViewPager) findViewById(R.id.viewpager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
片段1:
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.top_stories,container,false);
if (ParamConstants.API_KEY.isEmpty()) {
Toast.makeText(getContext(), "Please obtain your API KEY first from themoviedb.org", Toast.LENGTH_LONG).show();
}
recyclerView = (RecyclerView)rootView.findViewById(R.id.news_recycle);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
fetchNews(recyclerView);
return rootView;
}
private void fetchNews(final RecyclerView rv) {
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
Call<JsonElement> call = apiService.getNews("google-news", "top", ParamConstants.API_KEY);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(Call<JsonElement> call, Response<JsonElement> response) {
Log.d("resonse", response.toString());
JsonElement object = response.body();
Type listType = new TypeToken<List<News>>() {
}.getType();
news = new Gson().fromJson(object.getAsJsonObject().getAsJsonArray("articles"), listType);
rv.setAdapter(new NewsAdapter(news, R.layout.news_list_item, getContext()));
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),DividerItemDecoration.VERTICAL_LIST));
}
@Override
public void onFailure(Call<JsonElement> call, Throwable t) {
Log.e(TAG, t.toString());
}
});
Call<JsonElement> source = apiService.getSources("", "", "");
source.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(Call<JsonElement> call, Response<JsonElement> response) {
Log.d("sources", response.body().toString());
Type listType = new TypeToken<List<NewsResponse>>() {
}.getType();
newsResponse = new Gson().fromJson(response.body().getAsJsonObject().getAsJsonArray("sources"), listType);
newsResponse.get(0).getCategory().toString();
}
@Override
public void onFailure(Call<JsonElement> call, Throwable t) {
Log.e("sourcesfailure", t.toString());
}
});
}
片段2:
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.trending_fragment,container,false);
if (ParamConstants.API_KEY.isEmpty()) {
Toast.makeText(getContext(), "Please obtain your API KEY first from themoviedb.org", Toast.LENGTH_LONG).show();
}
recyclerView = (RecyclerView)rootView.findViewById(R.id.news_recycle);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
fetchTrendingNews(recyclerView);
return rootView;
}
private void fetchTrendingNews(final RecyclerView recyclerView) {
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
Call<JsonElement> call = apiService.getNews("BBC News", "popular", ParamConstants.API_KEY);
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(Call<JsonElement> call, Response<JsonElement> response) {
Log.d("resonse", response.toString());
JsonElement object = response.body();
Type listType = new TypeToken<List<News>>() {
}.getType();
news = new Gson().fromJson(object.getAsJsonObject().getAsJsonArray("articles"), listType);
recyclerView.setAdapter(new NewsAdapter(news, R.layout.news_list_item, getContext()));
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),DividerItemDecoration.VERTICAL_LIST));
}
@Override
public void onFailure(Call<JsonElement> call, Throwable t) {
Log.e(TAG, t.toString());
}
});
}
错误日志:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager)' on a null object reference
at com.kotlin.whatshappening.activity.fragment.Trending.onCreateView(Trending.java:65)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2184)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1298)
at android.support.v4.app.FragmentManagerImpl.moveFragmentsToInvisible(FragmentManager.java:2323)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2136)
at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2092)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:1969)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:620)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:143)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1268)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1116)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1642)
at android.view.View.measure(View.java:18809)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5954)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
at android.view.View.measure(View.java:18809)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5954)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139)
at android.view.View.measure(View.java:18809)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5954)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
at android.view.View.measure(View.java:18809)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5954)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure(View.java:18809)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5954)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
at android.view.View.measure(View.java:18809)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5954)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at com.android.internal.policy.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2643)
at android.view.View.measure(View.java:18809)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2112)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1228)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1464)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1119)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6060)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
at android.view.Choreographer.doCallbacks(Choreographer.java:670)
at android.view.Choreographer.doFrame(Choreographer.java:606)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
at android.os.Handler.handleCallback(Handler.java:746)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.
那么我如何根据每个选定的选项卡进行网络调用。
【问题讨论】:
-
显示你的错误日志。
-
@gaurav 检查 trending_fragment.xml 是否包含 ID 为 news_recycle 的 RecyclerView ?
-
@DivySoni 感谢您的帮助
-
@gauravtiwari 你的问题解决了吗?
-
@DivySoni 是的,它解决了,你正确地提到了错误。
标签: android android-fragments tabs