android.com培训:示例不起作用

android.com培训:示例不起作用,android,android-fragments,Android,Android Fragments,我三天前开始使用android,现在正在android.com上接受培训。 在关于片段的部分中,我遇到了由 片段中的findViewById() 代码是从 编辑:将示例源上载到 news_articles.xml(main): 现在的问题是updateArticleView()。 getActivity().findViewById(R.id.article)返回null 现在调试对我来说相当困难。 在调试过程中,是否有任何方法可以查看组件树或类似的内容 我所做的 我可以通过尝试以下方法来解决

我三天前开始使用android,现在正在android.com上接受培训。 在关于片段的部分中,我遇到了由 片段中的findViewById()

代码是从

编辑:将示例源上载到

news_articles.xml(main):

现在的问题是updateArticleView()。
getActivity().findViewById(R.id.article)
返回null

现在调试对我来说相当困难。
在调试过程中,是否有任何方法可以查看组件树或类似的内容


我所做的
我可以通过尝试以下方法来解决该错误:
getView().findViewById(R.id.article)

而不是
getActivity().findViewById(R.id.article)

updateArticleView()
中没有工作,但在
onViewCreated()
中将其分配给成员变量中工作

使用
getActivity().findViewById(R.id.article\u视图)
这不是在XML中分配的id,而是膨胀的XML的名称有效

只需使用
getView()
也可以


问题
对于初学者来说,从官方网站上获取不起作用的示例是令人困惑的。
我也不知道为什么使用
getView()
会起作用

有人能解释一下
getView()
getActivity()
在这种情况下是如何分解为组件树或其他东西的吗?

另外,有什么区别使得
getView().findViewById(R.id.article)
onViewCreated()
中工作,而不是在
updateArticleView()中工作?getView()两次返回相同的视图。


我目前不知道写这个
updateArticleView

的权利是什么,我不是最好的帮助理论部分的人,但是试着这样做

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

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

通过使用
onCreateView()
方法中的膨胀视图来标识片段视图中的id。在onCreateView()中使用
getView()
时,由于尚未创建视图,它将返回null

它在onViewCreated()中工作

因为当片段视图膨胀后调用此方法时。因此getView()将返回膨胀视图

可以通过以下方式初始化视图:

  • 为视图声明类变量
  • 在onCreateView中查找小部件的参考

     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
          View view = inflater.inflate(R.layout.article_view, container, false);
          article = (TextView) view.findViewById(R.id.article);
          return view;
     }
    
  • 现在在
    updateArticleView
    中直接使用这篇
    文章
    文本视图来设置文本

  • 片段
    是您的
    活动的一部分
    但具有不同的视图。当您希望在单个
    活动
    中显示多个视图,如
    选项卡
    时,可以使用它们

    无论何时创建
    片段
    ,它都不知道会给出什么视图。您必须在创建视图时在
    内做出决定。这就像“好的,现在我准备好了,请告诉我我应该是什么样子”在
    onCreateView
    中。现在,您有责任给它一个
    视图

    因此,您可以对希望显示的视图进行充气<在这种情况下,代码>文章视图

    一旦膨胀,您将需要访问
    片段
    的视图元素,而不是
    活动
    ,因此您必须在
    onCreate视图
    中获取该视图的引用

    您可以获取对
    视图的引用
    或单个元素的引用。假设您的
    文章视图中有一个
    文本视图
    。你能做的是

    public class ArticleFragment extends Fragment {
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            View view = inflater.inflate(R.layout.article_view, container, false);
            TextView article = (TextView) view.findViewById(R.id.article);
            article.setText("some text");
            return view;
        }
    }
    

    public class ArticleFragment extends Fragment {
        View view;
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            View view = inflater.inflate(R.layout.article_view, container, false);
            this.view = view;
            return view;
        }
    
        public void updateArticleView(int position) {
            TextView article = (TextView) view.findViewById(R.id.article);
            article.setText("some text");
            mCurrentPosition = position;
        }
    
    }
    
    确保在视图膨胀后调用
    updateArticleView
    。这意味着您可以在任何地方调用它,而不是
    onCreate
    (它是
    onCreate
    ,而不是
    onCreateView
    。在膨胀视图后,您完全可以在
    onCreateView
    内调用它

    更新

    我认为您在提交视图中的
    片段时感到困惑

    按照下面的示例显示
    片段

    您的主视图,比如说
    activity\u main.xml
    ,应该是这样的

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    ...>
    
        <FrameLayout
              android:id="@+id/fragment_container"
              ... />
    
    </LinearLayout>
    

    你现在可以想怎么玩就怎么玩。我的两个例子现在都可以用了。

    好的,我现在自己解决了这个问题

    我的结构如下:

    • 视图组线性布局
      • ID为的片段:标题\u片段
      • ID为的片段:article\u片段
    标题\u片段
    此片段来自类
    HeadlinesFragment
    ,该类
    扩展了ListFragment
    ,并使用它的默认值
    onCreateView()
    默认的
    onCreate视图
    返回一个
    视图
    ,它是一个
    框架布局

    文章片段
    此片段来自ArticleFragment类,它膨胀了以下XML:

    <?xml version="1.0" encoding="utf-8"?>
    
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/article"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="16dp"
        android:text="test"
        android:textSize="18sp" />
    
    结果:

    <?xml version="1.0" encoding="utf-8"?>
    
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
        <TextView xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/article"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="16dp"
            android:text="test"
            android:textSize="18sp" />
    </LinearLayout>
    
    • 视图组线性布局
      • ID为的框架布局:标题\u片段
      • ID为:article_片段的线性布局
        • ID为的文本视图:文章
    在这种情况下,可以通过其原始ID文章找到TextView


    此时,我只能猜测ID在何处更改。我假设它发生在片段的
    onAttach()
    内部或之后,这基本上是我在
    onViewCreated()
    方法中所做的。我是否可以确保在
    onCreateView()中创建的视图已准备就绪
    ?是的,但是通过这种方式,你可以在onCreateView()上对getView()问题进行findViewById,这可能是因为getView()只在onCreateView之后工作,最后你返回了视图,视图不再为空。我问的不是
    getView()
    ,而是本地
    视图
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        public View onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            FragmentTransaction transaction = getFragmentManager().beginTransaction();
    
            Fragment fragment = new HeadlinesFragment();
            transaction.replace(R.id.fragment_container, fragment);
            transaction.commit();
        }
    
    }
    
    <?xml version="1.0" encoding="utf-8"?>
    
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/article"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="16dp"
        android:text="test"
        android:textSize="18sp" />
    
    <?xml version="1.0" encoding="utf-8"?>
    
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
        <TextView xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/article"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="16dp"
            android:text="test"
            android:textSize="18sp" />
    </LinearLayout>