【问题标题】:NullPointerException accessing views in onCreate() - unable to find view by id [duplicate]NullPointerException 在 onCreate() 中访问视图 - 无法通过 id 找到视图 [重复]
【发布时间】:2014-05-30 05:52:55
【问题描述】:

我一直在查看许多在 onCreate 函数中获取指向显示器的指针的示例,但每次执行此操作时,我的 findViewById 函数都会返回空值,但如果我在其他地方执行此操作,则效果很好。为了让它正常工作,我缺少什么? 感谢您的帮助,我一定错过了什么

EditText messageField;
AutoCompleteTextView numberField;
EditText countField;
TextView messageDisplay;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
    sms = SmsManager.getDefault();
    preferences = PreferenceManager.getDefaultSharedPreferences(this);

    messageField = (EditText) findViewById(R.id.message);
    numberField = (AutoCompleteTextView) findViewById(R.id.number);
    countField = (EditText) findViewById(R.id.count);
    messageDisplay = (TextView) findViewById(R.id.display_message);

    if (savedInstanceState == null) {
        getFragmentManager().beginTransaction()
        .add(R.id.container, new PlaceholderFragment()).commit();
    }


}

fragment_main.xml

<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"
android:background="#000000"
tools:context="com.example.last.MainActivity$PlaceholderFragment" >


<AutoCompleteTextView
    android:id="@+id/number"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_alignRight="@+id/send"
    android:layout_marginTop="49dp"
    android:textColor="@android:color/white"
    android:inputType="numberSigned"
    android:selectAllOnFocus="true"
    android:ems="10"
    android:text="@string/phone_number" >

    <requestFocus />
</AutoCompleteTextView>

<Button
    android:id="@+id/send"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_below="@+id/message"
    android:layout_marginRight="25dp"
    android:layout_marginTop="70dp"
    android:onClick="sendMessage"
    android:textColor="@android:color/white"
    android:text="@string/send_button" />

<EditText
    android:id="@+id/message"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignRight="@+id/send"
    android:layout_below="@+id/number"
    android:layout_marginTop="61dp"
    android:ems="10"
    android:inputType="textMultiLine"
    android:textColor="@android:color/white"
    android:selectAllOnFocus="true"
    android:text="@string/default_message" />

<EditText
    android:id="@+id/count"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/message"
    android:layout_marginTop="32dp"
    android:ems="4"
    android:maxEms="4"
    android:inputType="numberSigned"
    android:textColor="@android:color/white"
    android:text="@string/default_count" />

<ProgressBar
    android:id="@+id/progressBar1"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/message"
    android:layout_below="@+id/send" />

<TextView
    android:id="@+id/display_message"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/progressBar1"
    android:layout_below="@+id/progressBar1"
    android:layout_marginTop="45dp"
    android:layout_toLeftOf="@+id/send"
    android:textColor="@android:color/white"
    android:text="@string/default_display_message" />

<TextView
    android:id="@+id/char_count"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBaseline="@+id/message"
    android:layout_alignBottom="@+id/message"
    android:layout_alignParentRight="true"
    android:text="18/160" />

<android.gesture.GestureOverlayView
    android:id="@+id/easter_egg_gesture"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentRight="true"
    android:layout_below="@+id/display_message" >

</android.gesture.GestureOverlayView>

<Button
    android:id="@+id/eeb"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBottom="@+id/easter_egg_gesture"
    android:layout_alignParentLeft="true"
    android:background="#000000"
    android:onClick="easterEgg" />

activity_main.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.app.joebot.MainActivity"
tools:ignore="MergeRootFrame" />

【问题讨论】:

  • 确保您引用的所有视图都来自activity_main.xml 文件。
  • 我明白了,我去看看我是怎么做到的
  • @user2967314 转到此post

标签: android android-layout android-view android-lifecycle


【解决方案1】:

从您的代码看来,您的组件(如 EdiText 和 TextView)位于 Fragment_main.xml 中,但您在 Activity_main.xml 中引用它们。

将组件的初始化更改为正确的布局。

【讨论】:

    【解决方案2】:

    您正在尝试从 Activity 中引用 Fragment 布局中的视图。这是不可能的,因为视图驻留在片段的布局中,而不是它试图查看的活动的布局。您应该在它们所在的 Fragment 中定义这些视图,然后如果您希望从 Activity 访问它们,则通过方法公开它们。

    但是,您不应轻易做出该决定,因为建议您将 Fragment 详细信息保留在 Fragment 中,并且仅在此之外公开您需要的内容。例如结果或值而不是整个视图。

    public MyFragment extends Fragment implements View.OnClickListener
    {
        private Button myButton;
        private EditText myEditText;
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            View view = inflater.inflate(R.layout.fragment_input_submit, container, false);
            myButton = (Button) view.findViewById(R.id.myButton);
            myEditText = (EditText) view.findViewById(R.id.myEditText);
            myButton.setOnClickListener(this);
            return view;
        }
    
        @Override
        public void onClick(View v)
        {
            // keep the Fragment interaction in the Fragment
            switch (v.getId())
            {
                case R.id.myButton:
                    Log.v("example fragment", "myButton was pressed");
                    break;
                default:
                    break;
            }
        }
    
        public EditText getMyEditText()
        {
            // you could get the EditText to use in your Activity
            return this.myEditText;
        }
    
        public String getEditTextContents()
        {
            // or you could just allow access the data
            return this.myEditText.getText().toString();
        }
    }
    

    要使用此功能,您需要在 Activity 中保留对 Fragment 的引用:

    public MyActivity extends FragmentActivity
    {
        private MyFragment myFragment;
    
        @Override
        public void onCreate(Bundle bundle)
        {
            super.onCreate(bundle);
            setContentView(R.layout.activity_main);
    
            myFragment = new MyFragment();
            getFragmentManager().beginTransaction()
                .add(R.id.container, myFragment).commit();
        }
        ...
    }
    

    然后要访问 Fragment 的信息,您可以调用:

    EditText myEditText = myFragment.getMyEditText();
        or
    String editTextContents = myFragment.getEditTextContents();
    

    取决于您的选择。

    您还可以使用接口从 Fragment 与 Activity 进行通信。请参阅this previous answer我在此处提出了一个相关问题,以了解有关该问题的详细信息以及更多示例。

    【讨论】:

      【解决方案3】:

      问题是,下面四行代码:

      messageField = (EditText) findViewById(R.id.message);
      numberField = (AutoCompleteTextView) findViewById(R.id.number);
      countField = (EditText) findViewById(R.id.count);
      messageDisplay = (TextView) findViewById(R.id.display_message);
      

      这些行应该出现在您的片段交易之后

      if (savedInstanceState == null) {
          getFragmentManager().beginTransaction()
          .add(R.id.container, new PlaceholderFragment()).commit();
          getFragmentManager().executePendingTransactions();
      }
      
      messageField = (EditText) findViewById(R.id.message);
      numberField = (AutoCompleteTextView) findViewById(R.id.number);
      countField = (EditText) findViewById(R.id.count);
      messageDisplay = (TextView) findViewById(R.id.display_message);
      

      这应该可以。

      还请注意,我已将executePendingTransactions() 方法添加到您的代码中(在这种情况下是必需的)。但是,我更愿意在Fragment 中处理那些Views(除非有充分的理由在Activity 本身中使用它们)。从ActivityonCreate() 方法中删除这些行,并将它们添加到PlaceholderFragmentonViewCreated() 方法中:

      @Override
      public void onViewCreated(View view, Bundle savedInstanceState){
      
          messageField = (EditText) view.findViewById(R.id.message);
          numberField = (AutoCompleteTextView) view.findViewById(R.id.number);
          countField = (EditText) view.findViewById(R.id.count);
          messageDisplay = (TextView) view.findViewById(R.id.display_message);
      
      }
      

      你想用这些Views 做什么都可以用这个方法完成。希望这会有所帮助... :)

      【讨论】:

        猜你喜欢
        • 2014-07-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多