一个小的自定义控件
程序员文章站
2022-06-08 16:10:47
...
一个简单的滑动开关
/**
* Created by YuX on 2018/7/19 10:32
* ^_^ qq:565749553
*/
public class AppToggle extends View {
private GestureDetector gestureDetector;// 这个是用于引用手势探测器的
private int textColor;
private float textSize;
private int bgColor;
private int fgColor;
private String textLeft;
private String textRight;
private float padding;
private float corner;
private float fgLeft;
private float fgRight;
private float moveLengh;
private float movescope = -1;
private float moveStep;
private boolean onMove = false;
private boolean isLeftOn = true;
private ToggleListener toggleListener;
private boolean changeComplete=true;
public boolean isChangeComplete() {
return changeComplete;
}
public void setChangeComplete(boolean changeComplete) {
this.changeComplete = changeComplete;
}
public ToggleListener getToggleListener() {
return toggleListener;
}
public void setToggleListener(ToggleListener toggleListener) {
this.toggleListener = toggleListener;
}
// private int Width;
// private int Height;
public AppToggle(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// TODO Auto-generated constructor stub
}
public AppToggle(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.AppToggle);
textColor = a.getColor(R.styleable.AppToggle_textColor,
0XFFFFFFFF);
padding = a.getDimension(R.styleable.AppToggle_padding, 0);
corner = a.getDimension(R.styleable.AppToggle_corner, 5);
textSize = a.getDimension(R.styleable.AppToggle_textSize, 36);
bgColor = a.getColor(R.styleable.AppToggle_bgColor,
0XFFEAEAEA);
fgColor = a.getColor(R.styleable.AppToggle_fgColor, 0XFFFF0000);
textLeft = a.getString(R.styleable.AppToggle_textleft);
textRight = a.getString(R.styleable.AppToggle_textright);
a.recycle();
gestureDetector = new GestureDetector(context, new GestureListener(),
null, true);// 初始化手势探测器
}
public AppToggle(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
if (movescope == -1) {
movescope = getWidth() / 2 - corner;
moveStep = movescope / 10;
fgLeft = 0;
fgRight = getWidth() / 2 + corner;
}
Paint tPaint = new Paint();
tPaint.setAntiAlias(true);
tPaint.setTextSize(textSize);
tPaint.setColor(textColor);
Paint.FontMetricsInt fontMetrics = tPaint.getFontMetricsInt();
Paint bgPaint = new Paint();
bgPaint.setColor(bgColor);
Paint fgPaint = new Paint();
fgPaint.setColor(fgColor);
RectF bgRect = new RectF();
bgRect.top = 0;
bgRect.right = getWidth();
bgRect.left = 0;
bgRect.bottom = getHeight();
canvas.drawRoundRect(bgRect, corner, corner, bgPaint);
RectF fgRect = new RectF();
fgRect.top = 0;
fgRect.right = fgRight + moveLengh;
fgRect.left = fgLeft + moveLengh;
fgRect.bottom = getHeight();
canvas.drawRoundRect(fgRect, corner, corner, fgPaint);
float baseline = (getHeight() - fontMetrics.bottom - fontMetrics.top) / 2;//垂直居中
float tLeftX = corner + padding;
float tLeftY = baseline;
canvas.drawText(textLeft, tLeftX, tLeftY, tPaint);
float tRightX = getWidth() / 2 + corner + padding;
float tRightY = baseline;
canvas.drawText(textRight, tRightX, tRightY, tPaint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
boolean retVal = false;
retVal = gestureDetector.onTouchEvent(event);
return retVal;
}// 覆盖这个方法是为了让组件响应触摸事件
Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message message) {
switch (message.what) {
case 0:
invalidate();
break;
case 1:
if(toggleListener!=null)
toggleListener.change(isLeftOn);
break;
}
return false;
}
});
private void moveToRight() {
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (moveLengh < movescope) {
moveLengh += moveStep;
handler.sendEmptyMessage(0);
} else {
onMove = false;
handler.sendEmptyMessage(1);
timer.cancel();
}
}
}, 0, 10);
}
private void moveToLeft() {
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (moveLengh > 0) {
moveLengh -= moveStep;
handler.sendEmptyMessage(0);
} else {
onMove = false;
handler.sendEmptyMessage(1);
timer.cancel();
}
}
}, 0, 10);
}
private class GestureListener extends
GestureDetector.SimpleOnGestureListener {
@Override
public boolean onDown(MotionEvent e) {
// TODO Auto-generated method stub
// Toast.makeText(context, e.getX() + "," + e.getY(),
// Toast.LENGTH_SHORT).show();
if (changeComplete) {
if (e.getX() > movescope && isLeftOn && !onMove) {
changeComplete = false;
onMove = true;
isLeftOn = false;
moveToRight();
}
if (e.getX() < movescope && !isLeftOn && !onMove){
changeComplete = false;
onMove = true;
isLeftOn = true;
moveToLeft();
}
}
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
// TODO Auto-generated method stub
return true;
}
}
public interface ToggleListener {
void change(boolean leftOn);
}
}
自定义属性
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="AppToggle"> <attr name="textColor" format="color" /> <attr name="textSize" format="dimension" /> <attr name="bgColor" format="color" /> <attr name="fgColor" format="color" /> <attr name="textleft" format="string" /> <attr name="textright" format="string" /> <attr name="padding" format="dimension"/> <attr name="corner" format="dimension"/> </declare-styleable> </resources>
多说几句:关于Android studio 自定义属性的使用,定义的名称需要与控件类名一致
布局文件
<包名.AppToggle android:layout_width="200dp" android:layout_height="30dp" app:textleft="可安装应用" app:textright="无权限应用" app:bgColor="#adadad" app:fgColor="@color/orange" app:textSize="13dp" app:textColor="@color/white" app:corner="15dp" android:id="@+id/app_toggle" />
上一篇: PHP编程风格规范分享_PHP教程