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

使用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);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容