本文主要讲述两个知识点: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"        />

运行效果

更多相关文章

  1. Android监听网络状态实现(BroadcastReceiver + Service) .
  2. Android(安卓)中文 API (25) —— ZoomControls
  3. android android:duplicateParentState="true"/ "false"
  4. Android中View的事件分发机制
  5. Android(安卓)Fragment 剖析 - 01
  6. Android开发四年相关面试知识整理
  7. Android(安卓)UI开发第十三篇——android-viewflow
  8. Android常见的Event-driven方案
  9. ANDROID中点击事件的实现方式

随机推荐

  1. ubuntu下无法更新android sdk
  2. 四、 Android之手机屏幕朝向
  3. Android 常用编程技巧
  4. 相对布局RelativeLayout
  5. 扫描二维码自动识别手机系统(Android/IOS)
  6. android EditText 实现搜索框点击搜索隐
  7. [置顶] Android学习博客和文章存档
  8. Android Service总结06 之AIDL
  9. 修改android 系统设置 android 版本
  10. EditText 相关功能