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

android_94_自定义ToggleButton

2017-01-23 20:39 375 查看
效果:



枚举:



自定义View与ViewGroup的区别



示意图:

getX();得到的是 View内部的坐标系;原点在View内的左上角

注意:文字是特殊情况,

getRawX();得到的是 屏幕坐标系:原点在屏幕的左上角



布局文件:

<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.sg31.sgtogglebutton.MainActivity" >

<com.sg31.sgtogglebutton.SGToogleButton
android:id="@+id/toggleBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
/>

</RelativeLayout>


主控制器:

package com.sg31.sgtogglebutton;

import com.sg31.sgtogglebutton.SGToogleButton.OnToggleStateChangeLisener;
import com.sg31.sgtogglebutton.SGToogleButton.ToggleState;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends ActionBarActivity {

private SGToogleButton toggleBtn;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

initToggleButton();

}

private void initToggleButton() {
toggleBtn = (SGToogleButton)findViewById(R.id.toggleBtn);
toggleBtn.setBgImgResource(R.drawable.onimg2);
toggleBtn.setSlideImgResource(R.drawable.slideimg);
toggleBtn.setToggleState(ToggleState.Closed);
toggleBtn.setOnToggleStateChangeLisener(new OnToggleStateChangeLisener() {

@Override
public void onToggleStateChanged(ToggleState state) {
// TODO Auto-generated method stub
System.out.println(state==ToggleState.Open?"open":"closed");
}
});
}
}


自定义ToggleButton

package com.sg31.sgtogglebutton;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class SGToogleButton extends View {

// 状态枚举
public enum ToggleState{
Open,Closed
}

// 代理
private OnToggleStateChangeLisener lisener;
private ToggleState toggleSate;
private Bitmap slideImg;
private Bitmap bgImg;
private int fingerX;
private boolean isSliding;
public interface OnToggleStateChangeLisener{
void onToggleStateChanged(ToggleState state);
}
public void setOnToggleStateChangeLisener(OnToggleStateChangeLisener lisener) {
this.lisener = lisener;
}

// 构造方法
public SGToogleButton(Context context) {
super(context);
}
public SGToogleButton(Context context, AttributeSet attrs) {
super(context, attrs);
}

// 供外界调用
public void setBgImgResource(int imgID) {
bgImg = BitmapFactory.decodeResource(getResources(), imgID);
}
// 供外界调用
public void setSlideImgResource(int imgID) {
slideImg = BitmapFactory.decodeResource(getResources(), imgID);
}
// 供外界调用
public void setToggleState(ToggleState state) {
toggleSate = state;
}

// 自定义View的第2步,onMeasure方法
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(bgImg.getWidth(), bgImg.getHeight());
}

// 自定义View的第3步,onDraw方法
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 1.绘制背景图 在 View中的位置 (画图可以不用Paint)
canvas.drawBitmap(bgImg, 0, 0, null);

// 2根据状态及变量,进行绘制滑块
if (isSliding) {
int slideImgX = fingerX - slideImg.getWidth()/2;
if (slideImgX < 0) {
// 防止左边越界
slideImgX = 0;
}
if (slideImgX > bgImg.getWidth() - slideImg.getWidth()) {
// 防止右边越界
slideImgX = bgImg.getWidth() - slideImg.getWidth();
}
canvas.drawBitmap(slideImg, slideImgX, 0, null);
} else {
// 抬起时:要么关,要么开
if (toggleSate == ToggleState.Open) {
// 背景图片: 左是开, 右是关
canvas.drawBitmap(slideImg, 0, 0, null);
} else {
canvas.drawBitmap(slideImg, bgImg.getWidth() - slideImg.getWidth(), 0, null);
}

}

}

// 自定义View的第4步,onTouchEvent方法
@Override
public boolean onTouchEvent(MotionEvent event) {
System.out.println("sg__touch");
// 得到按下点,在View自己内部的坐标(相对于View自身的左上角)
fingerX = (int)event.getX();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
{
// 只要按下,就标记为滑动
isSliding = true;
}
break;
case MotionEvent.ACTION_MOVE:
{

}
break;
case MotionEvent.ACTION_UP:
{
isSliding = false;
int toggleCenterX = bgImg.getWidth()/2;
if (fingerX > toggleCenterX) {
// 如果用户手指按下的地方,在view的中心线之后面,则表示 滑块从左往右,从开到闭
// 只有不是闭的时候,才要关闭
if (toggleSate != ToggleState.Closed) {
toggleSate = ToggleState.Closed;
// 通知
if (lisener != null) {
lisener.onToggleStateChanged(toggleSate);
}
}
} else {
// 如果用户手指按下的地方,在view的中心线之前面,则表示 滑块从右往左,从闭到开
// 只有不是开的时候,才要打开
if (toggleSate != ToggleState.Open) {
toggleSate = ToggleState.Open;
// 通知
if (lisener != null) {
lisener.onToggleStateChanged(toggleSate);
}
}
}
}
break;

default:
break;
}
// 非常重要的方法,不然没法更新界面
invalidate();
// 自己要处理,所以返回true
return true;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息