【问题标题】:Android - Accessing views in a fragmentAndroid - 访问片段中的视图
【发布时间】:2017-01-05 19:19:59
【问题描述】:

我有一个导航抽屉活动,我在其中附加不同的片段

public class MainActivity extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener, rp_fragment.OnFragmentInteractionListener, sensors_fragment.OnFragmentInteractionListener, stats_fragment.OnFragmentInteractionListener {

我正在尝试修改片段中包含的 textview 的 text 属性,但我一直在视图上收到空指针异常 (java.lang.NullPointerException: Attempt to invoke virtual method 'void com.teicrete.alucard. sempi.sensors_fragment.ctv_tvst(int)' 在空对象引用上)。

主要活动:

public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        if (id == R.id.nav_camera) {
            ft.replace(R.id.fragment_placeholder, new rp_fragment());
            ft.commit();
        } else if (id == R.id.nav_gallery) {
            ft.replace(R.id.fragment_placeholder, new sensors_fragment());
            ft.commit();
            gentempdata();
            sensors_fragment sf = (sensors_fragment)fm.findFragmentById(R.id.fragment_sensors);
           sf.ctv_tvst(1);

片段:

    public class sensors_fragment extends Fragment {
            // TODO: Rename parameter arguments, choose names that match
            // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
            private static final String ARG_PARAM1 = "param1";
            private static final String ARG_PARAM2 = "param2";

            TextView ctv_tv;
            TextView otv_tv;
            View view;
    ...

        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                    Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            view =  inflater.inflate(R.layout.fragment_sensors, container, false);
            TextView ctv_tv = (TextView)view.findViewById(R.id.ctv_tv);
            TextView otv_tv = (TextView)view.findViewById(R.id.otv_tv);
            //ctv_tv.setText("Test");   Only this works
            return view;
        }    
...

        public void ctv_tvst(int mtext) {
            ctv_tv.setText(mtext);
        }

我在这里查看过类似的帖子,但我无法解决我的问题。我能够修改文本视图的唯一地方是片段的 onCreateView (参见上面的代码)。如果我尝试从 mainactivity 或其他任何地方执行此操作,我会收到空​​指针错误。

有什么见解吗?

编辑:请参阅我在 android_griezmann 的帖子中的回复。 现在,我正在片段类本身中做我需要做的一切,然后我加载它们。我仍然想弄清楚为什么我不能从外部访问它的方法或视图。

【问题讨论】:

    标签: java android android-fragments


    【解决方案1】:

    从 onCreateView 更改这些行:

     TextView ctv_tv = (TextView)view.findViewById(R.id.ctv_tv);
     TextView otv_tv = (TextView)view.findViewById(R.id.otv_tv);
    

    收件人:

     ctv_tv = (TextView)view.findViewById(R.id.ctv_tv);
     otv_tv = (TextView)view.findViewById(R.id.otv_tv);
    

    目前您正在通过TextView ctv_tv 分配对新对象的引用,但实际上您希望将此引用分配给类字段,因此您不必添加TextView

    【讨论】:

    • 我做了这个更改,但仍然收到同样的错误。
    【解决方案2】:

    您的问题是Fragment 本身而不是TextView。您将片段对象设为 null 而不是 textview。

    所以试着找到像下面这样的片段。

    if (id == R.id.nav_gallery) {
            ft.replace(R.id.fragment_placeholder, new sensors_fragment(),"YOUR_TAG_NAME");
            ft.commit();
            gentempdata();
            sensors_fragment sf = (sensors_fragment) fm.findFragmentByTag("YOUR_TAG_NAME");
            sf.ctv_tvst(1);
        }
    

    也改变这个方法!

    public void ctv_tvst(int mtext) {
        ctv_tv.setText("" + mtext);
    }
    

    【讨论】:

    • 我相信你可能是正确的片段为空。我还尝试了例如 sf.getView() 而不是我的自定义方法,但我得到了同样的错误。但是,就像您指出的那样分配标签并不能解决问题。我还为其布局文件分配了一个 ID,但这也不起作用。
    • @PanagiotisMoraitis 通过TAG 找到片段后,您是否遇到相同的错误?
    • 确实如此。 TAG 也出现同样的错误。正如我所说,我认为您对片段为空是正确的。不知道为什么!
    【解决方案3】:
    @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
    
    TextView ctv_tv = (TextView)getView().findViewById(R.id.ctv_tv);
    TextView otv_tv = (TextView)getView().findViewById(R.id.otv_tv);
    
            }
    

    覆盖创建的 onactivity,然后参考您的视图。事实上,这是获取您的视图参考而不出现 NullPointer 异常的最佳位置

    【讨论】:

    • 我的 Fragment 类上没有 onActivityCreated 方法。
    • @PanagiotisMoraitis 这怎么可能??
    【解决方案4】:

    如果您想在替换或添加时传递数据,请在片段构造函数中传递数据,如下所示

    else if (id == R.id.nav_gallery) {
    
            ft.replace(R.id.fragment_placeholder, new sensors_fragment("your data"));
            ft.commit();
    

    然后在你的fragmet中根据构造函数的数据改变textview的值

    【讨论】:

      【解决方案5】:

      这就是问题所在。只需删除 TextView

       public View onCreateView(LayoutInflater inflater, ViewGroup container,
                      Bundle savedInstanceState) {
              // Inflate the layout for this fragment
              view =  inflater.inflate(R.layout.fragment_sensors, container, false);
              **TextView** ctv_tv = (TextView)view.findViewById(R.id.ctv_tv);
              **TextView** otv_tv = (TextView)view.findViewById(R.id.otv_tv);
              //ctv_tv.setText("Test");   Only this works
              return view;
          }    
      

      【讨论】:

        【解决方案6】:

        替换以下代码

        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                             Bundle savedInstanceState) {
             // Inflate the layout for this fragment
             view =  inflater.inflate(R.layout.fragment_sensors,container, false);
             TextView ctv_tv = (TextView)view.findViewById(R.id.ctv_tv);
             TextView otv_tv = (TextView)view.findViewById(R.id.otv_tv);
             //ctv_tv.setText("Test");   Only this works
             return view;
        }
        

        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                                 Bundle savedInstanceState) {
                 // Inflate the layout for this fragment
                 view =  inflater.inflate(R.layout.fragment_sensors,container, false);
                 ctv_tv = (TextView)view.findViewById(R.id.ctv_tv);
                 otv_tv = (TextView)view.findViewById(R.id.otv_tv);
                 //ctv_tv.setText("Test");   Only this works
                 return view;
            }
        

        创建一个变量String ctv_tv_string 并将ctv_tvst() 方法中的值赋值给TextView。它不会抛出错误,因为您在 oncreateview ctv_tv.setText(ctv_tv_string) 之后没有引用任何 ui 元素

        【讨论】:

        • 这是您问题的原因!您收到此错误是因为您是 ctv_tvst 方法,因为甚至调用了片段 onCreateView()!
        • 创建一个字符串变量 ctv_tv_string 并在 ctv_tvst() 方法中赋值,不要赋值给 TextView。它不会引发错误,因为您在 oncreateview ctv_tv.setText(ctv_tv_string) 之后没有引用任何 ui 元素
        • @Tulsi 在你的回答中,你说用户不必要地创建了两个新对象。你能解释一下他在哪里做的吗??
        • 这一行 TextView ctv_tv = (TextView)view.findViewById(R.id.ctv_tv);
        • 我在那里没有看到任何对象创建.. java 中的对象是使用 new 关键字创建的.. Object obj = new Object();在上面的代码中 TextView ctv_tv = (TextView)view.findViewById(R.id.ctv_tv);他只是通过将 ctv_tv 声明为 TextView 来引用视图.. 并且声明不会导致对象创建
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-24
        相关资源
        最近更新 更多