如果在OnCreateView外部使用,findViewById将返回null

时间:2017-01-17 16:53:32

标签: android android-layout android-fragments

为什么会出错?

public class ArticleFragment extends Fragment {
    final static String ARG_POSITION = "position";
    int mCurrentPosition = -1;

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

        // If activity recreated (such as from screen rotate), restore
        // the previous article selection set by onSaveInstanceState().
        // This is primarily necessary when in the two-pane layout.
        if (savedInstanceState != null) {
            mCurrentPosition = savedInstanceState.getInt(ARG_POSITION);
        }

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

    @Override
    public void onStart() {
        super.onStart();

        // During startup, check if there are arguments passed to the fragment.
        // onStart is a good place to do this because the layout has already been
        // applied to the fragment at this point so we can safely call the method
        // below that sets the article text.
        Bundle args = getArguments();
        if (args != null) {
            // Set article based on argument passed in
            updateArticleView(args.getInt(ARG_POSITION));
        } else if (mCurrentPosition != -1) {
            // Set article based on saved instance state defined during onCreateView
            updateArticleView(mCurrentPosition);
        }
    }

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

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        // Save the current article selection in case we need to recreate the fragment
        outState.putInt(ARG_POSITION, mCurrentPosition);
    }
}

失败的行是:

article.setText(Ipsum.Articles[position]);

因为文章为空。所以:

getActivity().findViewById(R.id.article)

返回null。

但是,如果我在onCreateView中设置文章如下:

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

    // If activity recreated (such as from screen rotate), restore
    // the previous article selection set by onSaveInstanceState().
    // This is primarily necessary when in the two-pane layout.
    if (savedInstanceState != null) {
        mCurrentPosition = savedInstanceState.getInt(ARG_POSITION);
    }

    View view = inflater.inflate(R.layout.article_view, container, false);;
    article = (TextView) view.findViewById(R.id.article);

    return view;
}

并更改updateArticle,如下所示:

public void updateArticleView(int position) {
    article.setText(Ipsum.Articles[position]);
    mCurrentPosition = position;
}

它可以正常工作。

5 个答案:

答案 0 :(得分:2)

可能不是打电话

TextView article = (TextView) getActivity().findViewById(R.id.article);

你应该致电

TextView article = (TextView) getView().findViewById(R.id.article);

答案 1 :(得分:2)

它不起作用,因为textview在片段而不是活动中。 getActivity()返回活动而不是片段。因此,它无法找到片段的本地textView。

而在onCreateView中,你提到了view.findViewById(),其中' view'是片段。

答案 2 :(得分:1)

您正在访问片段中的活动上下文,并且此时不必完成活动的创建。如果你必须在onCreate之外调用它,那么在片段的OnActivityCreated方法中调用它。

但似乎你的textview是片段而不是活动

答案 3 :(得分:1)

您可以保存从块中膨胀的视图

    onCreateView(LayoutInflater inflater, ViewGroup container, 
        Bundle savedInstanceState){
        //Previous code
        view = inflater.inflate(R.layout.article_view, container, false);
    }

然后您可以在代码中的任何其他地方调用它来获取如下视图:

    view.findViewById(R.id.view_searched);

而不是:

    getActivity().findViewById(R.id.view_searched);

答案 4 :(得分:0)

因为findViewById用于获取View对象的id,而不是Activity对象。实例化Fragment时,使用onCreateView方法创建视图:

 View view = inflater.inflate(R.layout.article_view, container, false);;
 article = (TextView) view.findViewById(R.id.article);
 return view;

您正在视图中搜索该ID(容器为R.layout.article_view)。

如果您执行getActivity.findViewById(),则无法通过您的身份查找。