如何修复官方Android教程中Basic Fragments示例代码中的错误

时间:2018-01-31 11:14:18

标签: android android-fragments

我已下载官方片段教程here的示例代码,在将其更新为使用gradle并使用最新版本的Android Studio后,我发现在点击文章时和运行时会抛出NullPointerException在具有大屏幕的模拟器上(即平板电脑大小的屏幕 - 在手机大小的屏幕上它工作正常)。您可以找到更新后的代码here。例外是:

java.lang.NullPointerException
    at com.example.fragmentbasics.ArticleFragment.updateArticleView(ArticleFragment.java:64)
    at com.example.fragmentbasics.MainActivity.onArticleSelected(MainActivity.java:66)
    at com.example.fragmentbasics.HeadlinesFragment.onListItemClick(HeadlinesFragment.java:75)
    at android.support.v4.app.ListFragment$2.onItemClick(ListFragment.java:60)
    at android.widget.AdapterView.performItemClick(AdapterView.java:298)
    at android.widget.AbsListView.performItemClick(AbsListView.java:1100)
    at android.widget.AbsListView$PerformClick.run(AbsListView.java:2788)
    at android.widget.AbsListView$1.run(AbsListView.java:3463)
    at android.os.Handler.handleCallback(Handler.java:730)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:5103)

据我所知,在创建片段ArticleFragment时,应将布局article_view扩展到主活动中。这个布局有一个带有id“article”的TextView。无论屏幕大小如何,都应该发生这种情况。

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
    Bundle savedInstanceState) {
    ...

    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.article_view, container, false);
}

但由于某种原因,稍后在ArticleFragment上调用updateArticleView时,找不到ID为“article”的视图,导致上面的NPE。

public void updateArticleView(int position) {
    TextView article = (TextView) getActivity().findViewById(R.id.article);
    article.setText(Ipsum.Articles[position]);
    mCurrentPosition = position;
}

我们需要对示例代码进行哪些更改以避免此NPE并使示例代码适用于所有屏幕尺寸?

更新

由于Roberto Martucci在下面的回答,这个问题已得到解决。我已经更新了github存储库的master分支以包含修复。

2 个答案:

答案 0 :(得分:1)

由于它是一个片段,您应该在其根视图上调用findViewById而不是在活动内容上调用private View rootView; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ... // Inflate the layout for this fragment rootView = inflater.inflate(R.layout.article_view, container, false) return rootView; } public void updateArticleView(int position) { if(rootView != null) { TextView article = (TextView) rootView.findViewById(R.id.article); article.setText(Ipsum.Articles[position]); } mCurrentPosition = position; } 。应用这些更改以避免例外:

article_view.xml

<强>更新

我测试了你的代码,我可能找到了解决方案。你必须像以前在其他答案中建议的那样将TextView添加到layout-large,但它必须具有以下结构。您的FrameLayout需要有一个父容器,因此我将其包装在<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/article" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp" android:textSize="18sp" /> </FrameLayout>

kubernetes

答案 1 :(得分:0)

稍微检查后,我发现了......

你的结构必须是这样的:

layout
   -article_view.xml
   -news_articles.xml
layout-small
   -article_view.xml
layout-large
   -article_view.xml
layout-xlarge
    -article_view.xml

试了一下,它正在发挥作用。

编辑:或任何其他方式,但您必须在所有这些文件夹中包含article_view.xml