Android onClick method doesn't work on a custom view

后端 未结 10 1848
南旧
南旧 2021-01-01 09:32

I\'ve started working on an app. I build the menu yesterday but the onClick method doesn\'t work! I created a class that extends View and called her MainMenuObject - that cl

相关标签:
10条回答
  • 2021-01-01 10:06

    I had the same problem. In my case I had a LinearLayout as a root element of my custom view, with clickable and focusable set to true, and the custom view tag itself (used in a fragment's layout) was also set to be clickable and focusable. Turns out that the only thing I had to do to get it working was to remove all the clickable and focusable attributes from within the XML :) Counter-intuitive, but it worked.

    0 讨论(0)
  • 2021-01-01 10:10

    In my case I had a RelativeLayout as a parent in my custom view and the only way to make it work was to set focusable and clickable to true in the RelativeLayout and in the constructor of the custom view, after inflating the layout, add this:

    View view = inflate(getContext(), R.layout.layout_my_custom_view, this);
    
    view.findViewById(R.id.theparent).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                performClick();
            }
        });
    
    0 讨论(0)
  • 2021-01-01 10:13

    I've got a solution! It's not really a solution for this specific issue, but a whole new approach. I sent this thread to somebody I know and he told me to use the Animation SDK the android has (like Wireless Designs mentioned), so instead of doing the main menu page with 4 classes, I'm doing it only with one class that extends Activity, and the Animation class offers many animation options. I want to thank you both for helping me, you are great. I'm adding the code if someone will encounter this thread with the same problem or something:

    package elad.openapp;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.HapticFeedbackConstants;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.Window;
    import android.view.animation.Animation;
    import android.view.animation.AnimationSet;
    import android.view.animation.ScaleAnimation;
    import android.view.animation.TranslateAnimation;
    import android.widget.ImageView;
    import android.widget.Toast;
    
    public class OpeningTimes extends Activity implements OnClickListener{
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        // Disabling the title bar..
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.main);
    
        // Create the buttons and title objects
        ImageView title = (ImageView)findViewById(R.id.title_main);
        ImageView search = (ImageView)findViewById(R.id.search_button_main);
        ImageView support = (ImageView)findViewById(R.id.support_button_main);
        ImageView about = (ImageView)findViewById(R.id.about_button_main);
    
        // Setting the onClick listeners
        search.setOnClickListener(this);
        support.setOnClickListener(this);
        about.setOnClickListener(this);
    
        setButtonsAnimation(title, search, support, about);
    
    }
    
    @Override
    public void onClick(View v) {
        if(v.getId()==R.id.search_button_main){
            v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
            startActivity(new Intent(this,SearchPage.class));
        }
        else if(v.getId()==R.id.support_button_main){
            v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
            Toast.makeText(this, "Coming soon...", Toast.LENGTH_LONG).show();
        }
        else if(v.getId()==R.id.about_button_main){
    
            v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
            Toast.makeText(this, "Coming soon...", Toast.LENGTH_LONG).show();
        }
    }
    
    // Setting the animation on the buttons
    public void setButtonsAnimation(ImageView title, ImageView search, ImageView support, ImageView about){
        // Title animation (two animations - scale and translate)
        AnimationSet animSet = new AnimationSet(true);
    
        Animation anim = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f);
        anim.setDuration(750);
        animSet.addAnimation(anim);
    
        anim = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
                Animation.RELATIVE_TO_SELF, -1.0f, Animation.RELATIVE_TO_SELF, 0.0f);
        anim.setDuration(750);
        animSet.addAnimation(anim);
    
        title.startAnimation(animSet);
    
        // Search button animation
        anim = new TranslateAnimation(Animation.RELATIVE_TO_SELF, -1.5f, Animation.RELATIVE_TO_SELF, 0.0f,
                Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f);
        anim.setDuration(750);
    
        search.startAnimation(anim);
    
        // Support button animation
        anim = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 1.5f, Animation.RELATIVE_TO_SELF, 0.0f,
                Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f);
        anim.setDuration(750);
    
        support.startAnimation(anim);
    
        // About button animation
        anim = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
                Animation.RELATIVE_TO_SELF, 3f, Animation.RELATIVE_TO_SELF, 0.0f);
        anim.setDuration(750);
    
        about.startAnimation(anim);
    }
    }
    
    0 讨论(0)
  • 2021-01-01 10:15

    You can just call performClick() in onTouchEvent of your custom view.

    Use this in you custom view:

        @Override
        public boolean onTouchEvent(final MotionEvent event) {
            if(event.getAction() == MotionEvent.ACTION_UP){
                return performClick();
            }
            return true;
        }
    
    0 讨论(0)
  • 2021-01-01 10:15

    You have to call setOnClickListener(this) in contructor(s) and implement View.OnClickListener on self.

    In this way:

    public class MyView extends View implements View.OnClickListener {
    
        public MyView(Context context) {
            super(context);
            setOnClickListener(this);
        }
    
        public MyView(Context context, AttributeSet attrs) {
            super(context, attrs);
            setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            Toast.makeText(getContext(), "On click.", Toast.LENGTH_SHORT).show();
        }
    }
    
    0 讨论(0)
  • 2021-01-01 10:18

    Implement the onClickListener in the MainMenuObjectView class, since those are the objects that will respond to clicks.
    Another alternative would be to extend Button instead of View, because you are using only buttons in there


    Update: Full example


    This is the idea to implement it directly into the clickable views. There is a TestView class that extends View and overrides onDraw, as you need it to, and also responds to clicks. I left out any animation implementation as you have that part and it's not relevant to the ClickListener discussion.
    I tested it in an Eclair emulator and it works as expected (a Toast message after a click).

    file: Test.java

    package com.aleadam.test;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    
    public class Test extends Activity {
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            LinearLayout ll = new LinearLayout(this);
            ll.setOrientation(LinearLayout.VERTICAL);
            TextView label = new TextView(this);
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
                 LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
            label.setText("Click the circle!");
            TestView testView = new TestView(this);
            ll.addView(label, layoutParams);
            ll.addView(testView, layoutParams);
            setContentView(ll);
        }
    }
    

    file: TestView.java

    package com.aleadam.test;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Toast;
    
    public class TestView extends View implements OnClickListener {
        Context context;
    
        public TestView(Context context) {
            super(context);
            this.context = context;
            setOnClickListener(this);
        }
    
        public void onClick(View arg0) {
            Toast.makeText(context, "View clicked.", Toast.LENGTH_SHORT).show();
        }
    
        @Override
        public void onDraw (Canvas canvas) {
            super.onDraw(canvas);
            this.setBackgroundColor(Color.LTGRAY);
            Paint paint = new Paint (Paint.ANTI_ALIAS_FLAG);
            paint.setColor(Color.RED);
            canvas.drawCircle(20, 20, 20, paint);
        }
    }
    

    If you need some clickable and some not clickable, you can add a constructor with a boolean argument to determine whether the ClickListener is attached or not to the View:

    public TestView(Context context, boolean clickable) {
        super(context);
        this.context = context;
        if (clickable)
            setOnClickListener(this);
    }
    
    0 讨论(0)
提交回复
热议问题