您的位置:首页 > 移动开发 > Android开发

最完美的android仿ios开关按钮源码

2015-09-02 10:38 645 查看
首先看一下我的目录结构:

                   


下面直接上源码:


package com.util;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
/**
*
* @author Naiqi.Duan
* @E-mail: itarchy@163.com
* @version 创建时间:2015-8-28下午3:17:34
* @Des:
*/
public class SlipButton extends View implements OnTouchListener
{
private boolean NowChoose = false;// 记录当前按钮是否打开,true为打开,flase为关闭

private boolean isChecked;

private boolean OnSlip = false;// 记录用户是否在滑动的变量

private float DownX, NowX;// 按下时的x,当前的x

private Rect Btn_On, Btn_Off;// 打开和关闭状态下,游标的Rect .

private boolean isChgLsnOn = false;

private OnChangedListener ChgLsn;

private Bitmap bg_on, bg_off, slip_btn;

public SlipButton(Context context)
{
super(context);
init();
}

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

public SlipButton(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
init();
}

private void init()
{// 初始化

bg_on = BitmapFactory.decodeResource(getResources(), R.drawable.split_left_1);
bg_off = BitmapFactory.decodeResource(getResources(), R.drawable.split_right_1);
slip_btn = BitmapFactory.decodeResource(getResources(), R.drawable.dian);
Btn_On = new Rect(0, 0, slip_btn.getWidth(), slip_btn.getHeight());
Btn_Off = new Rect(bg_off.getWidth() - slip_btn.getWidth(), 0, bg_off.getWidth(),
slip_btn.getHeight());
setOnTouchListener(this);// 设置监听器,也可以直接复写OnTouchEvent
}

@Override
protected void onDraw(Canvas canvas)
{// 绘图函数

super.onDraw(canvas);

Matrix matrix = new Matrix();
Paint paint = new Paint();
float x;

if (NowX < (bg_on.getWidth() / 2))// 滑动到前半段与后半段的背景不同,在此做判断
{
x = NowX - slip_btn.getWidth() / 2;
canvas.drawBitmap(bg_off, matrix, paint);// 画出关闭时的背景
}

else
{
x = bg_on.getWidth() - slip_btn.getWidth() / 2;
canvas.drawBitmap(bg_on, matrix, paint);// 画出打开时的背景
}

if (OnSlip)// 是否是在滑动状态,

{
if (NowX >= bg_on.getWidth())// 是否划出指定范围,不能让游标跑到外头,必须做这个判断

x = bg_on.getWidth() - slip_btn.getWidth() / 2;// 减去游标1/2的长度...

else if (NowX < 0)
{
x = 0;
}
else
{
x = NowX - slip_btn.getWidth() / 2;
}
}
else
{// 非滑动状态

if (NowChoose)// 根据现在的开关状态设置画游标的位置
{
x = Btn_Off.left;
canvas.drawBitmap(bg_on, matrix, paint);// 初始状态为true时应该画出打开状态图片
}
else
x = Btn_On.left;
}
if (isChecked)
{
canvas.drawBitmap(bg_on, matrix, paint);
x = Btn_Off.left;
isChecked = !isChecked;
}

if (x < 0)// 对游标位置进行异常判断...
x = 0;
else if (x > bg_on.getWidth() - slip_btn.getWidth())
x = bg_on.getWidth() - slip_btn.getWidth();
canvas.drawBitmap(slip_btn, x, 0, paint);// 画出游标.

}

public boolean onTouch(View v, MotionEvent event)
{
switch (event.getAction())
// 根据动作来执行代码

{
case MotionEvent.ACTION_MOVE:// 滑动
NowX = event.getX();
break;

case MotionEvent.ACTION_DOWN:// 按下

if (event.getX() > bg_on.getWidth() || event.getY() > bg_on.getHeight())
return false;
OnSlip = true;
DownX = event.getX();
NowX = DownX;
break;

case MotionEvent.ACTION_CANCEL: // 移到控件外部

OnSlip = false;
boolean choose = NowChoose;
if (NowX >= (bg_on.getWidth() / 2))
{
NowX = bg_on.getWidth() - slip_btn.getWidth() / 2;
NowChoose = true;
}
else
{
NowX = NowX - slip_btn.getWidth() / 2;
NowChoose = false;
}
if (isChgLsnOn && (choose != NowChoose)) // 如果设置了监听器,就调用其方法..
ChgLsn.OnChanged(NowChoose);
break;
case MotionEvent.ACTION_UP:// 松开

OnSlip = false;
boolean LastChoose = NowChoose;

if (event.getX() >= (bg_on.getWidth() / 2))
{
NowX = bg_on.getWidth() - slip_btn.getWidth() / 2;
NowChoose = true;
}

else
{
NowX = NowX - slip_btn.getWidth() / 2;
NowChoose = false;
}

if (isChgLsnOn && (LastChoose != NowChoose)) // 如果设置了监听器,就调用其方法..

ChgLsn.OnChanged(NowChoose);
break;
default:
}
invalidate();// 重画控件
return true;
}

public void SetOnChangedListener(OnChangedListener l)
{// 设置监听器,当状态修改的时候
isChgLsnOn = true;
ChgLsn = l;
}

public interface OnChangedListener
{
abstract void OnChanged(boolean CheckState);
}

public void setCheck(boolean isChecked)
{
this.isChecked = isChecked;
NowChoose = isChecked;
}
}
package com.view.SlipButton;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;

import com.util.R;
import com.util.SlipButton;
import com.util.SlipButton.OnChangedListener;
/**
*
* @author Naiqi.Duan
* @E-mail: itarchy@163.com
* @version 创建时间:2015-8-28下午3:17:42
* @Des:开关按钮
*/
public class SlipButtonActivity extends Activity {

private SlipButton sb = null;
//private Button btn = null;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.slip_button_activity);

findView();
setListener();
}

/**
* 设置监听
*/
private void setListener() {
sb.SetOnChangedListener(new OnChangedListener() {

public void OnChanged(boolean CheckState) {
//btn.setText(CheckState ? "打开提醒" : "关闭提醒");
}
});
}

/**
* 初始化控件
*/
private void findView() {
sb = (SlipButton) findViewById(R.id.splitbutton);
//btn = (Button) findViewById(R.id.ringagain);
sb.setCheck(true);
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<RelativeLayout
android:id="@+id/relativeLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dip"
android:padding="5dip" >

<com.util.SlipButton
android:id="@+id/splitbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginTop="10dip" />
</RelativeLayout>

</LinearLayout>

源码下载链接: http://download.csdn.net/detail/itarchy/9072829
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息