setOnClickListener not works in Canvas and FrameLayout

36 Views Asked by At

I am making a qr code scanning screen. There is a camera view in the background and scanning animation on it. At the bottom there are two image views that I added programmatically. These image views are drawn on a FrameLayout. Neither image view nor layout is clicked. I added button, image button instead of ImageView but setOnClickListener did not work.

I tried:

  • I gave id to image views (values/ids.xml) and it did not work.
  • Image view bringToFront() did not work
  • I made the layout clickable and focusable but it didn't work again

Draw method

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint = new Paint();

        if (!isUserPremium) {
            prepareAlertText(canvas);
        }

        drawKeyboardBtn(canvas);
        drawFlashButton(canvas);
        drawRectangleAndLine(canvas, paint);
    }

drawKeyboardBtn function

private void drawKeyboardBtn(Canvas canvas) {
        int leftPadding = (int) (getWidth() * 0.23);
        int topPadding = (int) (getHeight() * 0.85);
        int layoutWidth = (int) (getHeight() * 0.1);
        int layoutHeight = (int) (getHeight() * 0.1);


        ImageView keyboardImageView = new ImageView(getContext());
        FrameLayout frameLayout = new FrameLayout(getContext());

        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(layoutWidth, layoutHeight);

        layoutParams.setMargins(leftPadding, topPadding, 0, 0);
        keyboardImageView.setLayoutParams(layoutParams);

        keyboardImageView.setImageResource(R.drawable.ic_keyboard);
        keyboardImageView.setBackgroundResource(R.drawable.rounded_corner);
        keyboardImageView.setPadding(15, 15, 15, 15);

        frameLayout.setLayoutParams(layoutParams);
        frameLayout.addView(keyboardImageView);

        keyboardImageView.setClickable(true);
        keyboardImageView.setFocusable(true);
        keyboardImageView.setFocusableInTouchMode(true);


        //Also not worked
        //frameLayout.setClickable(true);
        //frameLayout.setFocusable(true);
        //frameLayout.setFocusableInTouchMode(true);

        //Also not worked
        // frameLayout.setOnClickListener(v -> {
        //    Log.e("GraphicOverlay", "onClick: " + v.getId());
        //    Toast.makeText(v.getContext(), "Keyboard clicked", Toast.LENGTH_LONG).show();
        // });

        keyboardImageView.setOnClickListener(v -> {
            Log.e("GraphicOverlay", "onClick: " + v.getId());
            Toast.makeText(v.getContext(), "Keyboard clicked", Toast.LENGTH_LONG).show();
        });

        frameLayout.measure(getWidth(), getHeight());
        frameLayout.layout(leftPadding, topPadding, leftPadding, topPadding);

        frameLayout.draw(canvas);
    }

UI View

Full Code Github Repo

1

There are 1 best solutions below

0
usr153.K On

onDraw(..) is called whenever UI is rendered / displaying / created. And these keyboardImageView and frameLayout are generated when entering onDraw(..) and cleaned when leaving onDraw() (because these are local variables).

How about redesigning your UI hierarchy like below? Basically, we shouldn't create AndroidViews nor anything such as Paint() inside onDraw(..).

<FrameLayout ... >
  <CameraView .. />
  
  <KeyboardView .. 
     onClick="onclickKeyboardButton" />

  <Button .. 
     onClick="onClick..." />

</FrameLayout>