【问题标题】:How to set the same OnClickListener to all(multiple) ImageView(s)如何将相同的 OnClickListener 设置为所有(多个)ImageView
【发布时间】:2015-09-15 17:00:44
【问题描述】:

我正在制作某种益智游戏,其中会有很多由 ImageView(s) 组成的块。现在在这种情况下,我只有 setOnClickListener 到 imageView1,而不是我为每个 ImageView 编写相同的 setOnClickListener 块,如何为所有 ImageView 编写一次 setOnclickListener??

这是示例代码

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) {

        }
    }
}

非常欢迎对我的代码提出的所有建议和改进。提前致谢。

【问题讨论】:

    标签: java android imageview android-animation android-imageview


    【解决方案1】:

    您可以尝试在变量中创建侦听器,然后将其分配给每个 ImageView。像这样的:

    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);
    

    尝试使用这个:

    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) {
    
                }
            }
    

    【讨论】:

    • 感谢您的回答,是的,我认为这会起作用,但在我的游戏中,我可能会有超过 20 个图像视图。那么有没有办法简化 if else 块语句?
    • 哦,你忘了设置 LayoutParams,这段代码只执行 ImageView 的动画,但不移动真正的 ImageView,这就是我调用 MyAnimationListener 类的原因,现在我如何检测哪个 ImageView 正在单击并将其传递给 MyAnimationListener 类?
    • 我认为您必须在 MyAnimationListener 中添加一个参数并尝试将 ImageView 作为参数发送。我认为您只需要将作为侦听器参数的视图转换为 ImageView。
    • 是的,Arsal Imam 给出了完整的解决方案,而不是使用 if else 块语句,只需编写 v.startAnimation(animation),并为监听器添加参数。感谢您的帮助。
    【解决方案2】:

    您可以使用下面的 Activity 来实现您的自定义 OnClickListener,

    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) {
    
            }
        }
    }
    

    【讨论】:

    • @Charas,最简单的方法是使用上面的一个 clicklistener 实现所有 imageViews
    • 感谢您的回答,它确实会移动每个 ImageView,但是 MyAnimationListener 类仍然只设置 imageView1 的 layoutParams,如何检测正在按下哪个 ImageView 并在 MyAnimationListener 类中设置 LayoutParams?
    • 一分钟,我正在更新我的答案
    • 好的,现在可以查看了,我用onClick()方法更新了AnimationListener
    • 酷!只需要在调用类时添加参数,很好。非常感谢先生。
    【解决方案3】:
    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;
    
                } 
            }; 
    

    然后将监听器设置为您的视图: imageView1.setOnClickListener(listener); imageView2.setOnClickListener(listener); imageView3.setOnClickListener(listener);

    【讨论】:

    • 这只会为 imageView1 设置动画!
    • 仍然...您指的是 imageView1。我假设他想为被点击的 ImageView 设置动画。
    • 您好,非常感谢您的回答,我刚刚实现了您的解决方案,它只移动了 imageView1,我认为是因为在 onClick(View v) 方法内部,它只写了 imageView1.startAnimation(动画),如何检测正在单击哪个 ImageView ?再次感谢您。
    • 嗨,我没有听懂你问题的具体部分,抱歉。参考 Kelvin 的回答,他是这么回答的。
    【解决方案4】:

    您始终可以将您的类扩展为活动并实现 OnClickListener。然后你应该重写 OnClick 函数。它将视图作为参数,您可以检查它是否是您的预期视图(即您的 Imageviews)

    例如:

    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
            }
        }
    }
    

    【讨论】:

    • 感谢您的回答,但是 v.getId() 不会返回一个 int 吗?
    • 是的,我正在将一个 int(v.getId()) 与另一个 int (R.id.image1) 进行比较。
    【解决方案5】:

    让MainActivity实现OnClickListener并调用

    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;
            }
        }
    }
    

    【讨论】:

    • 您能否提供实现 OnClickListener 的代码,以便每次调用 OnClickListener 时,它都能检测到哪个 ImageView 被点击?谢谢。
    【解决方案6】:

    虽然您的代码在Java 中,但kotlin 中有一个简单的方法,有人会发现它很有用。您可以为视图列表创建一个扩展函数

    扩展功能:

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

    如何使用:

    listOf(ImageView, ImageView2, ImageView3).setOnClickListener { 
        // put your action here 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多