尝试调用虚拟方法 'void android.widget.Button.setOnClickListener(android.view.View$onClickListener)'

Posted

技术标签:

【中文标题】尝试调用虚拟方法 \'void android.widget.Button.setOnClickListener(android.view.View$onClickListener)\'【英文标题】:attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$onClickListener)'尝试调用虚拟方法 'void android.widget.Button.setOnClickListener(android.view.View$onClickListener)' 【发布时间】:2021-03-05 12:46:48 【问题描述】:

我正在尝试为按钮实现LayoutInflater,但在执行此操作后出现此错误。我不确定它是否已正确实施。对于同一个问题,我尝试了不同的解决方案,但作为 android 新手,我仍然发现很难解决这个问题。

https://www.dropbox.com/s/s2k92n6ss4mtztg/Screenrecorder-2020-11-23-00-34-16-139.mp4?dl=0(我很抱歉无法解释工作流程,但请参阅此剪辑以获得更好的理解,第一个活动是 IntroductoryActivity,最后一个有开始按钮的活动是 onboardingfragment3)

请解释一下这个问题。谢谢!

IntroductoryActivity.java

 @Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_introductory);
     
    ............

    **//The button from fragment_on_boarding3**
    start_l=findViewById(R.id.startb);

    .............

    **//Having issue with this part**

    LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View layoutScreen = inflater.inflate(R.layout.fragment_on_boarding3,null);

    start_l.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            Intent mainActivity = new Intent(getApplicationContext(),MainActivity.class);
            startActivity(mainActivity);

          // I need to save a boolean value to storage so next time when the user runs the app,I could know that he has already checked the intro screen activity
          // I'm going to use shared preferences forthat process
            
            savePrefsData();
            finish();
        
    );


 private boolean restorePrefData() 
        SharedPreferences pref = getApplicationContext().getSharedPreferences("myPrefs",MODE_PRIVATE);
        Boolean isIntroActivityOpnendBefore = pref.getBoolean("isIntroOpnend",false);
        return  isIntroActivityOpnendBefore;



private void savePrefsData() 

    SharedPreferences pref = getApplicationContext().getSharedPreferences("myPrefs",MODE_PRIVATE);
    SharedPreferences.Editor editor = pref.edit();
    editor.putBoolean("isIntroOpnend",true);
    editor.commit();


OnBoardingFragment3.java

public class OnBoardingFragment3 extends Fragment 

Context mContext ;
Button start;

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

    ViewGroup root=(ViewGroup) inflater.inflate(R.layout.fragment_on_boarding3,container,false);

    return root;
    

fragment_on_boarding3.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
       xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:app="http://schemas.android.com/apk/res-auto"
       xmlns:tools="http://schemas.android.com/tools"
       android:layout_
       android:layout_>

         <Button android:id="@+id/startb"
    android:layout_
    android:layout_
    android:fontFamily="@font/bungee"
    android:text="Let's Start"
    android:textSize="15dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.498"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintVertical_bias="0.754" />
     
    </androidx.constraintlayout.widget.ConstraintLayout>

错误:

java.lang.RuntimeException: Unable to start activity ComponentInfocom.example.liq/com.example.liq.IntroductoryActivity: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2946) at....................

【问题讨论】:

你能添加完整的错误吗? 您不能在 Activity 中使用来自 Fragment 的视图。使用其片段中的按钮,否则您会像现在一样获得 NPE。 @Tuqay 以下是错误:java.lang.RuntimeException:无法启动活动 ComponentInfocom.example.liq/com.example.liq.IntroductoryActivity:java.lang.NullPointerException:尝试在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2946) 处的空对象引用上调用虚拟方法“void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)”...... ...... 【参考方案1】:

findViewById其实是这样称呼的:

this.findViewById(someId);

this 指的是活动(在您的情况下为 IntroductoryActivity);

来自docs:

查找由 onCreate(Bundle) 中处理的 android:id XML 属性标识的视图。

这个onCreate() 方法是您调用findViewById 的Activity 的onCreate 方法。在您的情况下,该 id(和 View)属于片段,因此 Activity 无法找到与该 id 关联的视图并返回 null,当您想要 setOnClickListenerstart_l 按钮时,您会获得 NPE。

您可以在片段的onViewCreated 方法中将 onClickListener 设置为该按钮:

@Override
public void onViewCreated(View view, Bundle savedInstanceState) 
  super.onViewCreated(view, savedInstanceState);
  start_l=view.findViewById(R.id.startb);
  start_l.setOnClickListener.......
  

编辑:阿里王子的建议也是一种可能而且可能更好的方法。你可以在onCreateView里面初始化视图:

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

    ViewGroup root=(ViewGroup) inflater.inflate(R.layout.fragment_on_boarding3,container,false);
    start_l=root.findViewById(R.id.startb);
    start_l.setOnClickListener.......
    return root;

我也推荐看看这个post

【讨论】:

或者,跟随他的片段,在 onCreateView 中,使用View rootView = inflater.inflate(R.layout.fragment_songs , group, false); 然后声明你的观点:start_l = rootView.findViewById @Tuqay 先生,我想调用 start_l.setOnClickListener() 中的 IntroductoryActivity 函数之一。这就是原因,我试图在 IntroductoryActivity 中设置 OnClickListener。 使用此答案中的更新代码编辑问题。你做的不对。 图凯,阿里王子,非常感谢。通过结合两种解决方案(在 OnBoardingFragment3 中复制 savePrefsData() 并实现阿里王子提出的代码,应用程序运行成功。由于没有 getActivity() 虽然在 OnClickButton 中调用了另一个意图,但现在已经解决了。@Prince Ali,你能回答这个问题吗,以便我可以将其标记为已解决? 如果它引导您完成,只需标记它,@Tuqay 会相应地对其进行编辑。

以上是关于尝试调用虚拟方法 'void android.widget.Button.setOnClickListener(android.view.View$onClickListener)'的主要内容,如果未能解决你的问题,请参考以下文章

尝试在空对象引用上调用虚拟方法“void android.hardware.Camera.stopPreview()”

尝试在空对象引用上调用虚拟方法 'void android.view.View.measure(int, int)'

尝试在空对象引用上调用虚拟方法“void androidx.recyclerview.widget.RecyclerView.setLayoutManager()”

Android Studio:尝试在空对象引用上调用虚拟方法“void android.view.View.setOnClickListener”

尝试在空对象引用上调用虚拟方法“void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)”

Android:尝试在空对象引用上调用虚拟方法“void android.widget.ListView.setAdapter(android.widget.ListAdapter)”