BubbleSeekBar开源框架在andorid7.0无法适配的解决方案

来源:互联网 发布:python单行注释 编辑:程序博客网 时间:2024/05/21 01:47

这里写图片描述
我们经常会用到带气泡问题提示的拖动seekbar。这里有一个非常好用的自定义seekbar框架BubbleSeekBar开源框架:https://github.com/widegalaxy/BubbleSeekBar/tree/5ccf3e91f0cc7e8ac5c338ae8ca709c2324bef59

但我在项目中使用的时候发现了一个问题,在android7.0系统上,竟然不能适配。想了很多解决办法,最后无解。如果哪位大神有好的解决方法,希望不吝赐教。查了很多资料只查到了PopupWindow 在 Android N(7.0) 的兼容性问题(解决方法:http://www.jianshu.com/p/0df10893bf5b)。但BubbleSeekBar的问题还是没有解决。它存在问题的主要代码是这块:

   if (mLayoutParams == null) {                mLayoutParams = new WindowManager.LayoutParams();                mLayoutParams.gravity = Gravity.TOP | GravityCompat.START;                mLayoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT;                mLayoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;                mLayoutParams.format = PixelFormat.TRANSLUCENT;                mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL                        | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE                        | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;                mLayoutParams.type = WindowManager.LayoutParams.TYPE_TOAST;//展示类型Toast                mLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN;            }            mLayoutParams.x = (int) mBubbleCenterRawX;            mLayoutParams.y = (int) mBubbleCenterRawSolidY;            mBubbleView.setAlpha(0);            mBubbleView.setVisibility(VISIBLE);            mBubbleView.animate().alpha(1f).setDuration(200)                    .setListener(new AnimatorListenerAdapter() {                        @Override                        public void onAnimationStart(Animator animation) {                            super.onAnimationStart(animation);                            try {                                mWindowManager.addView(mBubbleView, mLayoutParams);                            } catch (Exception x) {                            }                        }                    }).start();

后来没办法,只能重新找了一个自定义控件,修改成了自己想要的样式。

新的自定义控件有两个类组成,代码如下:

public class BubbleIndicator {    private final WindowManager mWindowManager;    private boolean mShowing;    private int[] mDrawingLocation = new int[2];    Point screenSize = new Point();    private Floater mPopupView;    public BubbleIndicator(Context context, AttributeSet attrs, int defStyleAttr, String maxValue) {        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);        mPopupView = new Floater(context, attrs, defStyleAttr, maxValue);        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();        screenSize.set(displayMetrics.widthPixels, displayMetrics.heightPixels);    }    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);    }    public void moveIndicator(Rect touchBounds, int progress) {        if (!isShowing()) {            return;        }        translateViewIntoPosition(touchBounds.centerX());        mPopupView.setProgressText(progress);    }    public void hideIndicator() {        if (!isShowing()) {            return;        }        mShowing = false;        mWindowManager.removeView(mPopupView);    }    private void translateViewIntoPosition(final int x) {        mPopupView.setFloatOffset(x + mDrawingLocation[0]);    }    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;    }    private void measureFloater() {        int specWidth = View.MeasureSpec.makeMeasureSpec(screenSize.x, View.MeasureSpec.EXACTLY);        int specHeight = View.MeasureSpec.makeMeasureSpec(screenSize.y, View.MeasureSpec.AT_MOST);        mPopupView.measure(specWidth, specHeight);    }    private boolean isShowing() {        return mShowing;    }    private int computeFlags(int curFlags) {        curFlags &= ~(                WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES |                        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |                        WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |                        WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |                        WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |                        WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);        curFlags |= WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES;        curFlags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;        curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;        curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;        return curFlags;    }    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.0");            // mMarker.setGravity(Gravity.CENTER);            mMarker.setPadding(20, 5, 5, 10);            mMarker.setTextColor(getResources().getColor(R.color.white));            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 + "%");        }    }}
public class BubbleSeekBar extends android.support.v7.widget.AppCompatSeekBar {    private Drawable mThumbDrawable;    private BubbleIndicator mBubbleIndicator;    public BubbleSeekBar(Context context) {        this(context, null);    }    public BubbleSeekBar(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public BubbleSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        mBubbleIndicator = new BubbleIndicator(context, attrs, defStyleAttr, "100");        setOnSeekBarChangeListener(mOnSeekBarChangeListener);    }    @Override    public void setThumb(Drawable thumb) {        super.setThumb(thumb);        mThumbDrawable = thumb;    }    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);        }    };}

用的时候,直接在布局文件中添加自定义控件即可

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.beibaokongming.seekbardemo.Main2Activity">    <com.beibaokongming.seekbardemo.BubbleSeekBar        style="@style/SeekBar"        android:layout_width="368dp"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        tools:layout_editor_absoluteX="8dp"        tools:layout_editor_absoluteY="196dp" /></RelativeLayout>

源码下载地址:http://download.csdn.net/detail/beibaokongming/9823949

2 0
原创粉丝点击