美文网首页大智收藏程序员Android开发经验谈
Android自定义ViewPager导航页和自定义按钮

Android自定义ViewPager导航页和自定义按钮

作者: 清枫_小天 | 来源:发表于2016-05-18 22:19 被阅读768次

    使用Viewpager制作导航页

    • 先绘制出那几个点,动态的用java代码编写

            ImageView gray_iView = new ImageView(this);
            gray_iView.setImageResource(R.drawable.gray_shape);
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
            if (i > 0) {
                layoutParams.leftMargin = 20;
            }
            gray_iView.setLayoutParams(layoutParams);
            linearLayout.addView(gray_iView);  
      

    这里用到了LayoutParams给控件设置大小,每个控件都有类似与衣服,我们拿到他设置在穿回去,最终添加到一个水平的线性布局。我们可以将这行代码放到for循环中写,就只需写一句。

    • 在绘制出需要移动的红点,该位置必须与第一个灰点重合。放到包裹那三个点的线性布局的相对布局中

          red_ivImageView = new ImageView(this);
        red_ivImageView.setImageResource(R.drawable.red_shape);
        relativeLayout.addView(red_ivImageView); 
      
    • 在viewPage 的监听方法中的onPageScrolled中调用,设置其leftMargin.第二个参数float类型是划得百分比(0-1),

          RelativeLayout.LayoutParams layoutParams = (android.widget.RelativeLayout.LayoutParams) red_ivImageView
                        .getLayoutParams();
          layoutParams.leftMargin = (int) (left * (arg0+arg1));
          red_ivImageView.setLayoutParams(layoutParams);
      

    left是第二个点到第一个点之间的距离,必须先等其所有的绘制完了才能得到要不然是0,每一个app都有一颗绘制树我们可以从sdk的tools>hierarchyviewer中查看。
    我们可以通过如下代码获取:

           // 绘制试图树
        red_ivImageView.getViewTreeObserver().addOnGlobalLayoutListener(
                new OnGlobalLayoutListener() {
                    // 该方法就是在界面全部绘制结束之后回调
                    @Override
                    public void onGlobalLayout() {
                        left = llLayout.getChildAt(1).getLeft()
                                - llLayout.getChildAt(0).getLeft();
                        Log.d("ZTS", left + "");
                        // 删除回调响应
                        red_ivImageView.getViewTreeObserver()
                                .removeGlobalOnLayoutListener(this);
                    }
                });  
    

    自定义开关按钮

    利用的两张图片实现按钮的功能

    • 写个类继承View 重写里面实现的方法,如果要自定义属性的话还需要两个参数的构造方法,在重写onMeasure(控制控件的大小)和onDraw(控制控件的样式)方法
    • 实现里面的逻辑代码功能
        public static final int STATE_NONE = 0;
        public static final int STATE_DOWN = 1;
        public static final int STATE_MOVE = 2;
        public static final int STATE_UP = 3;
    
        private Bitmap toggleBackground, toggleSolide;
        private Paint paint = new Paint();
        private float currentX;
        private int state = STATE_NONE;
          private boolean isOpen;
    
        private OnToggleListener listener;
       
           private ImageView iv_bg, iv_slid;
    
           public ToggleView(Context context, AttributeSet attrs) {
        super(context, attrs);
           }
    
           public ToggleView(Context context) {
        super(context);
                  }
    
           /*
            * 控制控件的大小
            */
           @Override
           protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    
               if (toggleBackground != null) {
            // 指定控件的宽高
            setMeasuredDimension(toggleBackground.getWidth(),
                    toggleBackground.getHeight());
        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    
        }
    
                  }
       
           /*
            * 控制控件的样式
            */
           @Override
           protected void onDraw(Canvas canvas) {
    
        if (toggleBackground != null) {
            canvas.drawBitmap(toggleBackground, 0, 0, paint);
        }
        switch (state) {
        case STATE_MOVE:
        case STATE_DOWN:
    
            if (currentX > toggleSolide.getWidth() / 2.0f) {
                // 让滑块向右移动(重新位置滑块的位置)
                float left = currentX - toggleBackground.getWidth() / 2f;
                float maxleft = toggleBackground.getWidth()
                        - toggleSolide.getWidth();
                if (left > maxleft) {
                    left = maxleft;
                } else if (left < 0) {
                    left = 0;
                }
                canvas.drawBitmap(toggleSolide, left, 0, paint);
    
            } else if (currentX < toggleSolide.getWidth() / 2.0f) {
                // 滑块不动
                canvas.drawBitmap(toggleSolide, 0, 0, paint);
    
            }
    
            break;
    
        case STATE_UP:
        case STATE_NONE:
            if (isOpen) {
                canvas.drawBitmap(toggleSolide, toggleBackground.getWidth()
                        - toggleSolide.getWidth(), 0, paint);
    
            } else {
                canvas.drawBitmap(toggleSolide, 0, 0, paint);
    
            }
    
            break;
    
        }
    
        super.onDraw(canvas);
    }
    
    /*
     * 设置背景图片
     */
    public void setToggleBackground(int resId) {
        toggleBackground = BitmapFactory.decodeResource(getResources(), resId);
    
    }
    
    /*
     * 设置滑块图片
     */
    public void ToggleSolide(int resId) {
        toggleSolide = BitmapFactory.decodeResource(getResources(), resId);
    
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
    
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            currentX = event.getX();
            // 将标识位进行修改
            state = STATE_DOWN;
            // 通知界面重新绘制
            invalidate();
            // postInvalidate();//在子线程里重新绘制
    
            break;
        case MotionEvent.ACTION_MOVE:
            currentX = event.getX();
            state = STATE_MOVE;
            invalidate();
    
            break;
        case MotionEvent.ACTION_UP:
    
            currentX = event.getX();
            state = STATE_UP;
            if (currentX > toggleBackground.getWidth() / 2) {
                // 滑块在右边,开关处于开启状态
                isOpen = true;
                if (listener != null) {
                    listener.onToggleChanged(true);
                }
            } else if (currentX < toggleBackground.getWidth() / 2) {
                // 滑块在左边,开关处于关闭状态
                isOpen = false;
                if (listener != null) {
                    listener.onToggleChanged(false);
                }
            }
    
            invalidate();
    
            break;
        }
    
        return true;
           }
    
           public void setOnToggleListener(OnToggleListener listener) {
               this.listener = listener;
           }
    
           public interface OnToggleListener {
               abstract void onToggleChanged(boolean isOpen);
           }
    

    自定义收索框

    利用PopupWindows

          popupWindow = new PopupWindow(lv, et.getWidth(),
                    RelativeLayout.LayoutParams.WRAP_CONTENT);
            //设置外面是否能点击取消
            popupWindow.setOutsideTouchable(true);
            popupWindow.setFocusable(true);
             //设置这个背景才有效果
            popupWindow.setBackgroundDrawable(new ColorDrawable());
       //设置在那个的下面
        popupWindow.showAsDropDown(et);

    相关文章

      网友评论

      本文标题:Android自定义ViewPager导航页和自定义按钮

      本文链接:https://www.haomeiwen.com/subject/opwwrttx.html