本文主要讲述两个知识点:popwindow的使用和通过继承View实现一个自定义控件,实现点击,手动按钮的效果.

popwindow的使用

//定义 popupWindow
popWin = new PopupWindow(MainActivity.this);
popWin.setWidth(input.getWidth()); //设置宽度
popWin.setHeight(200); //设置popWin 高度 popWin.setContentView(listView); //为popWindow填充内容
popWin.setOutsideTouchable(true); // 点击popWin 以处的区域,自动关闭 popWin popWin.showAsDropDown(input, 0, 0);//设置 弹出窗口,显示的位置

自定义控件实现开关拖动按钮

第一步:实现自定义控件要继承view

public class MyToggleButton extends View implements OnClickListener{

第二步:写构造函数并初始化

/**
* 在代码里面创建对象的时候,使用此构造方法
*/
public MyToggleButton(Context context) {
super(context);
// TODO Auto-generated constructor stub
} /**
* 在布局文件中声名的view,创建时由系统自动调用。
* @param context 上下文对象
* @param attrs 属性集
*/
public MyToggleButton(Context context, AttributeSet attrs) {
super(context, attrs); initView();
} /**
* 初始化
*/
private void initView() { //初始化图片
backgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.switch_background);
slideBtn = BitmapFactory.decodeResource(getResources(), R.drawable.slide_button); //初始化 画笔
paint = new Paint();
paint.setAntiAlias(true); // 打开抗矩齿 //添加onclick事件监听
setOnClickListener(this);
}

第三步:重写方法

/*
* view 对象显示的屏幕上,有几个重要步骤:
* 1、构造方法 创建 对象。
* 2、测量view的大小。 onMeasure(int,int);
* 3、确定view的位置 ,view自身有一些建议权,决定权在 父view手中。 onLayout();
* 4、绘制 view 的内容 。 onDraw(Canvas)
*/ @Override
/**
* 测量尺寸时的回调方法
*/
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// super.onMeasure(widthMeasureSpec, heightMeasureSpec); /**
* 设置当前view的大小
* width :view的宽度
* height :view的高度 (单位:像素)
*/
setMeasuredDimension(backgroundBitmap.getWidth(),backgroundBitmap.getHeight());
} //确定位置的时候调用此方法
//自定义view的时候,作用不大
// @Override
// protected void onLayout(boolean changed, int left, int top, int right,
// int bottom) {
// super.onLayout(changed, left, top, right, bottom);
// } /**
* 当前开关的状态
* true 为开
*/
private boolean currState = false; @Override
/**
* 绘制当前view的内容
*/
protected void onDraw(Canvas canvas) {
// super.onDraw(canvas); // 绘制 背景
/*
* backgroundBitmap 要绘制的图片
* left 图片的左边届
* top 图片的上边届
* paint 绘制图片要使用的画笔
*/
canvas.drawBitmap(backgroundBitmap, 0, 0, paint); //绘制 可滑动的按钮
canvas.drawBitmap(slideBtn, slideBtn_left, 0, paint);
}

第四步:监听点击与拖动事件

/**
* 判断是否发生拖动,
* 如果拖动了,就不再响应 onclick 事件
*
*/
private boolean isDrag = false;
@Override
/**
* onclick 事件在View.onTouchEvent 中被解析。
* 系统对onclick 事件的解析,过于简陋,只要有down 事件 up 事件,系统即认为 发生了click 事件
*
*/
public void onClick(View v) {
/*
* 如果没有拖动,才执行改变状态的动作
*/
if(!isDrag){
currState = !currState;
flushState();
}
} /**
* down 事件时的x值
*/
private int firstX;
/**
* touch 事件的上一个x值
*/
private int lastX; @Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event); switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
firstX = lastX =(int) event.getX();
isDrag = false; break;
case MotionEvent.ACTION_MOVE: //判断是否发生拖动
if(Math.abs(event.getX()-firstX)>5){
isDrag = true;
} //计算 手指在屏幕上移动的距离
int dis = (int) (event.getX() - lastX); //将本次的位置 设置给lastX
lastX = (int) event.getX(); //根据手指移动的距离,改变slideBtn_left 的值
slideBtn_left = slideBtn_left+dis;
break;
case MotionEvent.ACTION_UP: //在发生拖动的情况下,根据最后的位置,判断当前开关的状态
if (isDrag) { int maxLeft = backgroundBitmap.getWidth() - slideBtn.getWidth(); // slideBtn
// 左边届最大值
/*
* 根据 slideBtn_left 判断,当前应是什么状态
*/
if (slideBtn_left > maxLeft / 2) { // 此时应为 打开的状态
currState = true;
} else {
currState = false;
} flushState();
}
break;
} flushView(); return true;
}

第五步:刷新当前状态

/**
* 刷新当前状态
*/
private void flushState() {
if(currState){
slideBtn_left = backgroundBitmap.getWidth()-slideBtn.getWidth();
}else{
slideBtn_left = 0;
} flushView();
} /**
* 刷新当前视力
*/
private void flushView() {
/*
* 对 slideBtn_left 的值进行判断 ,确保其在合理的位置 即 0<=slideBtn_left <= maxLeft
*
*/ int maxLeft = backgroundBitmap.getWidth()-slideBtn.getWidth(); // slideBtn 左边届最大值 //确保 slideBtn_left >= 0
slideBtn_left = (slideBtn_left>0)?slideBtn_left:0; //确保 slideBtn_left <=maxLeft
slideBtn_left = (slideBtn_left<maxLeft)?slideBtn_left:maxLeft; /*
* 刷新当前视图 导致 执行onDraw执行
*/
invalidate();
}

第六步:在layout中添加全类名使用

<com.zj.switchbutton.MyTrouggleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>

运行效果

Android之自定义控件深入的更多相关文章

  1. Android中自定义控件TextSize属性问题

    本文主要说明一个自定义控件添加TextSize属性的坑,刚刚从坑里面爬出来,写个随笔,记录一下: *************************************************** ...

  2. Android笔记--自定义控件仿遥控器的圆形上下左右OK圆盘按钮

    原文:Android笔记--自定义控件仿遥控器的圆形上下左右OK圆盘按钮 上面就是几张预览图!代码在最底下 主要就两个步骤,画图.监听点击 1.整个控件基本上是一步步画出来的,重写onDraw方法开始 ...

  3. android创建自定义控件

    新建一个布局title.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xm ...

  4. 【转】Android中自定义控件的步骤

    原文网址:http://blog.csdn.net/lianchen/article/details/48038969 Android开发中难免遇到需要自定义控件的需求,有些是产品的要求在Androi ...

  5. 程序媛也话Android 之 自定义控件(垂直方向滑动条)

    Android里已经有足够多的控件供开发者使用,但有时候我们还是会想要一些不一样的东西,比如一些UI特效,比如一些3D动画,今天就讲讲比较basic的东西:自定义控件. 1.效果图 如果项目里需要一个 ...

  6. 《转载-两篇很好的文章整合》Android中自定义控件

    两篇很好的文章,有相互借鉴的地方,整合到一起收藏 分别转载自:http://blog.csdn.net/xu_fu/article/details/7829721 http://www.cnblogs ...

  7. Android之自定义控件

    开发自定义控件的步骤: 1.了解View的工作原理  2. 编写继承自View的子类 3. 为自定义View类增加属性  4. 绘制控件  5. 响应用户消息  6 .自定义回调函数    一.Vie ...

  8. Android中自定义控件,三个构造函数

    自定义控件时,最好抽象得彻底,并且编写需严谨,因为可能程序中多处都会引用到它,或者提供给团队中的其他人使用. 其一般步骤为: 1.创建控件的类文件,定义其功能逻辑.一般继承自现有控件或者View 2. ...

  9. Android学习——自定义控件(二)

    这篇文章来介绍自定义组合控件,自定义组合控件的应用场景很多,比如当你的UI如下时: 倘若不使用组合控件,则需要在XML文件中声明4个TextView和4个EditText,而使用了组合控件,则只需要四 ...

随机推荐

  1. 使用guava带来的方便

    ​    ​guava是在原先google-collection 的基础上发展过来的,是一个比较优秀的外部开源包,最近项目中使用的比较多,列举一些点.刚刚接触就被guava吸引了... ​    ​这 ...

  2. java随机生成简体中文取指定长度随机简体中文实用方法

    /**     * 获取指定长度随机简体中文     * @param len int     * @return String     */    public static String getR ...

  3. WSP (无线会话协议)

    WSP (无线会话协议) WSP是在无线应用协议(WAP:Wireless Application Protocol )组中的协议,用两种服务提供无线应用环境一个稳定的接口. 中文名 WSP WAP ...

  4. sqlplus 配置方法及相关命令

    sqlplus 配置方法及相关命令 1.配置文件 1.1 全局模式什么叫全局模式呢:当我们配置完sqlplus工具加载配置文件后,无论在哪个目录下登陆数据库,您设置[sqlplus提示符样子,在任何目 ...

  5. C++ 中宏的使用 --来自:http://blog.csdn.net/hgl868/article/details/7058906

    宏在代码中的使用实例: g_RunLog2("Middleware client for Linux, build:%s %s", __DATE__, __TIME__); 下面详 ...

  6. CSS - 如何实现强制不换行、自动换行、强制换行 以及 chrom默认焦点 IE下 Input 默认出现叉

    *:focus {outline: none;} input::-ms-clear {display:none;} 一般的文字截断(适用于内联与块): .text-overflow { display ...

  7. Word Amalgamation(枚举 + 排序)

    Word Amalgamation Time Limit: 1 Sec  Memory Limit: 64 MB Submit: 373  Solved: 247 Description In mil ...

  8. PHP Document 注释标记及规范 && PHP命名规范

    注释标记 @access 使用范围:class,function,var,define,module 该标记用于指明关键字的存取权限:private.public或proteced @author 指 ...

  9. String的内存分配

    1.String类是final类不能被继承 2.String str="abc"的内部工作 (1)先在栈中定 一个名为str的String类的引用变量 String str: (2 ...

  10. 我的grub.cfg配置文件

    路径:/boot/grub/grub.cfg 配置文件如下: # # DO NOT EDIT THIS FILE # # It is automatically generated by grub-m ...