1

I am making some kind of puzzle game where there will be a lot of blocks that are made of ImageView(s). Now in this case, I have only setOnClickListener to imageView1, now rather than me writing the same block of setOnClickListener for each ImageView, how do I write the setOnclickListener once for all the ImageView(s) ??

Here's the sample code

MainActivity.java

public class MainActivity extends Activity {

    ImageView imageView1, imageView2, imageView3;
    int x, y;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        x = 0;
        y = 0;

        imageView1 = (ImageView) findViewById(R.id.image1);
        imageView2 = (ImageView) findViewById(R.id.image2);
        imageView3 = (ImageView) findViewById(R.id.image3);

        imageView1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                TranslateAnimation animation = new TranslateAnimation(0, 0, 0, 50);
                animation.setDuration(1000);
                animation.setFillAfter(false);
                animation.setAnimationListener(new MyAnimationListener());

                imageView1.startAnimation(animation);
                x += 0;
                y += 50;

            }
        });
    }

    private class MyAnimationListener implements Animation.AnimationListener {

        @Override
        public void onAnimationStart(Animation animation) {

        }

        @Override
        public void onAnimationEnd(Animation animation) {
            imageView1.clearAnimation();
            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(imageView1.getWidth(),
                imageView1.getHeight());
            lp.setMargins(x, y, 0, 0);
            imageView1.setLayoutParams(lp);
        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    }
}

All suggestions and improvements of my codes are greatly welcomed. Thanks in advance.

Charas
  • 1,753
  • 4
  • 21
  • 53

6 Answers6

4

You can try to create your listener in a variable and then assign it to each ImageView. Something like this:

imageView1 = (ImageView) findViewById(R.id.image1);
        imageView2 = (ImageView) findViewById(R.id.image2);
        imageView3 = (ImageView) findViewById(R.id.image3);

        View.OnClickListener listener= new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                TranslateAnimation animation = new TranslateAnimation(0, 0, 0, 50);
                animation.setDuration(1000);
                animation.setFillAfter(false);
                animation.setAnimationListener(new MyAnimationListener());

                if(v==imageView1)
                imageView1.startAnimation(animation);
                else  if(v==imageView2)
                    imageView2.startAnimation(animation);
                else  if(v==imageView3)
                    imageView3.startAnimation(animation);
                x += 0;
                y += 50;

            }
        };

        imageView1.setOnClickListener(listener);
        imageView2.setOnClickListener(listener);
        imageView3.setOnClickListener(listener);

Try to use this:

imageView1 = (ImageView) findViewById(R.id.image1);
        imageView2 = (ImageView) findViewById(R.id.image2);
        imageView3 = (ImageView) findViewById(R.id.image3);

        View.OnClickListener listener= new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                TranslateAnimation animation = new TranslateAnimation(0, 0, 0, 50);
                animation.setDuration(1000);
                animation.setFillAfter(false);

                ImageView vista=(ImageView) v;
                animation.setAnimationListener(new MyAnimationListener(vista));


                vista.startAnimation(animation);

                x += 0;
                y += 50;

            }
        };

        imageView1.setOnClickListener(listener);
        imageView2.setOnClickListener(listener);
        imageView3.setOnClickListener(listener);

        private class MyAnimationListener implements Animation.AnimationListener {

            ImageView selected;
            public MyAnimationListener(ImageView vista)
            {
                selected=vista;
            }

            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                selected.clearAnimation();
                RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(selected.getWidth(),
                        selected.getHeight());
                lp.setMargins(x, y, 0, 0);
                selected.setLayoutParams(lp);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        }
Kevin Sanchez
  • 2,215
  • 2
  • 11
  • 19
  • Thank you for your answer, yes, I think this will work, but in my games, I will have possible more than 20 imageViews(s). So is there a way to simplify the if else block statement ? – Charas Sep 15 '15 at 17:18
  • Oh and you forgot to set the LayoutParams, this codes only perform animation of the ImageView, but does not move the real ImageView, that's why I called MyAnimationListener class, now how do I detect which ImageView is being clicked and pass it on to the MyAnimationListener class ? – Charas Sep 15 '15 at 17:28
  • I think you have to add a parameter in your MyAnimationListener and try to send the ImageView as a parameter. I think you just have to cast the view that comes as the parameter of the listener into an ImageView. – Kevin Sanchez Sep 15 '15 at 17:35
  • Yup Arsal Imam has given the full solution, instead of using the if else block statement, just write v.startAnimation(animation), and yup added parameter to the listener. Thank you for your help. – Charas Sep 15 '15 at 17:40
2

You can implement your custom OnClickListener with the Activity like below,

public class MainActivity extends Activity implements View.OnClickListener{

    ImageView imageView1, imageView2, imageView3;
    int x, y;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        x = 0;
        y = 0;

        imageView1 = (ImageView) findViewById(R.id.image1);
        imageView2 = (ImageView) findViewById(R.id.image2);
        imageView3 = (ImageView) findViewById(R.id.image3);

        imageView1.setOnClickListener(this);
        imageView2.setOnClickListener(this);
        imageView3.setOnClickListener(this);
    }
@Override
public void onClick(View v) {
   TranslateAnimation animation = new TranslateAnimation(0, 0, 0, 50);
                animation.setDuration(1000);
                animation.setFillAfter(false);
                animation.setAnimationListener(new MyAnimationListener(v));

                v.startAnimation(animation);
                x += 0;
                y += 50;
}
    private class MyAnimationListener implements Animation.AnimationListener {
        private View mView;

        public MyAnimationListener(View v)
       {
           this.mView = v;
       }
        @Override
        public void onAnimationStart(Animation animation) {

        }

        @Override
        public void onAnimationEnd(Animation animation) {
            mView.clearAnimation();
            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(mView.getWidth(),
                mView.getHeight());
            lp.setMargins(x, y, 0, 0);
            mView.setLayoutParams(lp);
        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    }
}
Arsal Imam
  • 2,882
  • 2
  • 24
  • 35
1
Create a distinct listener:

View.OnclickListener listener = new View.OnClickListener() {
            @Override 
            public void onClick(View v) {
                TranslateAnimation animation = new TranslateAnimation(0, 0, 0, 50);
                animation.setDuration(1000);
                animation.setFillAfter(false);
                animation.setAnimationListener(new MyAnimationListener());

                v.startAnimation(animation);
                x += 0;
                y += 50;

            } 
        }; 

then set the listener to your views: imageView1.setOnClickListener(listener); imageView2.setOnClickListener(listener); imageView3.setOnClickListener(listener);

Mateus Brandao
  • 900
  • 5
  • 9
  • This will only animate imageView1 ! – vilpe89 Sep 15 '15 at 17:07
  • Still... you are refering to imageView1. I assume that he wants to animate the ImageView which gets clicked. – vilpe89 Sep 15 '15 at 17:09
  • Hi, Thank you very much for your answer, I just implemented your solution, and it only moved imageView1, I think its because inside the onClick(View v) method, its only written imageView1.startAnimation(animation), how do I detect which ImageView is being clicked ? Thank you again. – Charas Sep 15 '15 at 17:15
  • Hi, i did not catch that specific part of your question, sorry. Refer to Kelvin's answer, he answered that. – Mateus Brandao Sep 15 '15 at 17:17
0

Let MainActivity implements OnClickListener and call

public class MainActivity extends Activity implements OnClickListener {

    ImageView imageView1, imageView2, imageView3;
    int x, y;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        x = 0;
        y = 0;

        imageView1 = (ImageView) findViewById(R.id.image1);
        imageView2 = (ImageView) findViewById(R.id.image2);
        imageView3 = (ImageView) findViewById(R.id.image3);
        imageView1.setOnClickListener(this);
        imageView2.setOnClickListener(this);
        imageView3.setOnClickListener(this);

    @Override
    public void onClick(View v) {
        switch(v.getId()){
        case R.id.image1:
            TranslateAnimation animation = new TranslateAnimation(0, 0, 0, 50);
            animation.setDuration(1000);
            animation.setFillAfter(false);
            animation.setAnimationListener(new MyAnimationListener());

            imageView1.startAnimation(animation);
            x += 0;
            y += 50;
        break;
        case R.id.image2:
        break;
        case R.id.image3:
        break;
        }
    }
}
elcolto
  • 961
  • 7
  • 11
  • Could you provide me with the codes to implements the OnClickListener, so that each time the OnClickListener is called, it is able to detect which ImageView is being clicked ? Thank you. – Charas Sep 15 '15 at 17:16
0

You can always extend your class as activity and implement OnClickListener. Then you should override the OnClick function. It takes a view as parameter that you can check if it is your intended view (i.e. your Imageviews)

eg:

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;

/**
 * Created by Rohan on 15-09-2015.
 */
public class MyActivity extends Activity implements View.OnClickListener{

    ImageView imageView1, imageView2, imageView3;
    int x, y;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        x = 0;
        y = 0;

        imageView1 = (ImageView) findViewById(R.id.image1);
        imageView2 = (ImageView) findViewById(R.id.image2);
        imageView3 = (ImageView) findViewById(R.id.image3);

        imageView1.setOnClickListener(this);
        imageView2.setOnClickListener(this);
        imageView3.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if(v.getId() == R.id.image1 || v.getId() == R.id.image2 || v.getId() == R.id.image3 ){
            //Do your stuff
        }
    }
}
Rohan
  • 74
  • 4
0

Although your code is in Java, there is an easy way in kotlin that someone could find useful. You can create an extension function for a list of views.

Extension function:

fun List<View>.setOnClickListener(onClickView: () -> Unit) {
    this.forEach { it.setOnClickListener { onClickView.invoke() } }
}

How to use it:

listOf(ImageView, ImageView2, ImageView3).setOnClickListener { 
    // put your action here 
}
Noelia
  • 3,698
  • 4
  • 17
  • 22