android 自定义控件
自定义控件
- 1组合控件:将系统原生控件组合起来加上动画效果,形成一种特殊的动画效果。
- 2完全自定义控件,继承自系统的View,自己去实现View效果
RotateAnimation
- 构造函数参数含义
-
- fromDegrees
从哪个角度开始旋转 - toDegrees
到哪个角度结束 - pivotXType
X轴以什么为参考 - pivotXValue
x轴以哪里为中心,是一个0~1的浮点数 - pivotYType
Y轴以什么为参考 - pivotYValue
y轴以哪里为中心,是一个0~1的浮点数
- fromDegrees
如何在动画完成后保持状态
animation.setFillAfter(true);
设置动画持续时间
animation.setDuration(1000); //持续1s
还可以给动画添加监听事件
animation.setAnimationListener(new Animation.AnimationListener() {@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {}@Overridepublic void onAnimationRepeat(Animation animation) {}});
添加动画时可能出现的bug
- 动画完成后已经消失的view,点击原位置还会触发点击事件,这是由于Android原生动画执行后view的位置不发生改变,所以如果想解决此bug就要在view消失的时候禁用,例如 button.setEnabled(false);
如何获取物理按键的点击事件
@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if(keyCode == KeyEvent.KEYCODE_MENU){//然后做自己的处理return true; //return true代表我们自己处理这个响应}return super.onKeyDown(keyCode, event);}
下拉列表(和QQ登陆那个一点用户名出现用户列表一样)
使用PopupWindow作为弹窗
我们一般使用三个参数的构造函数
PopupWindow popupWindow = new PopupWindow(View contentView, int width, int height);
参数含义
- contentView :代表我们想让它显示的view
- width : 弹窗的宽
- height : 弹窗的高
显示popupWindow
popupWindow.showAsDropDown(View anchor,int xoff, int yoff);
参数含义
- anchor : 代表在这个控件下面显示
- xoff : 在x轴上的偏移量
- yoff : 在y轴上的偏移量
去除listView的滚动条
当我们不想要listView的滚动条时我们可以这样做
listView.setVerticalScrollBarEnabled(false);
焦点问题
-
假如listView的item中含有button,imageButton,checkBox等会强制获取焦点的view,此时listView无法获取焦点,因此无法被点击。
解决方法:给item的根布局增加以下属性
android:descendantFocusability=”blocksDescendants” -
当popupWindow中填充的View是ListView的话,如果不做设置,listView是无法获取焦点,所以也就无法响应点击事件,所以我们应该做如下设置
popupWindow.setFocusable(true);
popupWindow.setBackgroundDrawable(new BitmapDrawable());
popupWindow.setOutsideTouchable(true);
动态改变popupWindow的宽高
假设popupWindow的高为300像素,当里面listView总的条目高小于300像素时,我们让popupWindow的高等于listView总条目的高
//这里的view代表当前listView的条目,list.size()是listView的条目数int listHeight = view.getHeight() * list.size();popupWindow.update(editText.getWidth(), listHeight < 300 ? listHeight : 300);
滑动开关
自定义控件步骤:
- 测量:onMeasure 设置自己显示在屏幕上的宽高
- 布局:onLayout 设置自己显示在屏幕上的位置(只有在自定义ViewGroup中才用到)
- 绘制:onDraw 控制显示在屏幕上的样子(自定义viewgroup时不需要这个)
View和ViewGroup的区别
1.他们都需要进行测量操作
2.ViewGroup主要是控制子view如何摆放,所以必须实现onLayout
View没有子view,所以不需要onLayout方法,但是必须实现onDraw
如何将图片资源id转化为图片
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);
设置当前控件在屏幕上的宽高
/*** switchBg是图片资源* @param widthMeasureSpec* @param heightMeasureSpec*/@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);setMeasuredDimension(switchBg.getWidth(), switchBg.getHeight());}
绘制自己显示在屏幕时的样子
@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//1.绘制背景图片//left: 图片的左边的x坐标//top: 图片顶部的y坐标canvas.drawBitmap(switchBg, 0, 0, null);}
处理按钮状态改变事件
这时我们就要用接口来处理这个事件
//ButtonState 为按钮的状态public interface OnButtonStateChangeListener{void onButtonStateChange(ButtonState state);}private OnButtonStateChangeListener listener;public void setOnButtonStateChangeListener(OnButtonStateChangeListener listener){this.listener = listener;}
然后我们就可以在需要的地方把状态传出去
listener.onButtonStateChange(buttonState);
自定义ViewGroup
1、onMeasure()
决定内部view(子view)的宽和高以及自己的宽和高
2、onLayout()
决定子view的放置位置
3、onTouchEvent()
处理触摸事件

浙公网安备 33010602011771号