android 自定义控件

自定义控件

  • 1组合控件:将系统原生控件组合起来加上动画效果,形成一种特殊的动画效果。
  • 2完全自定义控件,继承自系统的View,自己去实现View效果

RotateAnimation

构造函数参数含义
  • fromDegrees 
    从哪个角度开始旋转
  • toDegrees 
    到哪个角度结束
  • pivotXType 
    X轴以什么为参考
  • pivotXValue 
    x轴以哪里为中心,是一个0~1的浮点数
  • pivotYType 
    Y轴以什么为参考
  • pivotYValue 
    y轴以哪里为中心,是一个0~1的浮点数 

     

     

如何在动画完成后保持状态

  1. animation.setFillAfter(true);

设置动画持续时间

  1. animation.setDuration(1000); //持续1s

还可以给动画添加监听事件

  1. animation.setAnimationListener(new Animation.AnimationListener() {
  2. @Override
  3. public void onAnimationStart(Animation animation) {
  4. }
  5. @Override
  6. public void onAnimationEnd(Animation animation) {
  7. }
  8. @Override
  9. public void onAnimationRepeat(Animation animation) {
  10. }
  11. });

添加动画时可能出现的bug

  • 动画完成后已经消失的view,点击原位置还会触发点击事件,这是由于Android原生动画执行后view的位置不发生改变,所以如果想解决此bug就要在view消失的时候禁用,例如 button.setEnabled(false);

 

 

 

如何获取物理按键的点击事件

  1. @Override
  2. public boolean onKeyDown(int keyCode, KeyEvent event) {
  3. if(keyCode == KeyEvent.KEYCODE_MENU){
  4. //然后做自己的处理
  5. return true; //return true代表我们自己处理这个响应
  6. }
  7. return super.onKeyDown(keyCode, event);
  8. }

下拉列表(和QQ登陆那个一点用户名出现用户列表一样)

使用PopupWindow作为弹窗

我们一般使用三个参数的构造函数

  1. PopupWindow popupWindow = new PopupWindow(View contentView, int width, int height);

参数含义

  • contentView :代表我们想让它显示的view
  • width : 弹窗的宽
  • height : 弹窗的高

显示popupWindow

  1. popupWindow.showAsDropDown(View anchor,int xoff, int yoff);

参数含义

  • anchor : 代表在这个控件下面显示
  • xoff : 在x轴上的偏移量
  • yoff : 在y轴上的偏移量

 

 

去除listView的滚动条

当我们不想要listView的滚动条时我们可以这样做

  1. 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总条目的高

  1. //这里的view代表当前listView的条目,list.size()是listView的条目数
  2. int listHeight = view.getHeight() * list.size();
  3. 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转化为图片

  1. Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);

设置当前控件在屏幕上的宽高

  1. /**
  2. * switchBg是图片资源
  3. * @param widthMeasureSpec
  4. * @param heightMeasureSpec
  5. */
  6. @Override
  7. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  8. super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  9. setMeasuredDimension(switchBg.getWidth(), switchBg.getHeight());
  10. }

绘制自己显示在屏幕时的样子

  1. @Override
  2. protected void onDraw(Canvas canvas) {
  3. super.onDraw(canvas);
  4. //1.绘制背景图片
  5. //left: 图片的左边的x坐标
  6. //top: 图片顶部的y坐标
  7. canvas.drawBitmap(switchBg, 0, 0, null);
  8. }

处理按钮状态改变事件

这时我们就要用接口来处理这个事件

  1. //ButtonState 为按钮的状态
  2. public interface OnButtonStateChangeListener{
  3. void onButtonStateChange(ButtonState state);
  4. }
  5. private OnButtonStateChangeListener listener;
  6. public void setOnButtonStateChangeListener(OnButtonStateChangeListener listener){
  7. this.listener = listener;
  8. }

然后我们就可以在需要的地方把状态传出去

  1. listener.onButtonStateChange(buttonState);

自定义ViewGroup

1、onMeasure()

决定内部view(子view)的宽和高以及自己的宽和高

2、onLayout()

决定子view的放置位置

3、onTouchEvent()

处理触摸事件

posted @ 2017-03-13 16:36  天涯海角路  阅读(215)  评论(0)    收藏  举报