Android之自定义控件深入
本文主要讲述两个知识点: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之自定义控件深入的更多相关文章
- Android中自定义控件TextSize属性问题
本文主要说明一个自定义控件添加TextSize属性的坑,刚刚从坑里面爬出来,写个随笔,记录一下: *************************************************** ...
- Android笔记--自定义控件仿遥控器的圆形上下左右OK圆盘按钮
原文:Android笔记--自定义控件仿遥控器的圆形上下左右OK圆盘按钮 上面就是几张预览图!代码在最底下 主要就两个步骤,画图.监听点击 1.整个控件基本上是一步步画出来的,重写onDraw方法开始 ...
- android创建自定义控件
新建一个布局title.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xm ...
- 【转】Android中自定义控件的步骤
原文网址:http://blog.csdn.net/lianchen/article/details/48038969 Android开发中难免遇到需要自定义控件的需求,有些是产品的要求在Androi ...
- 程序媛也话Android 之 自定义控件(垂直方向滑动条)
Android里已经有足够多的控件供开发者使用,但有时候我们还是会想要一些不一样的东西,比如一些UI特效,比如一些3D动画,今天就讲讲比较basic的东西:自定义控件. 1.效果图 如果项目里需要一个 ...
- 《转载-两篇很好的文章整合》Android中自定义控件
两篇很好的文章,有相互借鉴的地方,整合到一起收藏 分别转载自:http://blog.csdn.net/xu_fu/article/details/7829721 http://www.cnblogs ...
- Android之自定义控件
开发自定义控件的步骤: 1.了解View的工作原理 2. 编写继承自View的子类 3. 为自定义View类增加属性 4. 绘制控件 5. 响应用户消息 6 .自定义回调函数 一.Vie ...
- Android中自定义控件,三个构造函数
自定义控件时,最好抽象得彻底,并且编写需严谨,因为可能程序中多处都会引用到它,或者提供给团队中的其他人使用. 其一般步骤为: 1.创建控件的类文件,定义其功能逻辑.一般继承自现有控件或者View 2. ...
- Android学习——自定义控件(二)
这篇文章来介绍自定义组合控件,自定义组合控件的应用场景很多,比如当你的UI如下时: 倘若不使用组合控件,则需要在XML文件中声明4个TextView和4个EditText,而使用了组合控件,则只需要四 ...
随机推荐
- Alpha阶段个人总结
一. 工作总结 第一次接触通信和服务端框架,在前期准备阶段学习了很多不同的技术,也相应花费了很多时间去尝试.刚开始时还不知道框架这种东西,准备自己写,于是学习并尝试了一些简单的HTTP通信,比较麻烦, ...
- HDU 5714
Problem Description 小明在旅游的路上看到了一条美丽的河,河上有许多船只,有的船只向左航行,有的船只向右航行.小明希望拍下这一美丽的风景,并且把尽可能多的船只都完整地拍到一张照片中. ...
- Mac OS下编写对拍程序
介绍 对拍是信息学竞赛中重要的技巧,它通过一个效率低下但正确率可以保证的程序,利用庞大的随机生成数据来验证我们的高级算法程序.对拍最大的优势在于可以通过人力所不能及的速度和数量达到验证的效果.下面我们 ...
- spring bean实例化方式
注意:xml配置中bean节点下scope属性默认值为singleton(单例),在需要多例的情况下需要配置成prototype spring提供三种实例化方式:默认构造.静态工厂.实例工厂 一.默认 ...
- pthread 学习系列 case2-- pthread_mutex_t
许多互斥对象 如果放置了过多的互斥对象,代码就没有什么并发性可言,运行起来也比单线程解决方案慢.如果放置了过少的互斥对象,代码将出现奇怪和令人尴尬的错误.幸运的是,有一个中间立场.首先,互斥对象是用于 ...
- 微信内置浏览器的 User Agent的判断
如何判断微信内置浏览器,首先需要获取微信内置浏览器的User Agent,经过在 iPhone 上微信的浏览器的检测,它的 User Agent 是: Mozilla/5.0 (iPhone; CPU ...
- sqlserver2012相关资源下载
1.输入网址http://www.codeplex.com 2.找到Microsoft SqlServer Product Samples选项 3.进入之后显示如下页面 4.选择SQL Server ...
- back(返回)键总结
对于一般的android手机,都提供了四个(目前主流三个)按键.这几个按键中,back(返回)键用得比较多,对back键出发的事件一般是通过重写onKeyDown(int keyCode, KeyEv ...
- 在VMware上面安装Solaris 10
导读 Oracle Solaris 11 是世界上最先进的企业操作系统,提供安全.速度.简单的企业云环境和DevOps.在这篇文章中我们将使用Solaris 10版本,但您可以按照同样的步骤,来安装刚 ...
- MotionEvent常见值
常见的动作常量: public static final int ACTION_DOWN = 0;单点触摸动作 public static final int ACTION_UP ...