0

I'm having an issue linking two buttons from a fragment to a class. I have one working but any attempt to get the second linking to a different class is failing. Here is the code I have for the one Button. Thanks in advance!

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

    View view = inflater.inflate(R.layout.account, container, false);

    Button button = (Button)view.findViewById(R.id.btGlobex);
    button.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v){
            switch(v.getId()){

                case R.id.btGlobex:
                    Intent intent = new Intent(getActivity(), GlobexActivity.class);
                    startActivity(intent);//Edited here
                    break;
            }
        }
    });

    return view;
}

UPDATE: I've gotten some great responses but my app crashes when I click on the account Fragment and I can't figure out as to why. The updated Code is as follows:

public class AccountFragment extends Fragment implements View.OnClickListener{

    public AccountFragment() {

    }

    public static AccountFragment newInstance() {
        AccountFragment fragment = new AccountFragment();
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.account, container, false);

        Button btGlobex = (Button)getView().findViewById(R.id.btGlobex);
        btGlobex.setOnClickListener(onClickListener);
        Button btUmbrella = (Button)getView().findViewById(R.id.btUmbrella);
        btUmbrella.setOnClickListener(onClickListener);
        return view;
    }

    private View.OnClickListener onClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v){
            switch(v.getId()){

                case R.id.btGlobex:
                    Intent intent1 = new Intent(getActivity(), GlobexActivity.class);
                    startActivity(intent1);//Edited here
                    break;
                case R.id.btUmbrella:
                    Intent intent2 = new Intent(getActivity(), UmbrellaActivity.class);
                    startActivity(intent2);//Edited here
                    break;
            }
        }
    };

    @Override
    public void onClick(View view) {

    }
}

I'm receiving the following error log

03-08 20:10:40.974 5458-5458/com.qreceipts.qreceipts E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.qreceipts.qreceipts, PID: 5458
java.lang.NullPointerException
at com.qreceipts.qreceipts.AccountFragment.onCreateView(AccountFragment.java:29)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2189)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1299)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:757)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2355)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2146)
at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2098)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2008)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:710)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5021)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:827)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:643)
at dalvik.system.NativeStart.main(Native Method)

Thanks again for any help!

Shivam Kumar
  • 1,892
  • 2
  • 21
  • 33
NiamLeeson
  • 13
  • 1
  • 5
  • So is this the code for the button that works, or the button that doesn't work? – dahui Mar 08 '17 at 16:29
  • That's the code for the button that works. I have a second button called btUmbrella that I can't seem to get working I've tried a few variations of this code but to no avail. – NiamLeeson Mar 08 '17 at 16:33
  • Post the code that doesn't work, no one is going to be able to troubleshoot code they can't see – dahui Mar 08 '17 at 16:37
  • Just added the non working code there! – NiamLeeson Mar 08 '17 at 16:52
  • Cool, see my answer – dahui Mar 08 '17 at 17:11
  • Hey dahui Thanks for the code but when i'm clicking the account fragment on the app it's now crashing. I can post the implemented code up it's probably something small but I can't figure it out! – NiamLeeson Mar 08 '17 at 17:51
  • Do you get any error message in Android Studio when the app crashes? It should give you a stack trace pointing to the line where it breaks – dahui Mar 09 '17 at 11:38
  • I've added the error log to the post. thanks again for your help – NiamLeeson Mar 09 '17 at 14:25
  • I've gotten it working turned out I had miss labeled something in the xml file. Rookie mistake! Thanks again for all the help! – NiamLeeson Mar 09 '17 at 14:29

2 Answers2

1

I think the problem is that when you do

Button button = (Button)view.findViewById(R.id.btGlobex);

This button is always going to be linked to R.id.btGlobex, so your v.getId() switch case is always going to get the id of R.id.btGlobex

If you want your second button to start the intent with a different class, you need to either do what you did for your first button by findViewById on your second button and add an onClickListener to it that start your second class, or implement the onClickListener interface like this I think:

public class YourFragment extends Fragment implements View.OnClickListener {

And do this for your buttons in your onCreateView:

Button button = (Button) view.findViewById(R.id.button1);
button.setOnClickListener(this);

Button button2 = (Button) view.findViewById(R.id.button2);
button2.setOnClickListener(this);

Then put your switch cases outside the onCreateView as its own method:

@Override
public void onClick(View v) {
    // Switch cases here
}

See this answer for more info.


Maybe you should set your onClickListener like this?

public class YourFragment extends Fragment implements View.OnClickListener {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.account, container, false);

        Button btGlobex = (Button) view.findViewById(R.id.btGlobex);
        btGlobex.setOnClickListener(this);

        Button btUmbrella = (Button) view.findViewById(R.id.btUmbrella);
        btUmbrella.setOnClickListener(this);

        return view;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btGlobex:
                Intent intent1 = new Intent(getActivity(), GlobexActivity.class);
                startActivity(intent1);
                break;
            case R.id.btUmbrella:
                Intent intent2 = new Intent(getActivity(), UmbrellaActivity.class);
                startActivity(intent2);
                break;
            default:
                break;
        }
    }
Community
  • 1
  • 1
Aimy_N_Chu
  • 126
  • 6
  • I've tried something similar but can't get it to work. I'm not sure if it's done differently in a fragment to an Activity. (I'm quite new to android!) – NiamLeeson Mar 08 '17 at 16:59
  • In your non-working code, could you try putting the onClick as its own method outside of onCreateView? – Aimy_N_Chu Mar 08 '17 at 17:06
  • I added an update. And also you totally should check out that link I posted for how to use onClickListener, it has some good examples I think. – Aimy_N_Chu Mar 08 '17 at 17:16
0

After seeing the updated code, the problem is clear. In the first case you are creating a new anonymous OnClickListener and assigning it to just your button.

When you add a second button you are assigning "this" to be the new listener, however if your class does not implement OnClickListener and provide an onClick method, then this won't work.

You can create a listener to use, make it a class level variable so you can use it throughout the class. This means you need to define it outside your onCreateView method, as a private member.

private OnClickListener onClickListener = new OnClickListener() {
    @Override
    public void onClick(View v){
        switch(v.getId()){

            case R.id.btGlobex:
                Intent intent1 = new Intent(getActivity(), GlobexActivity.class);
                startActivity(intent1);//Edited here
                break;
            case R.id.btUmbrella:
                Intent intent2 = new Intent(getActivity(), UmbrellaActivity.class);
                startActivity(intent2);//Edited here
                break;
        }
    }
}

Now your class provides an implementation of the OnClickListener interface, and you can now pass this listener to your buttons.

Button btGlobex = (Button)findViewById(R.id.btGlobex);
btGlobex.setOnClickListener(onClickListener);
Button btUmbrella = (Button)findViewById(R.id.btUmbrella);
btUmbrella.setOnClickListener(onClickListener);
return view;

In your second example, you are passing "this" to the buttons, which isn't working how you are expecting. You are creating an anonymous OnClickListener which is never being used, when you are using the "this" keyword, it's trying to pass in the entire class. Unless your class implements the OnClickListener interface, and provides an implementation of the onClick method, that will not work.

dahui
  • 2,128
  • 2
  • 21
  • 40