【问题标题】:How can I give an imageview click effect like a button on Android?如何在 Android 上提供像按钮一样的 imageview 点击效果?
【发布时间】:2011-06-04 19:28:08
【问题描述】:

我在我的 Android 应用程序中有 imageview,我使用它就像一个带有 onClick 事件的按钮,但正如您可能猜到的那样,单击时它不会给 imageview 一个可点击的效果。我怎样才能做到这一点?

【问题讨论】:

    标签: java android button imageview


    【解决方案1】:

    您可以使用这样的方式对单个图像执行此操作:

         //get the image view
        ImageView imageView = (ImageView)findViewById(R.id.ImageView);
    
        //set the ontouch listener
        imageView.setOnTouchListener(new OnTouchListener() {
    
            @Override
            public boolean onTouch(View v, MotionEvent event) {
    
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN: {
                        ImageView view = (ImageView) v;
                        //overlay is black with transparency of 0x77 (119)
                        view.getDrawable().setColorFilter(0x77000000,PorterDuff.Mode.SRC_ATOP);
                        view.invalidate();
                        break;
                    }
                    case MotionEvent.ACTION_UP:
                    case MotionEvent.ACTION_CANCEL: {
                        ImageView view = (ImageView) v;
                        //clear the overlay
                        view.getDrawable().clearColorFilter();
                        view.invalidate();
                        break;
                    }
                }
    
                return false;
            }
        });
    

    我可能会将它变成 ImageView 的子类(或 ImageButton,因为它也是 ImageView 的子类)以便于重用,但这应该允许您将“选定”外观应用于 imageview。

    【讨论】:

    • 我还为 ACTION_CANCEL 添加了一个案例,效果很好,谢谢!
    • 好电话 - 我自己在自己的代码中添加了这一点,但也会在这里更新。
    • 这可能是另一个问题,但是在 ACTION_UP 之后我将如何取消?具体来说......用户点击图像。用户将手指拖离图像以取消。但是此代码不会取消操作
    • 我还会添加 MotionEvent.ACTION_OUTSIDE ;)
    • 您可能想要返回false,否则视图的实际onClick() 事件将不会被触发
    【解决方案2】:

    你可以为点击/未点击状态设计不同的图片,并在onTouchListener中设置如下

    final ImageView v = (ImageView) findViewById(R.id.button0);
            v.setOnTouchListener(new OnTouchListener() {
                @Override
                public boolean onTouch(View arg0, MotionEvent arg1) {
                    switch (arg1.getAction()) {
                    case MotionEvent.ACTION_DOWN: {
                        v.setImageBitmap(res.getDrawable(R.drawable.img_down));
                        break;
                    }
                    case MotionEvent.ACTION_CANCEL:{
                        v.setImageBitmap(res.getDrawable(R.drawable.img_up));
                        break;
                    }
                    }
                    return true;
                }
            });
    

    更好的选择是你定义一个选择器如下

    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_selected="true"   
            android:drawable="@drawable/img_down" />
        <item android:state_selected="false"   
            android:drawable="@drawable/img_up" />
    </selector>
    

    并选择事件中的图像:

    v.setOnTouchListener(new OnTouchListener() {
                @Override
                public boolean onTouch(View arg0, MotionEvent arg1) {
                    v.setSelected(arg1.getAction()==MotionEvent.ACTION_DOWN);
                    return true;
                }
            });
    

    【讨论】:

    • 你能解释一下 res.getDrawable res 是做什么的吗?
    • v.setSelected 只会 == true 一次,由于 MotionEvent.ACTION_MOVE 而立即变为 false。一旦松开手指,就会发生 MotionEvent.ACTION_UP。如果使用选择器方法,请使用单独的逻辑来 setSelected 或 setPressed。 if (arg1.getAction() == MotionEvent.ACTION_DOWN) { v.setPressed(true); } else if (arg1.getAction() == MotionEvent.ACTION_UP) { v.setPressed(false); }
    • 最好是MotionEvent.ACTION_DOWN || MotionEvent.ACTION_MOVE,只要我们按下,图像就会一直显示。
    • 你不需要setOnTouchListener(...。您可以简单地创建&lt;selector ...&gt;,然后像&lt;ImageView ... android:clickable="true" android:focusable="true" android:src="@drawable/my_selector" /&gt;一样在XML 中设置ImageView 可点击
    【解决方案3】:

    可以使用 ColorFilter 方法仅处理一个图像文件。但是,ColorFilter 期望使用 ImageViews 而不是 Buttons,因此您必须将您的按钮转换为 ImageViews。如果您仍然使用图像作为按钮,这不是问题,但如果您有文本则更烦人......无论如何,假设您找到解决文本问题的方法,这里是要使用的代码:

    ImageView button = (ImageView) findViewById(R.id.button);
    button.setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
    

    这会将红色覆盖层应用于按钮(颜色代码是完全不透明红色的十六进制代码 - 前两位数字是透明度,然后是 RR GG BB。)。

    【讨论】:

    • 您能否解释一下代码运行后会发生什么,以及它打算在哪里调用?我试图在 imageView 初始化时调用这两行——它将我的图像涂成红色,然后什么都没有发生,无论是点击还是触摸。触摸调用时也是如此。
    【解决方案4】:

    编辑:虽然下面的原始答案有效且易于设置,但如果您想要/需要更有效的实施,请参阅 Google 的 Android 开发人员倡导者的 this post。另请注意,android:foreground 属性为coming to all Views,包括 ImageView,在 Android M 中默认情况下。


    为 ImageView 使用选择器的问题在于,您只能将其设置为视图的背景 - 只要您的图像是不透明的,您就不会看到它背后的选择器效果。

    诀窍是用属性android:foreground 将您的 ImageView 包装在 FrameLayout 中,这允许我们为其内容定义 overlay。如果我们将android:foreground 设置为选择器(例如?android:attr/selectableItemBackground 用于API 级别11+)并将OnClickListener 附加到FrameLayout 而不是ImageView,则图像将被我们选择器的drawable 覆盖——我们想要的点击效果!

    看:

    <FrameLayout
        android:id="@+id/imageButton"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:foreground="?android:attr/selectableItemBackground" >
    
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/yourImageFile" />
    
    </FrameLayout>
    

    (注意这应该放在你的父布局中。)

    final View imageButton = findViewById(R.id.imageButton);
    imageButton.setOnClickListener(new OnClickListener(){
        @Override
        public void onClick(View view) {
            // do whatever we wish!
        }
    });
    

    【讨论】:

    • 太棒了!这是一个非常好的解决方案。与联系人应用程序中用于 SMS 或呼叫操作的解决方案相同。
    • 在 API
    • selectableItemBackground 属性仅在 API 级别 11 中添加,因此如果您想将此解决方案用于较旧的 API 级别,则必须使用另一个选择器。例如,对于支持 API 级别 7 的应用程序之一,我使用使用 Android Holo Colors Generator tool 生成的 @drawable/list_selector_holo_light 资源。
    • 您可以只使用 1 个 &lt;ImageButton&gt; 和 selectableItemBackground 来实现相同的行为!
    【解决方案5】:

    在 XML 文件中使用 style="?android:borderlessButtonStyle"。 它将显示Android默认的点击效果。

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher" 
        style="?android:borderlessButtonStyle"
    />
    

    【讨论】:

    • 这实际上是最好的答案,容易多了
    • 这个设置了padding,即使你把padding设置为0,如果你给它的图片占据了整个imageView,你是看不到任何点击效果的。
    • @androiddeveloper 使用android:adjustViewBounds="true" 取消设置填充。
    • 推荐使用style="?android:attr/borderlessButtonStyle":developer.android.com/guide/topics/ui/controls/…
    • style="?android:actionButtonStyle" 用于 ActionBar 或 ToolBar 上的可点击 ImageView。
    【解决方案6】:

    只需使用ImageButton

    【讨论】:

    • 我个人不能让它看起来像 ImageView。没有边框,将图像拉伸到 ImageButton 等的大小。如果你能给出这个边框和拉伸问题,并更新你的帖子。我的一些声誉作为赏金归你=)
    【解决方案7】:

    这是我解决这个问题的简单方法:

    ImageView iv = (ImageView) findViewById(R.id.imageView);
    
    iv.setOnClickListener(new OnClickListener() {
    
        @Override
        public void onClick(View arg0) {
            // TODO Auto-generated method stub
            //Agrega porcentajes de cada fraccion de grafica pastel
    
            Animation animFadein = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.fade_in);
    
            iv.startAnimation(animFadein);
        });
    

    在文件res/anim/fade_in.xml

    <?xml version="1.0" encoding="utf-8"?>
        <set xmlns:android="http://schemas.android.com/apk/res/android"
             android:fillAfter="true" >
    
    <alpha
        android:duration="100"
        android:fromAlpha="0.0"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:toAlpha="1.0" />
     </set>
    

    【讨论】:

    • 很好的解决方案 - 谢谢!我滚动浏览了这篇文章,尝试了所有简洁的文章——但没有成功。最后我到了这里,它对我有用。一项观察 - 如果您有 2 个以上的按钮想要将动画应用于 .. 对于我的代码,我发现我需要为每个想要应用效果的按钮创建一个唯一的 Animation 对象实例。重复使用同一个实例会使所有按钮在单击 1 时闪烁。
    【解决方案8】:

    为 ImageView 设置可选择的背景并添加一些填充。然后附上OnClickListener

    <ImageView
        android:id="@+id/your_image_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/your_image"
        android:padding="10dp"
        android:background="?android:attr/selectableItemBackground"/>
    

    【讨论】:

    • 有没有办法在不设置padding的情况下使用,让整个ImageView都有效果而不仅仅是空白区域?
    • 这将显示立方波纹,我们需要中心波纹
    【解决方案9】:

    如果您想要点击时出现波纹,可以通过以下代码给出:

    <ImageView
        ...
        android:background="?attr/selectableItemBackgroundBorderless"
        android:clickable="true"
        ...
    </ImageView>
    

    同样可以为TextView实现点击效果

    <TextView
        ...
        android:background="?attr/selectableItemBackgroundBorderless"
        android:clickable="true"
        ...
    </TextView>
    

    【讨论】:

      【解决方案10】:

      用于定义选择器可绘制选项

      <selector xmlns:android="http://schemas.android.com/apk/res/android">
          <item android:state_selected="true"   
              android:drawable="@drawable/img_down" />
          <item android:state_selected="false"   
              android:drawable="@drawable/img_up" />
      </selector>
      

      我必须使用 android:state_pressed 而不是 android:state_selected

      <selector xmlns:android="http://schemas.android.com/apk/res/android">
          <item android:state_pressed ="true"   
              android:drawable="@drawable/img_down" />
          <item android:state_pressed ="false"   
              android:drawable="@drawable/img_up" />
      </selector>
      

      【讨论】:

        【解决方案11】:

        这对我有用:

        img.setOnTouchListener(new OnTouchListener(){
        
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        switch (event.getAction())
                        {
                            case MotionEvent.ACTION_DOWN:
                            {
                                ((ImageView)v).setImageAlpha(200);
                                break;
                            }
                            case MotionEvent.ACTION_MOVE:
                            {
                                // if inside bounds
                                if(event.getX() > 0 && event.getX() < v.getWidth() && event.getY() > 0 && event.getY() < v.getHeight())
                                {
                                    ((ImageView)v).setImageAlpha(200);
                                }
                                else
                                {
                                    ((ImageView)v).setImageAlpha(255);
                                }
        
                                break;
                            }
                            case MotionEvent.ACTION_UP:
                            {
                                ((ImageView)v).setImageAlpha(255);
                            }
                        }
                        return true;
                    }
        
                });
        

        @Edit:正如 Gunhan 所说,setImageAlpha 方法存在向后兼容性问题。 我用了这个方法:

        public static void setImageAlpha(ImageView img, int alpha)
            {
                if(Build.VERSION.SDK_INT > 15)
                {
                    img.setImageAlpha(alpha);
                }
                else
                {
                    img.setAlpha(alpha);
                }
            }
        

        【讨论】:

        • setImageAlpha 需要 API 级别 16。因此,对于向后兼容的应用程序,无法使用它
        • @Gunhan 实际上,您可以使用“nineOldAndroids”库,即使在较旧的 API 上也可以使用 alpha。只需使用: ViewHelper.setAlpha(view,alpha);
        【解决方案12】:

        你可以试试android:background="@android:drawable/list_selector_background" 以获得与默认“闹钟”(现在的桌面时钟)中的“添加闹钟”相同的效果。

        【讨论】:

          【解决方案13】:

          我做一些类似的事情 看适合不适合你

          查看新闻效果助手:

          • 用法:像iOS一样做一些简单的按下效果

            简单用法:

          • ImageView img = (ImageView) findViewById(R.id.img);

          • ViewPressEffectHelper.attach(img)

          https://gist.github.com/extralam/7489370

          【讨论】:

            【解决方案14】:

            结合以上所有答案,我希望 ImageView 被按下并更改状态,但如果用户移动然后“取消”并且不执行 onClickListener。

            我最终在类中创建了一个 Point 对象,并根据用户按下 ImageView 的时间设置其坐标。在 MotionEvent.ACTION_UP 上,我记录了一个新点并比较了这些点。

            我只能解释得这么好,但这就是我所做的。

            // set the ontouch listener
            weatherView.setOnTouchListener(new OnTouchListener() {
            
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    // Determine what action with a switch statement
                    switch (event.getAction()) {
            
                    // User presses down on the ImageView, record the original point
                    // and set the color filter
                    case MotionEvent.ACTION_DOWN: {
                        ImageView view = (ImageView) v;
            
                        // overlay is black with transparency of 0x77 (119)
                        view.getDrawable().setColorFilter(0x77000000,
                                PorterDuff.Mode.SRC_ATOP);
                        view.invalidate();
            
                        p = new Point((int) event.getX(), (int) event.getY());
                        break;
                    }
            
                    // Once the user releases, record new point then compare the
                    // difference, if within a certain range perform onCLick
                    // and or otherwise clear the color filter
                    case MotionEvent.ACTION_UP: {
                        ImageView view = (ImageView) v;
                        Point f = new Point((int) event.getX(), (int) event.getY());
                        if ((Math.abs(f.x - p.x) < 15)
                                && ((Math.abs(f.x - p.x) < 15))) {
                            view.performClick();
                        }
                        // clear the overlay
                        view.getDrawable().clearColorFilter();
                        view.invalidate();
                        break;
                    }
                    }
                    return true;
                }
            });
            

            我在 imageView 上设置了一个 onClickListener,但这可以是一个方法。

            【讨论】:

            • 通过添加与MotionEvent.ACTION_UP具有相同功能的case MotionEvent.ACTION_CANCEL,然后如果用户执行不是点击操作的“拖动”,则可以“清除”视图。
            【解决方案15】:

            您可以在 ImageView 中覆盖 setPressed 并在那里进行颜色过滤,而不是创建 onTouchEvent 侦听器:

            @Override
            public void setPressed(boolean pressed) {
                super.setPressed(pressed);
            
                if(getDrawable() == null)
                    return;
            
                if(pressed) {
                    getDrawable().setColorFilter(0x44000000, PorterDuff.Mode.SRC_ATOP);
                    invalidate();
                }
                else {
                    getDrawable().clearColorFilter();
                    invalidate();
                }
            }
            

            【讨论】:

              【解决方案16】:

              基于Mr Zorn's answer,我在我的抽象实用程序类中使用了一个静态方法:

              public abstract class Utility {
              ...
              
                  public static View.OnTouchListener imgPress(){
                      return imgPress(0x77eeddff); //DEFAULT color
                  }
              
                  public static View.OnTouchListener imgPress(final int color){
                      return new View.OnTouchListener() {
              
                          @Override
                          public boolean onTouch(View v, MotionEvent event) {
              
                              switch(event.getAction()) {
              
                                  case MotionEvent.ACTION_DOWN: {
                                      ImageView view = (ImageView) v;
                                      view.getDrawable().setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
                                      view.invalidate();
                                      break;
                                  }
              
                                  case MotionEvent.ACTION_UP:
                                      v.performClick();
              
                                  case MotionEvent.ACTION_CANCEL: {
                                      ImageView view = (ImageView) v;
              
                                      //Clear the overlay
                                      view.getDrawable().clearColorFilter();
                                      view.invalidate();
                                      break;
                                  }
                              }
              
                              return true;
                          }
                      };
                  }
              
                  ...
              }
              

              然后我将它与 onTouchListener 一起使用:

              ImageView img=(ImageView) view.findViewById(R.id.image);
              img.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View v) { /* Your click action */ }
              });
              img_zc.setOnTouchListener(Utility.imgPress()); //Or Utility.imgPress(int_color_with_alpha)
              

              如果您有很多图像,并且想要一个简单的 onTouch 效果,没有任何 XML 可绘制对象并且只有一个图像,这很简单。

              【讨论】:

                【解决方案17】:

                使用android.widget.Button,并将其background 属性设置为android.graphics.drawable.StateListDrawable。这一切都可以用 XML 或以编程方式完成。请参阅Custom Button section of the Form Stuff tutorial

                【讨论】:

                  【解决方案18】:

                  我创建了示例here,只需从您的布局中将 ImageView 更改为 ClickableImageView。希望它有所帮助。

                  【讨论】:

                    【解决方案19】:

                    我认为 ImageButton 是一个更好的解决方案

                    <ImageButton
                        android:layout_width="96dp"
                        android:layout_height="56dp"
                        android:src="@mipmap/ic_launcher"
                        android:adjustViewBounds="true"
                        android:background="@android:color/transparent"
                        android:foreground="@drawable/selector" />
                    

                    【讨论】:

                      【解决方案20】:

                      如果你使用背景图片,我有一个更美的解决方案:)

                      public static void blackButton(View button){
                          button.setOnTouchListener(new OnTouchListener() {
                      
                              public boolean onTouch(View v, MotionEvent event) {
                                  switch (event.getAction()) {
                                      case MotionEvent.ACTION_DOWN: {
                                          v.getBackground().setColorFilter(0xf0f47521,PorterDuff.Mode.SRC_ATOP);
                                          v.invalidate();
                                          break;
                                      }
                                      case MotionEvent.ACTION_UP: {
                                          v.getBackground().clearColorFilter();
                                          v.invalidate();
                                          break;
                                      }
                                  }
                                  return false;
                              }
                          });
                      }
                      

                      【讨论】:

                        【解决方案21】:

                        或者:

                        您可以使用此表单,与图像按钮。

                        创建文件res/drawable/btn_video.xml:

                        <?xml version="1.0" encoding="utf-8"?>
                        <selector xmlns:android="http://schemas.android.com/apk/res/android">
                            <item android:drawable="@drawable/image"
                                android:state_pressed="true" />
                            <item android:drawable="@drawable/ico2"
                                android:state_focused="true" />
                            <item android:drawable="@drawable/ico2" />
                        </selector>
                        

                        还有res/layout/activity_main.xml

                        <ImageButton
                            android:layout_width="match_parent"
                            android:layout_height="match_parent"
                            android:id="@+id/imageButton"
                            android:layout_gravity="center_horizontal"
                            android:onClick="eventImageBtn"
                            android:background="@drawable/btn_video"
                            android:adjustViewBounds="true"
                            android:scaleType="fitXY"
                        />
                        

                        您的图片只需点击即可更改,您可以使用线性布局进行调整:

                        <?xml version="1.0" encoding="utf-8"?>
                        <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
                            android:layout_width="match_parent"
                            android:layout_height="match_parent"
                            android:fillViewport="true">
                        
                            <LinearLayout
                                android:layout_width="match_parent"
                                android:layout_height="match_parent"
                                android:orientation="vertical"
                                android:background="@color/menu_item_background">
                        
                                <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"
                                              android:paddingLeft="@dimen/main_screen_side_padding" android:paddingRight="@dimen/main_screen_side_padding" android:paddingTop="@dimen/main_screen_side_padding" android:paddingBottom="@dimen/main_screen_side_padding"
                                              android:background="#ffb3ff13" android:weightSum="10.00">
                        
                        
                                    <LinearLayout android:layout_weight="2.50" android:background="#ff56cfcd" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="0dp" >
                        
                                        <ImageButton
                                            android:layout_width="match_parent"
                                            android:layout_height="match_parent"
                                            android:id="@+id/imageButton"
                                            android:layout_gravity="center_horizontal"
                                            android:onClick="eventImageBtn"
                                            android:background="@drawable/btn_video"
                                            android:adjustViewBounds="true"
                                            android:scaleType="fitXY"
                                        />
                                    </LinearLayout>
                        
                                    <LinearLayout android:layout_weight="0.50" android:layout_height="0dp" android:background="#ffffffff" android:orientation="vertical" android:layout_width="fill_parent" >
                                    </LinearLayout>
                        
                                    <LinearLayout android:layout_weight="4.50" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="0dp" android:background="#ff8aa5ff">
                                    </LinearLayout>
                        
                                    <LinearLayout android:layout_weight="0.50" android:layout_height="0dp" android:background="#ffffffff" android:orientation="vertical" android:layout_width="fill_parent" >
                                    </LinearLayout>
                        
                                    <LinearLayout android:layout_weight="2.00" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="0dp" android:background="#ffff7d1a" >
                                    </LinearLayout>
                        
                                </LinearLayout>
                            </LinearLayout>
                        </ScrollView>
                        

                        【讨论】:

                          【解决方案22】:

                          这是我的解决方案,它使用“nineOldAndroids”库,也支持旧 API:

                          rootView.setOnTouchListener(new OnTouchListener() {
                          
                              @Override
                              public boolean onTouch(final View v, final MotionEvent event) {
                          
                                  switch (event.getAction()) {
                          
                                      case MotionEvent.ACTION_UP:
                                      case MotionEvent.ACTION_CANCEL:
                                          v.setBackgroundResource(R.drawable.listview_normal);
                                          ViewHelper.setAlpha(imageView, 1);
                                          break;
                          
                                      case MotionEvent.ACTION_DOWN:
                                          v.setBackgroundResource(0);
                                          v.setBackgroundColor(getResources().getColor(R.color.listview_pressed));
                                          ViewHelper.setAlpha(imageView, 0.75f);
                                          break;
                                  }
                                  return false;
                              }
                          });
                          

                          它假定 rootView 是单元格本身(布局),并且它有一个 imageView,您希望受到您希望应用于整个单元格的颜色的影响。


                          编辑:如果您愿意,您还可以扩展 ImageView 以处理前景,并将其设置为“?android:attr/selectableItemBackground”。这个here 有一个库,还有一个关于如何为你想要的任何视图做的教程,here

                          【讨论】:

                          • @madlymad 感谢您修复代码格式,但我认为缩进出了点问题。反正能看懂就行了……
                          【解决方案23】:

                          感谢您对此主题的帮助。但是,您错过了一件事……您还需要处理 ACTION_CANCEL。如果不这样做,那么在视图层次结构中的父视图截获触摸事件的情况下,您可能无法正确恢复 ImageView 的 alpha 值(想想包装 ImageView 的 ScrollView)。

                          这是一个完整的类,它基于上述类,但也处理了 ACTION_CANCEL。它使用一个 ImageViewCompat 帮助类来抽象 JellyBean API 前后的差异。

                          public class ChangeAlphaOnPressedTouchListener implements OnTouchListener {
                          
                              private final float pressedAlpha;
                          
                              public ChangeAlphaOnPressedTouchListener(float pressedAlpha) {
                                  this.pressedAlpha = pressedAlpha;
                              }
                          
                              @Override
                              public boolean onTouch(View v, MotionEvent event) {
                                  ImageView iv = (ImageView) v;
                                  switch (event.getAction()) {
                                  case MotionEvent.ACTION_DOWN:
                                      ImageViewCompat.setAlpha(iv, pressedAlpha);
                                      break;
                          
                                  case MotionEvent.ACTION_MOVE:
                                      if (isInsideViewBounds(v, event)) {
                                          ImageViewCompat.setAlpha(iv, pressedAlpha);
                                      } else {
                                          ImageViewCompat.setAlpha(iv, 1f);
                                      }
                                      break;
                                  case MotionEvent.ACTION_UP:
                                      ImageViewCompat.setAlpha(iv, 1f);
                                      break;
                                  case MotionEvent.ACTION_CANCEL:
                                      ImageViewCompat.setAlpha(iv, 1f);
                                  }
                                  return false;
                              }
                          
                              private static boolean isInsideViewBounds(View v, MotionEvent event) {
                                  return event.getX() > 0 && event.getX() < v.getWidth() && event.getY() > 0
                                          && event.getY() < v.getHeight();
                              }
                          }
                          

                          【讨论】:

                            【解决方案24】:

                            这是我的代码。这个想法是 ImageView 在用户触摸时获取颜色过滤器,并在用户停止触摸时移除颜色过滤器。

                            Martin Booka Weser、András、Ah Lam、altosh,当 ImageView 也有 onClickEvent 时,解决方案不起作用。 worawee.s 和 kcoppock (with ImageButton) 解决方案需要背景,当 ImageView 不透明时没有任何意义。

                            这是AZ_关于滤色器思想的延伸。

                            class PressedEffectStateListDrawable extends StateListDrawable {
                            
                                private int selectionColor;
                            
                                public PressedEffectStateListDrawable(Drawable drawable, int selectionColor) {
                                    super();
                                    this.selectionColor = selectionColor;
                                    addState(new int[] { android.R.attr.state_pressed }, drawable);
                                    addState(new int[] {}, drawable);
                                }
                            
                                @Override
                                protected boolean onStateChange(int[] states) {
                                    boolean isStatePressedInArray = false;
                                    for (int state : states) {
                                        if (state == android.R.attr.state_pressed) {
                                            isStatePressedInArray = true;
                                        }
                                    }
                                    if (isStatePressedInArray) {
                                        super.setColorFilter(selectionColor, PorterDuff.Mode.MULTIPLY);
                                    } else {
                                        super.clearColorFilter();
                                    }
                                    return super.onStateChange(states);
                                }
                            
                                @Override
                                public boolean isStateful() {
                                    return true;
                                }
                            }
                            

                            用法:

                            Drawable drawable = new FastBitmapDrawable(bm);
                            imageView.setImageDrawable(new PressedEffectStateListDrawable(drawable, 0xFF33b5e5));
                            

                            【讨论】:

                              【解决方案25】:

                              我试过了:

                              <ImageButton
                                      android:layout_width="wrap_content"
                                      android:layout_height="wrap_content"
                                      android:contentDescription="@string/get_started"
                                      android:src="@drawable/home_started"
                                      style="?android:borderlessButtonStyle"
                                      android:adjustViewBounds="true"
                                      android:clickable="true"
                                      android:elevation="5dp"
                                      android:longClickable="true" />
                              

                              这很有效。上线请注意:style="?android:borderlessButtonStyle"

                              【讨论】:

                              • 这在填充为 0 并且图像占据整个视图区域的情况下不起作用。
                              【解决方案26】:

                              我认为最简单的方法是创建一个新的 XML 文件。在这种情况下,我们在drawable文件夹中将其命名为“example.xml”,并放入以下代码:

                              <selector xmlns:android="http://schemas.android.com/apk/res/android">
                                  <item android:drawable="@color/blue"
                                        android:state_pressed="true" />
                              
                              </selector>
                              

                              但在此之前,您必须在 values 文件夹中的 colors.xml 文件中设置颜色,如下所示:

                              <resources>
                                  <color name="blue">#0000FF</color>
                              </resources>
                              

                              这样,您只需将 Button / ImageButton 设置为使用新布局,如下所示:

                              <ImageView
                                  android:layout_width="wrap_content"
                                  android:layout_height="wrap_content"
                                  android:background="@drawable/example"
                              />
                              

                              然后当你点击那个图片时,它会变成里面设置的颜色

                              <item android:drawable="@color/blue"
                                    android:state_pressed="true" />
                              

                              给出你想要的反馈...

                              【讨论】:

                                【解决方案27】:

                                这是我见过的最好的解决方案。它更通用。

                                <?xml version="1.0" encoding="utf-8"?>
                                <set xmlns:android="http://schemas.android.com/apk/res/android"
                                     android:fillAfter="true" >
                                
                                    <alpha
                                        android:duration="100"
                                        android:fromAlpha="0.0"
                                        android:interpolator="@android:anim/accelerate_interpolator"
                                        android:toAlpha="1.0" />
                                </set>
                                

                                【讨论】:

                                • 应该注入到哪个地方和文件中?
                                【解决方案28】:

                                您可以为ImageView 制作简单的涟漪效果。这非常适合图标。

                                res/drawable 中创建circular_shape.xml

                                <?xml version="1.0" encoding="utf-8"?>
                                 <selector xmlns:android="http://schemas.android.com/apk/res/android">
                                
                                  <item>
                                    <shape android:shape="oval">
                                        <solid android:color="@android:color/white"/>
                                    </shape>
                                  </item>
                                

                                res/drawable创建一个可绘制的res文件ripple_effect_iv.xml

                                <ripple xmlns:android="http://schemas.android.com/apk/res/android"
                                android:color="?attr/colorControlHighlight">
                                
                                 <item
                                    android:id="@android:id/mask"
                                    android:drawable="@drawable/circular_shape" />
                                
                                </ripple>
                                

                                background设置为ImageView也可以考虑padding以显示自然波纹:

                                     <ImageView
                                        android:background="@drawable/ripple_effect_iv"
                                        android:padding="10dp"/>
                                

                                是的,您的ImageView 变小了,但您可以简单地增加android:layout_widthandroid:layout_height

                                【讨论】:

                                  【解决方案29】:

                                  就目前而言,我们应该发展Material Design实践。在这种情况下,您可以在 ImageView 上添加涟漪效果。

                                  【讨论】:

                                    猜你喜欢
                                    • 1970-01-01
                                    • 2021-11-19
                                    • 2020-04-11
                                    • 2011-11-02
                                    • 1970-01-01
                                    • 2016-05-25
                                    • 2012-02-22
                                    • 1970-01-01
                                    • 1970-01-01
                                    相关资源
                                    最近更新 更多