【问题标题】:Null P Exception while setting CheckBox with Android Fragments使用 Android 片段设置 CheckBox 时出现 Null P 异常
【发布时间】:2016-04-07 10:22:45
【问题描述】:

总结

我想我可以在 Fragment 中创建一个 CheckBox 并在 MainActivity 中以编程方式控制它。检查下面的链接以获取教程。

片段应该用于“模块化”应用程序。我想归档这个我可以将所有代码放在 MainActivity 中并将 UI 元素设置在 Fragment 中,因为我对 Java/Android 的经验非常有限。

通常,Fragment 应该照顾它自己拥有的一切。所以这就是我所做的:

MainActivity.java 我删除了 Checkbox View and Reference。

然后我在 Fragment (FragmentTest.java) 中创建了一个 CheckBox,如下所示:

public class FragmentTest extends Fragment{

    View rootView;
    CheckBox FragmentCheckbox;

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

        //Create a View and inflate the Fragment in this View.
        //This gives me the option to reference the Fragments Context like I did with:  rootView.findViewById
        rootView = inflater.inflate(R.layout.test_fragment, container, false);

        //Find the ID of the Checkbox in the Fragment
        FragmentCheckbox = (CheckBox) rootView.findViewById(R.id.checkBoxInFragment);
        //Set CheckBox to true
        FragmentCheckbox.setChecked(true);

        //return inflated View for the MainActivity to use
        return rootView;
    }
}

activity_main.xml 我删除了片段。不需要,因为在 MainActivity.java 中 //setContentView(R.layout.activity_main); 被注释掉了。

如果您想了解有关 Fragments 的更多信息,请观看此视频。我帮助我理解了 Fragments 的概念以及如何正确使用它们。

Fragment Tutorial Playlist

原始问题


今天我尝试在我的 Android 应用中实现 Fragments。我遵循了各种教程,几乎一切正常,将我的片段设置为主布局,还通过 ID 查找复选框,但尝试将我的复选框设置为 false 将返回空指针异常。我看了不同的问题,但我找不到答案。所有代码如下。感谢您的宝贵时间。

请注意,当我删除此行时,它会正常显示 CheckBox。但我无法在我的主活动文件中设置它。

fragmentCheckbox.setChecked(false);

我得到的错误:

Attempt to invoke virtual method 'void android.widget.CheckBox.setChecked(boolean)' on a null object reference

完整日志

FATAL EXCEPTION: main
    Process: *...............*.androidfragments, PID: 18658
    java.lang.RuntimeException: Unable to start activity ComponentInfo{*...............*.androidfragments/*...............*.androidfragments.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.CheckBox.setChecked(boolean)' on a null object reference
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2314)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2388)
    at android.app.ActivityThread.access$800(ActivityThread.java:148)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1292)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5312)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)
    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.CheckBox.setChecked(boolean)' on a null object reference
    at *...............*.androidfragments.MainActivity.onCreate(MainActivity.java:27)
    at android.app.Activity.performCreate(Activity.java:5953)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1128)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2267)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2388) 
    at android.app.ActivityThread.access$800(ActivityThread.java:148) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1292) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:135) 
    at android.app.ActivityThread.main(ActivityThread.java:5312) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:372) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)

主要活动: 这里我只是将我的 Fragment 设置为我的主布局

public class MainActivity extends AppCompatActivity {

CheckBox fragmentCheckbox;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

    FragmentTest fragmentTest = new FragmentTest();
    fragmentTransaction.replace(android.R.id.content, fragmentTest);

    fragmentTransaction.commit();

    fragmentCheckbox = (CheckBox) findViewById(R.id.checkBoxInFragment);
    fragmentCheckbox.setChecked(false);
  }
}

FragmentTest:返回我的片段

public class FragmentTest extends Fragment{
   @Nullable
   @Override
   public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
       return inflater.inflate(R.layout.test_fragment, container, false);
   }
}

我的 test_fragment XML 文件:基本上给我的 Checkbox 一个 ID

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    >

    <CheckBox
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New CheckBox"
        android:id="@+id/checkBoxInFragment"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />
</RelativeLayout>

还有我的主要 XML 文件

<fragment
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/test_fragment"/>

【问题讨论】:

  • 如果视图位于片段中,通常您希望片段控制该视图,而不是活动。否则没有片段没有意义。

标签: java android android-fragments android-studio checkbox


【解决方案1】:

当您调用replace 时,片段视图不会立即创建,因此您需要等到它实际创建后才能调用findViewById

【讨论】:

    【解决方案2】:

    你能把setChecked()放到片段中吗?

    public class FragmentTest extends Fragment{
       CheckBox fragmentCheckbox;
       @Nullable
       @Override
       public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
           View view = inflater.inflate(R.layout.test_fragment, container, false);
           fragmentCheckbox = (CheckBox) view.findViewById(R.id.checkBoxInFragment);
           fragmentCheckbox.setChecked(false);
           return view;
       }
    }
    

    编辑

    请尝试 UI Thread post 等待 Activity 中的 FragmentTransaction。

    new Handler().post(new Runnable () {
        public void run () {
            fragmentCheckbox = (CheckBox) findViewById(R.id.checkBoxInFragment);
            fragmentCheckbox.setChecked(false);
        }
    }
    

    如果你不能。 试试这个。

    ....
    fragmentTransaction.commit();
    fragmentManager.executePendingTransactions();
    fragmentCheckbox = (CheckBox) findViewById(R.id.checkBoxInFragment);
    fragmentCheckbox.setChecked(false);
    ...
    

    【讨论】:

    • 是的,这行得通,但是我有一段更大的代码,我想使用片段进行拆分。例如:我已连接到服务器,一旦连接断开,我想要一个片段显示在我可以再次连接到服务器的位置。代码是否可以不在 Fragments 中而是在 Main Activity 中?
    • 嘿,设置复选框与处理程序方法一起使用。谢谢你。但是我是否必须在 fragmentTransaction.commit() 之后将 onCreate 方法中的所有代码放入此处理程序中?
    • 处理程序发布只需要在 fragmentTransaction.commit() 之后立即进行。或者,你可以试试第三个executePendingTransactions () 吗?
    • 不,.executePendingTransactions();对我不起作用。只有 Handler 方式有效。但是当我有一个 onClick 侦听器时,它在处理程序中和它之外再次不起作用。有没有办法等待片段初始化它在其布局中的所有视图。这样它就不会返回空指针异常?
    • 嗯...请使用stackoverflow.com/a/8122789/4339442。并为 TestFragment 创建setChecked() 方法。 setChecked () 包含处理程序的帖子 setChecked。你必须为checkBox.setChecked() 实现processMessage()
    【解决方案3】:

    您正在尝试在活动内设置复选框,但复选框在片段 xml 内。因此,如果您想设置选中您的复选框。在片段的 onActivityCreated 方法中执行此操作。 如果是片段,则在 onCreateView 方法中创建复选框对象。由于复选框直接不可用于活动,因此引发空指针异常。希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 2014-09-05
      • 1970-01-01
      • 1970-01-01
      • 2014-09-16
      • 1970-01-01
      • 2014-03-06
      • 1970-01-01
      • 2012-02-27
      • 1970-01-01
      相关资源
      最近更新 更多