简体   繁体   中英

Multiple Buttons On One Listener - Crashes with two buttons, works for one

I have 3 buttons in my application, one on each tab of my tabbed activity and I want each one of them to do the same thing. However, only one when one of the buttons is clicked does it work. It crashes with the other two.

    public void changeOperation (View view) {
    Button b1, b2, b3;
    b1 = findViewById(R.id.prac_op); // Line 116 (As mentioned in exception)
    b2 = findViewById(R.id.operation);
    b3 = findViewById(R.id.instruc_op);
    switch (operation) {
        case 0:
            operation = 1;
            b1.setText("-");
            b2.setText("-");
            b3.setText("-");
            break;
        case 1:
            operation = 2;
            b1.setText("x");
            b2.setText("x");
            b3.setText("x");
            break;
        case 2:
            operation = 3;
            b1.setText("\u00F7");
            b2.setText("\u00F7");
            b3.setText("\u00F7");
            break;
        default:
        case 3:
            operation = 0;
            b1.setText("+");
            b2.setText("+");
            b3.setText("+");
            break;
    }
    Tab3Practice.reroll();
}

And the exception:

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.orion31.mathmachine, PID: 24662
              java.lang.IllegalStateException: Could not execute method for android:onClick
                  at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
                  at android.view.View.performClick(View.java:6254)
                  at android.view.View$PerformClick.run(View.java:24705)
                  at android.os.Handler.handleCallback(Handler.java:789)
                  at android.os.Handler.dispatchMessage(Handler.java:98)
                  at android.os.Looper.loop(Looper.java:164)
                  at android.app.ActivityThread.main(ActivityThread.java:6600)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:772)
               Caused by: java.lang.reflect.InvocationTargetException
                  at java.lang.reflect.Method.invoke(Native Method)
                  at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
                  at android.view.View.performClick(View.java:6254) 
                  at android.view.View$PerformClick.run(View.java:24705) 
                  at android.os.Handler.handleCallback(Handler.java:789) 
                  at android.os.Handler.dispatchMessage(Handler.java:98) 
                  at android.os.Looper.loop(Looper.java:164) 
                  at android.app.ActivityThread.main(ActivityThread.java:6600) 
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:772) 
               Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Window$Callback android.view.Window.getCallback()' on a null object reference
                  at android.support.v7.app.AppCompatDelegateImplBase.<init>(AppCompatDelegateImplBase.java:117)
                  at android.support.v7.app.AppCompatDelegateImplV9.<init>(AppCompatDelegateImplV9.java:149)
                  at android.support.v7.app.AppCompatDelegateImplV11.<init>(AppCompatDelegateImplV11.java:29)
                  at android.support.v7.app.AppCompatDelegateImplV14.<init>(AppCompatDelegateImplV14.java:54)
                  at android.support.v7.app.AppCompatDelegateImplV23.<init>(AppCompatDelegateImplV23.java:31)
                  at android.support.v7.app.AppCompatDelegateImplN.<init>(AppCompatDelegateImplN.java:31)
                  at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:198)
                  at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:183)
                  at android.support.v7.app.AppCompatActivity.getDelegate(AppCompatActivity.java:519)
                  at android.support.v7.app.AppCompatActivity.findViewById(AppCompatActivity.java:190)
                  at com.orion31.mathmachine.MathMain.changeOperation(MathMain.java:116)
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) 
                  at android.view.View.performClick(View.java:6254) 
                  at android.view.View$PerformClick.run(View.java:24705) 
                  at android.os.Handler.handleCallback(Handler.java:789) 
                  at android.os.Handler.dispatchMessage(Handler.java:98) 
                  at android.os.Looper.loop(Looper.java:164) 
                  at android.app.ActivityThread.main(ActivityThread.java:6600) 
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:772) 

This function is used as a OnClickListener for 3 buttons, but only the button the second tab actually successfully calls this function; the other two crash when clicked on. I have done some research on having multiple buttons on one OnClickListener . Is it a problem with my code, or a restriction with Android?

**Edit: ** MathMain.java

public class MathMain extends AppCompatActivity {

/**
 * The {@link android.support.v4.view.PagerAdapter} that will provide
 * fragments for each of the sections. We use a
 * {@link FragmentPagerAdapter} derivative, which will keep every
 * loaded fragment in memory. If this becomes too memory intensive, it
 * may be best to switch to a
 * {@link android.support.v4.app.FragmentStatePagerAdapter}.
 */
private SectionsPagerAdapter mSectionsPagerAdapter;

/**
 * The {@link ViewPager} that will host the section contents.
 */
private ViewPager mViewPager;
public static int operation;

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

    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    // Create the adapter that will return a fragment for each of the three
    // primary sections of the activity.
    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

    // Set up the ViewPager with the sections adapter.
    mViewPager = findViewById(R.id.container);
    mViewPager.setAdapter(mSectionsPagerAdapter);
    mViewPager.setCurrentItem(1);

    TabLayout tabLayout = findViewById(R.id.tabDots);
    tabLayout.setupWithViewPager(mViewPager, true);
}

public void changeOperation (View view) {
Button b1, b2, b3;
b1 = findViewById(R.id.prac_op); // Line 116 (As mentioned in exception)
b2 = findViewById(R.id.operation);
b3 = findViewById(R.id.instruc_op);
switch (operation) {
    case 0:
        operation = 1;
        b1.setText("-");
        b2.setText("-");
        b3.setText("-");
        break;
    case 1:
        operation = 2;
        b1.setText("x");
        b2.setText("x");
        b3.setText("x");
        break;
    case 2:
        operation = 3;
        b1.setText("\u00F7");
        b2.setText("\u00F7");
        b3.setText("\u00F7");
        break;
    default:
    case 3:
        operation = 0;
        b1.setText("+");
        b2.setText("+");
        b3.setText("+");
        break;
}
Tab3Practice.reroll();
}
        public void checkAnswer (View view) {
        TextView num1input = findViewById(R.id.num1);
        TextView num2input = findViewById(R.id.num2);
         TextView num3guess = findViewById(R.id.guessAnswer);

    if (
            (num1input.getText() == null || num1input.getText().equals("")) ||
            (num2input.getText() == null || num2input.getText().equals("")) ||
            (num3guess.getText() == null || num3guess.getText().equals(""))) return;

    double num1 = Double.parseDouble(num1input.getText().toString());
    double num2 = Double.parseDouble(num2input.getText().toString());
    double num3 = Double.parseDouble(num3guess.getText().toString());

    CheckDialog cd = new CheckDialog();

    double answer;
    switch (operation) {
        default:
        case 0:
            answer = num1 + num2;
            break;
        case 1:
            answer = num1 - num2;
            break;
        case 2:
            answer = num1 * num2;
            break;
        case 3:
            answer = num1 / num2;
            break;
    }

    if (answer == num3) {
        cd.setMessage("Good Job!  That's Correct.");
    } else if (Math.abs(answer - num3) <= 10) {
        cd.setMessage("Very close!  Keep trying!");
    } else {
        cd.setMessage("Nope!  That's not it.  Try again.");
    }

    num1input.setText("");
    num2input.setText("");
    num3guess.setText("");

    FragmentManager ft = getSupportFragmentManager();
    cd.show(ft, "check_dialog");


}



@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_math_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == R.id.action_about) {
        startActivity(new Intent(this, AboutScreen.class));
        return true;
    }
    return super.onOptionsItemSelected(item);
}

/**
 * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
 * one of the sections/tabs/pages.
 */


public static class CheckDialog extends DialogFragment {

    String message;

    @Override
    public Dialog onCreateDialog (Bundle savedInstanceState) {
         return new AlertDialog.Builder(getActivity()).setTitle("Check Your Work").setMessage(message)
                 .setNegativeButton("CLOSE", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        }).show();
    }

    @Override
    public void onStart() {
        super.onStart();
        ((AlertDialog) getDialog()).getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(Color.RED);
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

public class SectionsPagerAdapter extends FragmentPagerAdapter {

    SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        switch(position) {
            case 0:
                return new Tab1Check();
            case 1:
                return new Tab2Main();
            case 2:
                return new Tab3Practice();
            default:
                return null;
        }
    }

    @Override
    public int getCount() {
        // Show 3 total pages.
        return 3;
    }
}

}

In each fragment reference your button in onCreateView

    public class YourFragment extends Fragment ...

    Button button1;


    public void onCreateView(.... )
      {
          View view = inflate ...
          button1 = view.findViewById(R.id.prac_opl);
      }

Add this method in each of your fragments

    public void updateText(String text){
        button1.setText(text);
    }

Modify your Activity

    public class MathMain extends AppCompatActivity { 

    Tab1Check fragmentTab1;
    Tab2Main fragmentTab2;
    Tab3Practice fragmentTab3;

    /** 
    * The {@link android.support.v4.view.PagerAdapter} that will provide 
    * fragments for each of the sections. We use a 
    * {@link FragmentPagerAdapter} derivative, which will keep every 
    * loaded fragment in memory. If this becomes too memory intensive, it 
    * may be best to switch to a 
    * {@link android.support.v4.app.FragmentStatePagerAdapter}. 
    */ 
    private SectionsPagerAdapter mSectionsPagerAdapter; 

    /** 
    * The {@link ViewPager} that will host the section contents. 
    */ 
    private ViewPager mViewPager; 
    public static int operation; 

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

    Toolbar toolbar = findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 
    // Create the adapter that will return a fragment for each of the three 
    // primary sections of the activity. 
    fragmentTab1 = new Tab1Check();
    fragmentTab3 = new Tab2Main();
    fragmentTab3 = new Tab3Practice();
    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); 

    // Set up the ViewPager with the sections adapter. 
    mViewPager = findViewById(R.id.container); 
    mViewPager.setAdapter(mSectionsPagerAdapter); 
    mViewPager.setCurrentItem(1); 

    TabLayout tabLayout = findViewById(R.id.tabDots); 
    tabLayout.setupWithViewPager(mViewPager, true); 
    } 


    public void checkAnswer(View view) { 
    TextView num1input = findViewById(R.id.num1); 
    TextView num2input = findViewById(R.id.num2); 
    TextView num3guess = findViewById(R.id.guessAnswer); 

    if ( 
    (num1input.getText() == null || num1input.getText().equals("")) || 
    (num2input.getText() == null || num2input.getText().equals("")) || 
    (num3guess.getText() == null || num3guess.getText().equals(""))) return; 

    double num1 = Double.parseDouble(num1input.getText().toString()); 
    double num2 = Double.parseDouble(num2input.getText().toString()); 
    double num3 = Double.parseDouble(num3guess.getText().toString()); 

    CheckDialog cd = new CheckDialog(); 

    double answer; 
    switch (operation) { 
    default: 
    case 0: 
    answer = num1 + num2; 
    break; 
    case 1: 
    answer = num1 - num2; 
    break; 
    case 2: 
    answer = num1 * num2; 
    break; 
    case 3: 
    answer = num1 / num2; 
    break; 
    } 

    if (answer == num3) { 
    cd.setMessage("Good Job! That's Correct."); 
    } else if (Math.abs(answer - num3) <= 10) { 
    cd.setMessage("Very close! Keep trying!"); 
    } else { 
    cd.setMessage("Nope! That's not it. Try again."); 
    } 

    num1input.setText(""); 
    num2input.setText(""); 
    num3guess.setText(""); 

    FragmentManager ft = getSupportFragmentManager(); 
    cd.show(ft, "check_dialog"); 


    } 


    public void changeOperation(View view) { 

    switch(MathMain.operation) 

    { 
    case 0: 
    MathMain.operation = 1; 
    fragmentTab1.updateText("-");
    fragmentTab2.updateText("-");
    fragmentTab3.updateText("-");
    break; 
    case 1: 
    MathMain.operation = 2; 
    fragmentTab1.updateText("x");
    fragmentTab2.updateText("x");
    fragmentTab3.updateText("x");
    break; 
    case 2: 
    MathMain.operation = 3; 
    fragmentTab1.updateText("\u00F7");
    fragmentTab2.updateText("\u00F7");
    fragmentTab3.updateText("\u00F7");
    break; 
    default: 
    case 3: 
    MathMain.operation = 0; 
    fragmentTab1.updateText("+");
    fragmentTab2.updateText("+");
    fragmentTab3.updateText("+"); 
    break; 
    } 

    reroll(); 
    } 
    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.menu_math_main, menu); 
    return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
    if (item.getItemId() == R.id.action_about) { 
    startActivity(new Intent(this, AboutScreen.class)); 
    return true; 
    } 
    return super.onOptionsItemSelected(item); 
    } 

    /** 
    * A {@link FragmentPagerAdapter} that returns a fragment corresponding to 
    * one of the sections/tabs/pages. 
    */ 


    public static class CheckDialog extends DialogFragment { 

    String message; 

    @Override 
    public Dialog onCreateDialog (Bundle savedInstanceState) { 
    return new AlertDialog.Builder(getActivity()).setTitle("Check Your Work").setMessage(message) 
    .setNegativeButton("CLOSE", new DialogInterface.OnClickListener() { 
    @Override 
    public void onClick(DialogInterface dialog, int which) { 
    dialog.cancel(); 
    } 
    }).show(); 
    } 

    @Override 
    public void onStart() { 
    super.onStart(); 
    ((AlertDialog) getDialog()).getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(Color.RED); 
    } 

    public void setMessage(String message) { 
    this.message = message; 
    } 
    } 

    public class SectionsPagerAdapter extends FragmentPagerAdapter { 

    SectionsPagerAdapter(FragmentManager fm) { 
    super(fm); 
    } 

    @Override 
    public Fragment getItem(int position) { 
    switch(position) { 
    case 0: 
    return fragmentTab1; 
    case 1: 
    return fragmentTab2; 
    case 2: 
    return fragmentTab3; 
    default: 
    return null; 
    } 
    } 

    @Override 
    public int getCount() { 
    // Show 3 total pages. 
    return 3; 
    } 
    } 
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM