[Android開發]仿天天P圖帶氣泡顯示百分比進度的自定義SeekBar

仿天天P圖圖像美化修改工具,素材來自於天天P圖,效果圖


效果就是點擊之後會有氣泡顯示進度,優點是氣泡不佔用控件的高度

其他效果可參看https://github.com/AnderWeb/discreteSeekBar

實現方法:

添加OnSeekBarChangeListener,監聽進度

	private OnSeekBarChangeListener mOnSeekBarChangeListener = new OnSeekBarChangeListener() {
		
		@Override
		public void onStopTrackingTouch(SeekBar seekBar) {
			mBubbleIndicator.hideIndicator();
		}
		
		@Override
		public void onStartTrackingTouch(SeekBar seekBar) {
			mBubbleIndicator.showIndicator(seekBar, mThumbDrawable.getBounds());
		}
		
		@Override
		public void onProgressChanged(SeekBar seekBar, int progress,
				boolean fromUser) {
			if(fromUser)
				mBubbleIndicator.moveIndicator(mThumbDrawable.getBounds(), progress);
		}
	};

在氣泡類BubbleIndicator中,有個內部類Floater繼承於framelayout用於顯示數字氣泡,氣泡不通過重寫seekbar的ondraw來繪製在seekbar中,而是通過WindowManager使用懸浮窗口的基本原理來添加view。

點擊thumb,創建並且顯示氣泡

    public void showIndicator(View parent, Rect touchBounds) {
        if (isShowing()) {
            return;
        }

        IBinder windowToken = parent.getWindowToken();
        if (windowToken != null) {
            WindowManager.LayoutParams p = createPopupLayout(windowToken);

            p.gravity = Gravity.TOP | GravityCompat.START;
            updateLayoutParamsForPosiion(parent, p);
            mShowing = true;

            translateViewIntoPosition(touchBounds.centerX());
            invokePopup(p);
        }
    }
	
    private WindowManager.LayoutParams createPopupLayout(IBinder windowToken) {
        WindowManager.LayoutParams p = new WindowManager.LayoutParams();
        p.gravity = Gravity.START | Gravity.TOP;
        p.width = ViewGroup.LayoutParams.MATCH_PARENT;
        p.height = ViewGroup.LayoutParams.MATCH_PARENT;
        p.format = PixelFormat.TRANSLUCENT;
        p.flags = computeFlags(p.flags);
        p.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
        p.token = windowToken;
        p.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN;
        return p;
    }
	
    private void invokePopup(WindowManager.LayoutParams p) {
        mWindowManager.addView(mPopupView, p);
    }

氣泡的初始x座標是0,寬度屏幕寬,高度爲thumb所在座標減去氣泡高度

    private void updateLayoutParamsForPosiion(View anchor, WindowManager.LayoutParams p) {
        measureFloater();
        int measuredHeight = mPopupView.getMeasuredHeight();
        anchor.getLocationInWindow(mDrawingLocation);
        p.x = 0;
        p.y = mDrawingLocation[1] - measuredHeight;
        p.width = screenSize.x;
        p.height = measuredHeight;
    }
然後根據thumb中心位置調整氣泡位置

    private void translateViewIntoPosition(final int x) {
        mPopupView.setFloatOffset(x + mDrawingLocation[0]);
    }
x是thumb所在rect的centerX,加上其坐在的初始位置,最終結果爲移動後的位置。

然後在內部類floater中調整其位置

	private class Floater extends FrameLayout{
        public TextView mMarker;
        private int mOffset;

        public Floater(Context context, AttributeSet attrs, int defStyleAttr, String maxValue) {
            super(context);
            mMarker = new TextView(context);
            mMarker.setText("0%");
            mMarker.setGravity(Gravity.CENTER);
            mMarker.setBackgroundResource(R.drawable.tooltip_bg);
            addView(mMarker, new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP));
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            measureChildren(widthMeasureSpec, heightMeasureSpec);
            int widthSize = MeasureSpec.getSize(widthMeasureSpec);
            int heightSie = mMarker.getMeasuredHeight();
            setMeasuredDimension(widthSize, heightSie);
        }

        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            int centerDiffX = (mMarker.getMeasuredWidth() - mMarker.getPaddingLeft()) / 2;
            int offset = mOffset - centerDiffX;
            mMarker.layout(offset, 0, offset + mMarker.getMeasuredWidth(), mMarker.getMeasuredHeight());
        }

        public void setFloatOffset(int x) {
            mOffset = x;
            int centerDiffX = (mMarker.getMeasuredWidth() - mMarker.getPaddingLeft()) / 2;
            int offset = mOffset - centerDiffX;
            mMarker.offsetLeftAndRight(offset - mMarker.getLeft());
        }
        
        public void setProgressText(int progress){
            mMarker.setText(""+progress+"%");
        }
    }

通過offsetLeftAndRight設置左右位移,位移距離爲移動的距離減去移動前距離左邊的距離

移動thumb時,同時移動氣泡

	public void moveIndicator(Rect touchBounds, int progress) {
		if (!isShowing()) {
            return;
        }
	<span style="white-space:pre">	</span>translateViewIntoPosition(touchBounds.centerX());
		mPopupView.setProgressText(progress);
	}
	
	private void translateViewIntoPosition(final int x) {
       <span style="white-space:pre">	</span> <span style="white-space:pre">	</span>mPopupView.setFloatOffset(x + mDrawingLocation[0]);
    }
	
鬆開時,移除氣泡、

	public void hideIndicator(){
		if (!isShowing()) {
            return;
        }
		mShowing = false;
		mWindowManager.removeView(mPopupView);
	}

代碼地址:

http://download.csdn.net/detail/oshunz/9372241


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章