Search code examples
androidonclicklistenerandroid-custom-viewonresume

Listener won't work


I'm trying to set a Listener for my custom views that I put in a LinearLayout. Those views are created by code depending on a certain files or data, so I don't know the number of views there is. The OnClickListener is being set, but onClick() is never called:

@Override
    protected void onResume() {
        super.onResume();
        try {
            setupBackEnd();
        } catch (IOException e) {
            Toast.makeText(this, "Error Reading or Writing data in Storage, Try to restart the App", Toast.LENGTH_LONG).show();
            e.printStackTrace();
        }

        Toast.makeText(DayActivity.this, "Child count: " + linearList.getChildCount(), Toast.LENGTH_SHORT).show();
        for (int i = 0; i < linearList.getChildCount(); i++) {
            linearList.getChildAt(i).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Toast.makeText(DayActivity.this, "clicked", Toast.LENGTH_SHORT).show();
                }
            });
        }
    }

This is my code. To make sure the child views are already there I showed a Toast and it gave me "Child Count: 5" but "clicked" Toast never shows up. I made sure that My custom Views are clickable (The childs of linearlist). But the listener won't work for some reason. Anyone knows why?

Edit: After I tried to debug the code I got this error:

10-27 18:52:26.309 17630-17630/osm_cave.timecave E/AndroidRuntime: FATAL EXCEPTION: main
                                                                   Process: osm_cave.timecave, PID: 17630
                                                                   android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@672721e is not valid; is your activity running?
                                                                       at android.view.ViewRootImpl.setView(ViewRootImpl.java:679)
                                                                       at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:342)
                                                                       at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
                                                                       at android.widget.Toast$TN.handleShow(Toast.java:459)
                                                                       at android.widget.Toast$TN$2.handleMessage(Toast.java:342)
                                                                       at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                       at android.os.Looper.loop(Looper.java:154)
                                                                       at android.app.ActivityThread.main(ActivityThread.java:6119)
                                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
c

This error won't be shown when I launch the app without debugging it only appears when Debugging with breakpoints. This error is supposed to mean I'm trying to use a context that no longer exist but I'm not so what's the problem here??


Solution

  • It looks like your toast message is running into an error.

     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
     at android.widget.Toast$TN.handleShow(Toast.java:459)
     at android.widget.Toast$TN$2.handleMessage(Toast.java:342)
     at android.os.Handler.dispatchMessage(Handler.java:102)
    

    If I remember correctly, the new object that you are creating of type View.OnClickListener (since it is anonymous) cannot access the DayActivity.this attribute. Instead you should get the activity from the view.

    public void onClick(View view) {
        Activity activity = (Activity) view.getContext()
        Toast.makeText(activity, "clicked", Toast.LENGTH_SHORT).show();
    }
    

    While there's nothing wrong with using a Toast message to test for an event occurring, I would recommend simplifying to just using a log message. Log messages aren't context sensitive are unlikely to fail except if you provide a null message to it.

    If Log messages are not working, the next troubleshooting step should be to examine the custom views and view hierarchy. If any clickable transparent views are in front of the custom views, they would intercept the click events. Double check that the view itself is clickable as well.