Android 自定义ToggleButton

效果图

这里写图片描述

思考

  • 因为是自定义view,不是viewGroup,所以在进行了onMeasure()的测量方法之后,所以不需要onLayout方法,但是必须实现onDraw()方法

  • 程序如何设计呢?

    1. 需要提供设置ToggleButton开关背景图片的方法
    2. 需要提供设置ToggleButton滑动背景图片的方法
    3. 需要提供设置ToggleButton开关状态的方法
    4. 需要提供设置ToggleButton状态改变的监听器
  • 如何实现开关随手指滑动的呢?这里需要重写onTouchEvent()方法。

    1. 如果用户正在滑动,则去获取当前手指滑动位置的X坐标currentX,然后去动态的绘制滑动的图片位置。具体判断如下图:
      这里写图片描述

    2. 如果用户抬起手指,则去判断currentX与背景图片中心点的X坐标,然后去设置开关的状态。具体判断如下图:
      这里写图片描述

  • 控件画好了之后,得提供开关状态改变的接口,供外界使用。这里要注意:仅当状态改变时,才调用。所以调用之前要加个判断。

步骤

1. 布局

<RelativeLayout 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" >

    <com.example.togglebutton.MyToggleButton
        android:id="@+id/my_toggle_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />

</RelativeLayout>

2. 主函数(调用上面布局显示自定义控件的函数)

public class MainActivity extends Activity {

    private MyToggleButton myToggleButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myToggleButton = (MyToggleButton) this.findViewById(R.id.my_toggle_button);
        myToggleButton.setSwitchBackgroundRes(R.drawable.switch_background);//设置开关的背景图片
        myToggleButton.setSlideBackgroundRes(R.drawable.slide_button_background);//设置滑动的图片
        myToggleButton.setToggleState(ToggleState.Open);//设置开关的状态
        myToggleButton.setOnToggleStateChangeListener(new OnToggleStateChangeListener() {

            @Override
            public void onToggleStateChange(ToggleState state) {
                Toast.makeText(MainActivity.this, state==ToggleState.Open?"开启":"关闭", 0).show();
            }
        });
    }

}

3. 自定义的ToggleButton

public class MyToggleButton extends View {

    private ToggleState toggleState = ToggleState.Open; //当前开关的状态
    private Bitmap switchBg;    //开关的背景图片
    private Bitmap slideBg;     //滑动的图片
    private int currentX;       //当前手指的X坐标
    private boolean isSliding = false;      //是否处于滑动状态

    public MyToggleButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public MyToggleButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyToggleButton(Context context) {
        super(context);
    }

    public enum ToggleState{
        Open,Close
    }

    /**
     * 设置开关的背景图片
     * @param switchBackground
     */
    public void setSwitchBackgroundRes(int switchBackground) {
        switchBg = BitmapFactory.decodeResource(getResources(), switchBackground);
    }

    /**
     * 设置滑动块的图片
     * @param slideButtonBackground
     */
    public void setSlideBackgroundRes(int slideButtonBackground) {
        slideBg = BitmapFactory.decodeResource(getResources(), slideButtonBackground);
    }

    /**
     * 设置开关的状态
     * @param state
     */
    public void setToggleState(ToggleState state) {
        toggleState = state;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(switchBg.getWidth(), switchBg.getHeight());
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //绘制背景图片  left top 都是相对于自身的坐标系 不是屏幕坐标系
        canvas.drawBitmap(switchBg, 0, 0, null);

        if(isSliding){  //绘制手指滑动时的滑动块图片
            int left = currentX - slideBg.getWidth()/2;
            if(left < 0) 
                left = 0;
            if(left > switchBg.getWidth() - slideBg.getWidth()){
                left = switchBg.getWidth() - slideBg.getWidth();
            }
            canvas.drawBitmap(slideBg, left, 0, null);
        }else{  //绘制停止滑动时的滑动块图片
            if(toggleState == ToggleState.Open){
                canvas.drawBitmap(slideBg, switchBg.getWidth() - slideBg.getWidth(), 0, null);
            }else{
                canvas.drawBitmap(slideBg, 0, 0, null);
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        currentX = (int) event.getX();
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            isSliding = true;
            break;
        case MotionEvent.ACTION_MOVE:
            break;
        case MotionEvent.ACTION_UP:
            isSliding = false;
            if(currentX < switchBg.getWidth()/2){   //滑块置为左边,关闭状态
                if(toggleState != ToggleState.Close){
                    toggleState = ToggleState.Close;
                    if(listener != null){
                        listener.onToggleStateChange(toggleState);
                    }
                }
            }else{  //滑块置为右边,打开状态
                if(toggleState != ToggleState.Open){
                    toggleState = ToggleState.Open;
                    if(listener != null){
                        listener.onToggleStateChange(toggleState);
                    }
                }
            }
            break;
        }
        invalidate();
        return true;
    }

    private OnToggleStateChangeListener listener;
    public void setOnToggleStateChangeListener(OnToggleStateChangeListener listener){
        this.listener = listener;
    }
    public interface OnToggleStateChangeListener{
        void onToggleStateChange(ToggleState state);
    }

4. 注意:

设置的开关的背景图片以及滑动块图片在绘制时都需要转换成bitmap方便测量和绘制
onTouchEvent()方法执行结束前,需要调用invalidate()方法去重新onDraw(); 并且return true表示已经处理。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ToggleButtonAndroid中的一个控件,它可以用来切换两种状态,通常用于表示开关按钮。在使用ToggleButton时,你可以通过设置几个常用属性来自定义按钮的行为和外观,如android:textOn和android:textOff属性可以设置按钮在不同状态下显示的文字。 如果你想在Android Studio中使用ToggleButton,你可以参考以下步骤: 1. 在布局文件中添加ToggleButton控件,设置它的id和其他属性,如android:textOn和android:textOff。 2. 在Activity中找到ToggleButton控件,使用findViewById方法绑定该控件。 3. 为ToggleButton设置一个监听器,通过setOnCheckedChangeListener方法实现。 4. 在监听器的onCheckedChanged方法中,根据按钮的状态进行相应的操作。 以下是一个简单的示例代码,演示了如何在Android Studio中创建和使用ToggleButton控件: ```java public class MainActivity extends AppCompatActivity { private TextView tv_show = null; private ToggleButton btn_tog_test = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv_show = findViewById(R.id.tv_show); btn_tog_test = findViewById(R.id.btn_tog_test); btn_tog_test.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) { if (isChecked) { tv_show.setText("已经开始"); } else { tv_show.setText("已经停止"); } } }); } } ``` 在这个示例中,我们创建了一个Activity,并在布局文件中添加了一个TextView和一个ToggleButton控件。当ToggleButton的状态切换时,我们通过监听器来更新TextView的文本。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值