android 使用selector+自定义view实现图片按钮点击放大缩小功能

先看效果,点击放大的

点击缩小

我看了下网上都是用onTouchEvent来实现的,我尽量不想写onTouchEvent内的代码,因为如果遇到手势冲突很折磨人,所以我就用selector里的state_pressed配合view的onDraw来实现这个功能
看过onDraw源码都知道,IamgeView的显示就是mDrawable.draw(canvas);所以只要我们在调用mDrawable.draw(canvas)之前改变mDrawable的尺寸就可以了实现放大缩小了
所以在自定义view内的代码很简单,只要改onDraw就可以了,判断是不是state_pressed,是就改变drawable.setBounds()的大小

@Override
protected void onDraw(Canvas canvas) {
    Drawable drawable = getDrawable();
    if(drawable != null && isPressed()){
        int left = drawable.getBounds().left;
        int top = drawable.getBounds().top;
        int right = drawable.getBounds().right;
        int bottom = drawable.getBounds().bottom;
        drawable.setBounds(strokeWidth,strokeWidth,getWidth() - strokeWidth,getHeight() - strokeWidth);
        drawable.draw(canvas);
        drawable.setBounds(left,top,right,bottom);
    }else{
        super.onDraw(canvas);
    }
}

strokeWidth为负数就是放大,正数就是缩小
可是有一个问题,放大的时候会显示不全,超出的部分没有了,这是因为在调用onDraw的时候显示的范围已经固定了,超过就不显示了,那咋整,可以反过来想,既然不能超出,那我就先缩小嘛,
android:padding="10dp",其他都不用改,这样就是放大到view大小了
缩小就没啥说的,就是设置初始值的时候想了下怎么设置,我选择用android:translationX="10dp",在初始化的时候

strokeWidth = (int) getTranslationX();
setTranslationX(0);

我这样写唯一的缺点就是无法添加背景,因为背景也跟着放大缩小,好了贴源码

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.hyq.hm.scalebutton.MainActivity">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <com.hyq.hm.scalebutton.ScaleImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@drawable/ic_video_encoder"
            android:background="@drawable/drawable_selector_background"
            android:layout_margin="30dp"
            android:onClick="onTest"
            android:translationX="10dp"
            />
        <com.hyq.hm.scalebutton.ScaleImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@drawable/ic_video_encoder"
            android:background="@drawable/drawable_selector_background"
            android:layout_margin="30dp"
            android:onClick="onTest"
            android:padding="10dp"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            />
    </RelativeLayout>
</android.support.constraint.ConstraintLayout>

drawable_selector_background.xml

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

这里要说一下为什么要android:background="@drawable/drawable_selector_background"这样写,因为如果不设置android:state_pressed="true"那么点击的时候就不会调用onDraw,android:drawable="@color/translucent",既然不能设置背景,那就把背景设置成透明的

ScaleImageView.java

public class ScaleImageView extends ImageView {
    private int strokeWidth = 0;
    public ScaleImageView(Context context) {
        super(context);
    }

    public ScaleImageView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        strokeWidth = (int) getTranslationX();
        setTranslationX(0);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Drawable drawable = getDrawable();
        if(drawable != null && isPressed()){
            int left = drawable.getBounds().left;
            int top = drawable.getBounds().top;
            int right = drawable.getBounds().right;
            int bottom = drawable.getBounds().bottom;
            drawable.setBounds(strokeWidth,strokeWidth,getWidth() - strokeWidth,getHeight() - strokeWidth);
            drawable.draw(canvas);
            drawable.setBounds(left,top,right,bottom);
        }else{
            super.onDraw(canvas);
        }
    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public void onTest(View view){
    }
}
<color name="translucent">#00000000</color>

这种写法也可以换成state_selected等其他的,在onDraw把isPressed()换成isSelected等其他的,也可以实现既换图片,又放大缩小,只要src指定drawable_selector,drawable_selector的state_pressed或state_selected显示不同的图片就ok了

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值