在安卓开发过程当中,其实安卓已经给我们开发人员提供了好多控件供我们使用,但是,在开发过程中,为了实现一些比较绚丽的效果,或是为了实现某些功能,就必须使用到自动以控件了,比如说在开发的时候,我们会用到椭圆形图形、本章索要所得滑动解锁等,都是需要用到自动以控件的。
在安卓中开发中,控件都是在布局当中写的,那么自定义控件也是一样的,在布局当中引用就可以了,制作自定义控件也是也不是一件难事,一般就是创建一个类去继承View或是ViewGroup,那么下面就来体会一下吧!
滑动解锁按钮看美女帅车
大家注意看下注释
public class MySockView extends View {
private int screenHweight;
private int screenWidth;
private Bitmap jiesuo_bg;
private Bitmap jiesuo_button;
private int jiesuo_bgWidth;
private int jiesuo_bgHeight;
private int jiesuo_buttonWidth;
private int right;
private int top;
private int left;
private int currentX;
private int currentY;
private Paint paint;
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//如果没有滑动到解锁的指定位置,就返回到起始位置
//判断如果滑动的小球在指定范围内
if(currentX>left){
//慢慢回到起始位置
currentX=currentX-10;
//重置界面
invalidate();
sendEmptyMessageDelayed(0,5);
}
}
};
private boolean onBlock;
private OnUnlockListener onUnlockListener;
public MySockView(Context context) {
super(context);
init();
}
private void init() {
//得到解锁图片
jiesuo_bg = BitmapFactory.decodeResource(getResources(), R.mipmap.jiesuo_bg);
jiesuo_button = BitmapFactory.decodeResource(getResources(), R.mipmap.jiesuo_button);
//得到宽高
jiesuo_bgWidth = jiesuo_bg.getWidth();
jiesuo_bgHeight = jiesuo_bg.getHeight();
jiesuo_buttonWidth = jiesuo_button.getWidth();
}
public MySockView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MySockView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
//测量的方法
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//得到屏幕的宽高
screenHweight = getMeasuredHeight();
screenWidth = getMeasuredWidth();
//计算出图片距离上、左、右的长度
left = screenWidth/2-jiesuo_bgWidth/2;
top = screenHweight/2-jiesuo_bgHeight/2;
//计算出滑动小球距离右边的距离
right = screenWidth/2+jiesuo_bgWidth/2-jiesuo_buttonWidth;
currentX = left;
currentY = top;
//创建一个画笔
paint = new Paint();
}
//绘制的方法
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//绘制解锁图片
canvas.drawBitmap(jiesuo_bg,left,top,paint);
//边界点判断
if(currentXright){
currentX=right;
}
canvas.drawBitmap(jiesuo_button, currentX, currentY, null);
}
//触摸
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//判断一下,当前手指是否按在了小滑块上
float downX = event.getX();
float downY = event.getY();
onBlock = isOnBlock(downX, downY);
if(onBlock){
//移除所有的消息
handler.removeCallbacksAndMessages(null);
Toast.makeText(getContext(),"按到了",Toast.LENGTH_SHORT).show();
}
break;
case MotionEvent.ACTION_MOVE:
if(onBlock){
//获取move的x和y坐标
float moveX = event.getX();
float moveY = event.getY();
currentX= (int) (moveX-jiesuo_buttonWidth/2);
//重新绘制
invalidate();
}
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
onBlock =false;
//判断抬起时小球的位置
if(currentX>=right-3){
//解锁了
if(onUnlockListener!=null){
onUnlockListener.setUnlock(true);
}
Toast.makeText(getContext(), "解锁了", Toast.LENGTH_SHORT).show();
}else{
//返回原位置
// currentX=left;
handler.sendEmptyMessageDelayed(0,5);
}
invalidate();
break;
}
return true;
}
//判断是否按在圆球上
public boolean isOnBlock(float downX,float downY){
//先计算圆心位置
int rx=currentX+jiesuo_buttonWidth/2;
int ry=currentY+jiesuo_buttonWidth/2;
//计算手指按下点和圆心的距离
double sqrt = Math.sqrt((downX - rx) * (downX - rx) + (downY - ry) * (downY - ry));
if(sqrt<=jiesuo_buttonWidth/2){
return true;
}
return false;
}
//解锁之后要监听的方法
public void setUnOnClick(OnUnlockListener onUnlockListener){
this.onUnlockListener=onUnlockListener;
}
}
回调的接口
public interface OnUnlockListener {
//参数表示是否解锁
public void setUnlock(boolean unlock);
}
布局中引用、注意要将包名改为自己的包名
代码中调用
public class MainActivity extends AppCompatActivity implements OnUnlockListener {
private MySockView mySockView;
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//查找控件
imageView = (ImageView) findViewById(R.id.imageView);
mySockView = (MySockView) findViewById(R.id.mySockView);
//设置是否解锁的监听
mySockView.setUnOnClick(this);
}
@Override
public void setUnlock(boolean unlock) {
if(unlock){
mySockView.setVisibility(View.GONE);
imageView.setVisibility(View.VISIBLE);
}
}
}
自定义属性之在布局中设置圆的半径,字体大小及背景色
效果图
自定义属性的使用
1.在values文件夹下创建attrs.xml文件
布局文件
自定义View之圆中嵌字
public class MyCircleText extends View {
private int width;
private int height;
private int widthTwo;
private int heightTwo;
private String text;
private String size;
private String neicir;
private String waicir;
private String color;
//在代码中创建对象时调用new MyCircleText
public MyCircleText(Context context) {
super(context);
init();
}
//在xml文件引用的时候
public MyCircleText(Context context, AttributeSet attrs) {
super(context, attrs);
//得到自定义属性的值
text = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto","text");
size = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto","size");
neicir = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto","neicir");
waicir = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto","waicir");
color = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto","mycolor");
init();
}
//传递defStyleAttr
public MyCircleText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
//初始化数据的方法
public void init(){
}
//测量的方法
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//拿到屏幕的宽和高
width = getWidth();
height = getHeight();
//屏幕的1/2的宽高
widthTwo = width/2;
heightTwo = height/2;
}
//绘制的方法
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//创建一支画笔
Paint paint=new Paint();
//设置画笔的颜色
paint.setColor(Color.parseColor(color));
//实心画笔
paint.setStyle(Paint.Style.FILL);
//绘制一个矩形
/**
* 绘制一个圆形
* 参数:
* 1.左边距
* 2.上边距
* 3.圆形的半径
*/
canvas.drawCircle(widthTwo,heightTwo,Integer.parseInt(waicir),paint);
paint.setColor(Color.YELLOW);
canvas.drawCircle(widthTwo,heightTwo,Integer.parseInt(neicir),paint);
paint.setColor(Color.BLACK);
//绘制文字
// String text="画圆";
paint.setTextSize(50);
canvas.drawText(text,widthTwo-50,heightTwo+20,paint);
}
//重写onTouch方法
@Override
public boolean onTouchEvent(MotionEvent event) {
//判断事件类型
switch (event.getAction()) {
//按下
case MotionEvent.ACTION_DOWN:
//获取按下的坐标
float downX = event.getX();
float downY=event.getY();
int xx=this.getWidth();
int yy=this.getHeight();
//获取与圆心点
int rx=widthTwo;
int ry=yy/2;
double sqrt = Math.sqrt((downX - rx) * (downX - rx) + (downY - ry) * (downY - ry));
if(sqrt<=yy/2&&sqrt>=110){
Toast.makeText(getContext(), "在圆环内", Toast.LENGTH_SHORT).show();
}else if(sqrt<=110){
Toast.makeText(getContext(), ".在小圆内..", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getContext(), ".在圆环外..", Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
return true;
}
}
这就是自定义View 的简单应用,也不难哈!