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
- BubbleSeekBar开源框架在andorid7.0无法适配的解决方案
- TestDirector8.0在IE8.0下无法使用的解决方案
- TestDirector8.0在IE9下无法使用的解决方案
- mt8735 andorid7.0 lcm调试总结
- ionic入门教程第二十课-在微信中使用ionic的解决方案(开源框架)
- ionic入门教程第二十课-在微信中使用ionic的解决方案(开源框架)
- Struts2验证框架无法显示错误提示的解决方案
- mt8735 andorid7.0 lcm Icn6202驱动(lk)
- mt8735 andorid7.0 lcm Icn6202驱动(kernel)
- 关于在VS2005环境下无法从源视图切换到设计视图的解决方案
- 关于在VS2005环境下无法从源视图切换到设计视图的解决方案
- 关于在VS2005环境下无法从源视图切换到设计视图的解决方案
- .NET2.0程序集无法在.net 4.0 中运行的解决方案
- .NET2.0程序集无法在.net 4.0 中运行的解决方案--针对vsts测试项目
- ASP.NET 4.5 MVC 4 无法在Windows2008的IIS7.0上解决方案
- .NET2.0程序集无法在.net 4.0 中运行的解决方案
- AForge.NET .NET2.0程序集无法在.net 4.0 中运行的解决方案
- .NET2.0程序集无法在.net 4.0 中运行的解决方案
- DAY6作业-百度登录框
- iOS获取类名NSStringFromClass 和 获取类NSClassFromString
- Lru cache算法以及他的锁的问题
- OpenStack安装与配置
- 动态规划为什么就是经典?
- BubbleSeekBar开源框架在andorid7.0无法适配的解决方案
- Node学习过程中遇到的一些小问题
- 使用Google的zxing组件识别二维码时,调整扫描区域和取景框的大小
- Easy 20 Same Tree(100)
- Android实现socket简单通讯总结
- mybatis自动生成代码git地址
- Spring AOP详解
- Java 网络编程时序问题
- 用深度学习解决大规模文本分类问题