13

So, my problem is that OnClickListener doesn't work when I set android:clickable="true" into my class.

This is MyClass xml code:

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/background"
    android:clickable="true">
...
...
</RelativeLayout>

MyClass.java:

public class MyClass extends RelativeLayout implements OnClickListener {
    public MyClass(Context context) {
        super(context);

        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.book_item, this);
        setOnClickListener(this);
    }

    public void onClick(View v) {
        Log.v("TAG", "Hello");
    }
...
...
}

It works fine when I set android:clickable to false. What do I wrong?

Onik
  • 19,396
  • 14
  • 68
  • 91
Scit
  • 1,722
  • 4
  • 15
  • 18

5 Answers5

20

Setting an OnClickListener will automatically set the clickable property to true. The code you are showing is confusing though. My understanding is that your MyClass view is the parent of the RelativeLayout shown in the XML file.

If so, the child RelativeLayout will get the touch events first (since it's clickable) but won't do anything with them since it doesn't have a click listener.

Just remove clickable=true from your XML.

Seraphim's
  • 12,559
  • 20
  • 88
  • 129
Romain Guy
  • 97,993
  • 18
  • 219
  • 200
11

when you do this: android:clickable="true" you disable the onClickListener (its not logical but its like that..).

So set it to "false" or just remove this line from your XML file ;)

Jake1164
  • 12,291
  • 6
  • 47
  • 64
eento
  • 761
  • 4
  • 20
  • 53
5

Add id to your layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/yourId"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/background"
android:clickable="true">
</RelativeLayout>

Then in java code:

public class MyClass extends RelativeLayout implements OnClickListener {
    public MyClass(Context context) {
        super(context);

        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.book_item, this);
        findViewById(R.id.yourId).setOnClickListener(this);
    }

    public void onClick(View v) {
        Log.v("TAG", "Hello");
    }
...
...
}
Shawn Chin
  • 84,080
  • 19
  • 162
  • 191
1
 ((RelativeLayout)findViewById(R.id.yourId)).setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
                //code area ...
                Log.v("TAG", "Hello");

                return true;
            } else{
                return false;
            }
        }
    });

You can use this way too.

ercanpinar
  • 216
  • 3
  • 14
0

Instead of implementing OnClickListener to the whole class, you can set OnClickListener to each of the elements after filtering them if there are only few elements to do actions.

TextView textLogin = findViewById(R.id.textLogin);

textLogin.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Log.i("click", "textLoginClicked.");
    }
});

Else you should state that the elements you are going to set OnClickListener like,

textLogin.setOnClickListener(this);

Then you can use,

@Override
public void onClick(View view) {
    if (view.getId() == R.id.textLogin) {
        Log.i("Click", "Login clicked.");
    }
}
Wimukthi Rajapaksha
  • 961
  • 1
  • 11
  • 23