2

I'm using a custom grid adapter that creates image buttons and displays them on an activity, using the method SetImageResource() to set the src image of the buttons.

However, when clicked, these buttons do not have the desired button click/ripple effect. After looking around, I found a couple of solutions for that, utilising a TypedValue with SetBackgroundResource(), or utilising a TypedArray with SetBackgroundDrawable(). Without the image resource, either of these methods work, but upon adding the image resource, the selectableItemBackground effect disappears.

The code is as following:

ImageButton button;

if (convertView == null)
{
    LayoutInflater inflater = (LayoutInflater)context.GetSystemService(Context.LayoutInflaterService);

    //  Grid buttons
    convertView = inflater.Inflate(Resource.Layout.sublayout_Menu_Button, null);

    button = convertView.FindViewById<ImageButton>(Resource.Id.mainMenu_ImgBtn);

    button.SetMinimumHeight(Main_Menu.GRID_HEIGHT / numRows);

    TypedValue tv = new TypedValue();
    context.Theme.ResolveAttribute(Resource.Attribute.selectableItemBackground, tv, true);
    button.SetBackgroundResource(tv.ResourceId);

    //  This code is another method that works similarly to the above                
    //int[] attrs = new int[] { Android.Resource.Attribute.SelectableItemBackground };
    //TypedArray ta = context.ObtainStyledAttributes(attrs);
    //Drawable drawableFromTheme = ta.GetDrawable(0);
    //ta.Recycle();
    //button.SetBackgroundDrawable(drawableFromTheme);

    button.SetImageResource(buttonImages[position]);

    switch (position)
    {
        case 0:
            button.Click += delegate
            {
                Intent intent = new Intent(context, typeof(Select_Hospital));
                context.StartActivity(intent);
            };
            break;

        case 1:
            button.Click += delegate
            {
                Intent intent = new Intent(context, typeof(My_Appointments));
                context.StartActivity(intent);
            };
            break;

        case 2:
            button.Click += delegate
            {
                Intent intent = new Intent(context, typeof(Treatment_Information));
                context.StartActivity(intent);
            };
            break;

        case 3:
            button.Click += delegate
            {
                Intent intent = new Intent(context, typeof(Search));
                context.StartActivity(intent);
            };
            break;
    }
}

How can I resolve this problem? Any help would be very much appreciated!

--EDIT--

MyImageButton code:

class MyImageButton : ImageButton, IOnTouchListener
{
    private Context context;

    public MyImageButton(Context context, IAttributeSet attrs) : base(context, attrs)
    {
        this.context = context;
        this.SetOnTouchListener(this);
    }

    public bool OnTouch(View v, MotionEvent e)
    {
        if (e.Action == MotionEventActions.Down)
        {
            ImageView iv = (ImageView)v;
            iv.SetColorFilter(new Android.Graphics.Color(context.GetColor(Resource.Color._5_grey)));
        }
        else if (e.Action == MotionEventActions.Up)
        {
            ImageView iv = (ImageView)v;
            iv.ClearColorFilter();
        }
        return true;
    }
};

AXML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Dental_IT.Droid.Adapters.MyImageButton
        android:id="@+id/mainMenu_ImgBtn"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:background="@null" />
</LinearLayout>
Ryalis
  • 147
  • 1
  • 15

1 Answers1

1

when clicked, these buttons do not have the desired button click/ripple effect.

When click the ImageButton, it did has a button click/ripple effect, but it was covered by images.

You could custom a ImageButton to handle with the touch event, when receive a click event, you could add a ColorFilter on the image to implement your click/ripple effect.

Here is my code :

public class MyImageButton : ImageButton
{
    public float[] BT_SELECTED_DARK = new float[] { 1, 0, 0, 0, -50, 0, 1,
            0, 0, -50, 0, 0, 1, 0, -50, 0, 0, 0, 1, 0 };

    public MyImageButton(Context context, IAttributeSet attrs):base(context,attrs)
    {
    }

    public override bool OnTouchEvent(MotionEvent e)
    {
        if (e.Action == MotionEventActions.Down)
        {
            this.SetColorFilter(new ColorMatrixColorFilter(BT_SELECTED_DARK));
        }
        else if (e.Action == MotionEventActions.Up)
        {
            this.ClearColorFilter();
        }
        return base.OnTouchEvent(e);
    }
}

When you adding the image resource :

button.SetImageResource(Resource.Drawable.download);
button.Click += (sender, e) =>
{
    Toast.MakeText(this,"Hi, I am York!",ToastLength.Short).Show();
};

Effect :

enter image description here

York Shen
  • 9,014
  • 1
  • 16
  • 40
  • The animation does work, but the click delegate events don't work now – Ryalis Aug 05 '17 at 07:11
  • @Ryalis, I will update my answer when I can use my computer. – York Shen Aug 05 '17 at 07:47
  • Sure, no problem. Also, would you mind explaining how the code works? – Ryalis Aug 05 '17 at 08:11
  • I have updated my post with the click delegates that do not work – Ryalis Aug 05 '17 at 22:16
  • @Ryalis, I use your code and it works fine by my side, you could debug your code to find the reason. If possible, you could share a basic demo to reproduce this problem, troubleshooting this issue will be much easier if I have a demo. – York Shen Aug 06 '17 at 07:43
  • I'm using a custom grid adapter to populate the buttons. I've tried a simple click delegate to test the functionality, but even then it does not do anything. – Ryalis Aug 06 '17 at 11:10
  • @Ryalis, that's strange, it should be work. Could you please share a basic demo that can reproduce this problem? I cant reproduce your problem. – York Shen Aug 06 '17 at 11:19
  • Sorry, I am not able to share a basic demo at the moment. Could [this](https://stackoverflow.com/questions/5159366/cant-handle-both-click-and-touch-events-simultaneously) be the reason why it isn't working? – Ryalis Aug 06 '17 at 11:31
  • Updated the post. – Ryalis Aug 06 '17 at 11:48
  • @Ryalis, please update your `MyImageButton` code as my answer, then try again, : ) – York Shen Aug 06 '17 at 11:52
  • Thank you! That works, but only after I add `this.context = context;` in the `MyImageButton` constructor – Ryalis Aug 06 '17 at 12:14
  • @Ryalis, when you implement `IOnTouchListener` interface in `MyImageButto` class, the click event was was intercepted by `OnTouchEvent` method, that's the reason why click delegates that do not work. – York Shen Aug 06 '17 at 12:14