禁用ViewPager左右两侧拉到边界的渐变颜色
Android ViewPager在拖拽到左边和右边的时候,禁止显示黄色或者蓝色的渐变图片的解决方法
先说明哦,想看看院里的,从头开始看,否则,就拉到最下面啦。解决方案就在最下面。
修改前:

修改后:

先看下ViewPager中和这个颜色相关的代码:
|
private EdgeEffectCompat mLeftEdge; private EdgeEffectCompat mRightEdge; |
就是这俩货,导致的边界颜色。没办法,这货是private的,后面只能通过反射来得到了。
再看下draw()方法中的逻辑:
|
@Override public void draw(Canvas canvas) { super.draw(canvas); boolean needsInvalidate = false; final int overScrollMode = ViewCompat.getOverScrollMode(this); if (overScrollMode == ViewCompat.OVER_SCROLL_ALWAYS || (overScrollMode == ViewCompat.OVER_SCROLL_IF_CONTENT_SCROLLS && mAdapter != null && mAdapter.getCount() > 1)) { if (!mLeftEdge.isFinished()) { final int restoreCount = canvas.save(); final int height = getHeight() - getPaddingTop() - getPaddingBottom(); canvas.rotate(270); canvas.translate(-height + getPaddingTop(), 0); mLeftEdge.setSize(height, getWidth()); needsInvalidate |= mLeftEdge.draw(canvas); canvas.restoreToCount(restoreCount); } if (!mRightEdge.isFinished()) { final int restoreCount = canvas.save(); final int width = getWidth(); final int height = getHeight() - getPaddingTop() - getPaddingBottom(); final int itemCount = mAdapter != null ? mAdapter.getCount() : 1; canvas.rotate(90); canvas.translate(-getPaddingTop(), -itemCount * (width + mPageMargin) + mPageMargin); mRightEdge.setSize(height, width); needsInvalidate |= mRightEdge.draw(canvas); canvas.restoreToCount(restoreCount); } } else { mLeftEdge.finish(); mRightEdge.finish(); } if (needsInvalidate) { // Keep animating invalidate(); } } |
在进行绘制渐变图片之前会判断是否已经finish,【if (!mLeftEdge.isFinished())】,如果我们能修改为finished状态,不就OK了吗?!经过测试,调用mLeftEdge.finish()和mRightEdge.finish()就能达到我们要的结果。但是悲催的是,draw()方法是随时随地都在调用的,所以要在一个在draw()方法之后调用,但是还得随时随地调用的方法才行。
好吧,先说点原理的东东。
ViewPager.javaàdraw()方法 à mRightEdge.draw(canvas);以及mLeftEdge.draw(canvas);à EdgeEffectCompat.javaà看下全部的代码吧:
|
public class EdgeEffectCompat { private Object mEdgeEffect; private static final EdgeEffectImpl IMPL; static { if (Build.VERSION.SDK_INT >= 14) { // ICS IMPL = new EdgeEffectIcsImpl(); } else { IMPL = new BaseEdgeEffectImpl(); } } interface EdgeEffectImpl { public Object newEdgeEffect(Context context); public void setSize(Object edgeEffect, int width, int height); public boolean isFinished(Object edgeEffect); public void finish(Object edgeEffect); public boolean onPull(Object edgeEffect, float deltaDistance); public boolean onRelease(Object edgeEffect); public boolean onAbsorb(Object edgeEffect, int velocity); public boolean draw(Object edgeEffect, Canvas canvas); } /** * Null implementation to use pre-ICS */ static class BaseEdgeEffectImpl implements EdgeEffectImpl { public Object newEdgeEffect(Context context) { return null; } public void setSize(Object edgeEffect, int width, int height) { } public boolean isFinished(Object edgeEffect) { return true; } public void finish(Object edgeEffect) { } public boolean onPull(Object edgeEffect, float deltaDistance) { return false; } public boolean onRelease(Object edgeEffect) { return false; } public boolean onAbsorb(Object edgeEffect, int velocity) { return false; } public boolean draw(Object edgeEffect, Canvas canvas) { return false; } } static class EdgeEffectIcsImpl implements EdgeEffectImpl { public Object newEdgeEffect(Context context) { return EdgeEffectCompatIcs.newEdgeEffect(context); } public void setSize(Object edgeEffect, int width, int height) { EdgeEffectCompatIcs.setSize(edgeEffect, width, height); } public boolean isFinished(Object edgeEffect) { return EdgeEffectCompatIcs.isFinished(edgeEffect); } public void finish(Object edgeEffect) { EdgeEffectCompatIcs.finish(edgeEffect); } public boolean onPull(Object edgeEffect, float deltaDistance) { return EdgeEffectCompatIcs.onPull(edgeEffect, deltaDistance); } public boolean onRelease(Object edgeEffect) { return EdgeEffectCompatIcs.onRelease(edgeEffect); } public boolean onAbsorb(Object edgeEffect, int velocity) { return EdgeEffectCompatIcs.onAbsorb(edgeEffect, velocity); } public boolean draw(Object edgeEffect, Canvas canvas) { return EdgeEffectCompatIcs.draw(edgeEffect, canvas); } } /** * Construct a new EdgeEffect themed using the given context. * * <p>Note: On platform versions that do not support EdgeEffect, all operations * on the newly constructed object will be mocked/no-ops.</p> * * @param context Context to use for theming the effect */ public EdgeEffectCompat(Context context) { mEdgeEffect = IMPL.newEdgeEffect(context); } /** * Set the size of this edge effect in pixels. * * @param width Effect width in pixels * @param height Effect height in pixels */ public void setSize(int width, int height) { IMPL.setSize(mEdgeEffect, width, height); } /** * Reports if this EdgeEffectCompat's animation is finished. If this method returns false * after a call to {@link #draw(Canvas)} the host widget should schedule another * drawing pass to continue the animation. * * @return true if animation is finished, false if drawing should continue on the next frame. */ public boolean isFinished() { return IMPL.isFinished(mEdgeEffect); } /** * Immediately finish the current animation. * After this call {@link #isFinished()} will return true. */ public void finish() { IMPL.finish(mEdgeEffect); } /** * A view should call this when content is pulled away from an edge by the user. * This will update the state of the current visual effect and its associated animation. * The host view should always {@link android.view.View#invalidate()} if this method * returns true and draw the results accordingly. * * @param deltaDistance Change in distance since the last call. Values may be 0 (no change) to * 1.f (full length of the view) or negative values to express change * back toward the edge reached to initiate the effect. * @return true if the host view should call invalidate, false if it should not. */ public boolean onPull(float deltaDistance) { return IMPL.onPull(mEdgeEffect, deltaDistance); } /** * Call when the object is released after being pulled. * This will begin the "decay" phase of the effect. After calling this method * the host view should {@link android.view.View#invalidate()} if this method * returns true and thereby draw the results accordingly. * * @return true if the host view should invalidate, false if it should not. */ public boolean onRelease() { return IMPL.onRelease(mEdgeEffect); } /** * Call when the effect absorbs an impact at the given velocity. * Used when a fling reaches the scroll boundary. * * <p>When using a {@link android.widget.Scroller} or {@link android.widget.OverScroller}, * the method <code>getCurrVelocity</code> will provide a reasonable approximation * to use here.</p> * * @param velocity Velocity at impact in pixels per second. * @return true if the host view should invalidate, false if it should not. */ public boolean onAbsorb(int velocity) { return IMPL.onAbsorb(mEdgeEffect, velocity); } /** * Draw into the provided canvas. Assumes that the canvas has been rotated * accordingly and the size has been set. The effect will be drawn the full * width of X=0 to X=width, beginning from Y=0 and extending to some factor < * 1.f of height. * * @param canvas Canvas to draw into * @return true if drawing should continue beyond this frame to continue the * animation */ public boolean draw(Canvas canvas) { return IMPL.draw(mEdgeEffect, canvas); } } |
à看完之后,下面进入到EdgeEffectCompatIcs.javaà好吧,再贴上完整的代码
|
class EdgeEffectCompatIcs { public static Object newEdgeEffect(Context context) { return new EdgeEffect(context); } public static void setSize(Object edgeEffect, int width, int height) { ((EdgeEffect) edgeEffect).setSize(width, height); } public static boolean isFinished(Object edgeEffect) { return ((EdgeEffect) edgeEffect).isFinished(); } public static void finish(Object edgeEffect) { ((EdgeEffect) edgeEffect).finish(); } public static boolean onPull(Object edgeEffect, float deltaDistance) { ((EdgeEffect) edgeEffect).onPull(deltaDistance); return true; } public static boolean onRelease(Object edgeEffect) { EdgeEffect eff = (EdgeEffect) edgeEffect; eff.onRelease(); return eff.isFinished(); } public static boolean onAbsorb(Object edgeEffect, int velocity) { ((EdgeEffect) edgeEffect).onAbsorb(velocity); return true; } public static boolean draw(Object edgeEffect, Canvas canvas) { return ((EdgeEffect) edgeEffect).draw(canvas); } } |
à下面进入到EdgeEffect.java中吧à如果你有闲情逸致的话,那就看下他的代码吧,都是这货在搞鬼。
下面就说正经的内容了,看看我的解决方案:
主要是在自定义的OnPageChangeListener里面。
先定义一下:
|
private EdgeEffectCompat leftEdge; private EdgeEffectCompat rightEdge; |
然后是构造中,通过反射得到对象:
|
try { Field leftEdgeField = mViewPager.getClass().getDeclaredField("mLeftEdge"); Field rightEdgeField = mViewPager.getClass().getDeclaredField("mRightEdge"); Log.i("xinye", "=======leftEdgeField:" + leftEdgeField + ",rightEdgeField:" + rightEdgeField); if(leftEdgeField != null && rightEdgeField != null){ leftEdgeField.setAccessible(true); rightEdgeField.setAccessible(true); leftEdge = (EdgeEffectCompat) leftEdgeField.get(mViewPager); rightEdge = (EdgeEffectCompat) rightEdgeField.get(mViewPager); Log.i("xinye", "=======OK啦,leftEdge:" + leftEdge + ",rightEdge:" + rightEdge); } } catch (Exception e) { e.printStackTrace(); } |
然后,就是最重要的了:
|
@Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels){ if(leftEdge != null && rightEdge != null){ leftEdge.finish(); rightEdge.finish(); leftEdge.setSize(0, 0); rightEdge.setSize(0, 0); } |
好吧,完事了。做做看吧
禁用ViewPager左右两侧拉到边界的渐变颜色的更多相关文章
- 禁用ViewPager边界滑动效果(转)
反射设置方法 private EdgeEffectCompat leftEdge; private EdgeEffectCompat rightEdge; public void DisableLRS ...
- 禁用ViewPager的滑动事件
public class NoScrollViewPager extends ViewPager { private boolean noScroll = false; public NoScroll ...
- 禁用ipv6的两种方法
1 通过系统配置文件/etc/sysctl.conf 在sysctl.conf文件中添加行 # 禁用整个系统所有接口的IPv6 net.ipv6.conf.all.disable_ipv6 = 1 # ...
- 通过focusInEvent和eventFilter两种方法改写控件颜色(自定义控件就是这么来的)
http://www.cnblogs.com/hicjiajia/archive/2012/05/30/2526768.html http://www.cnblogs.com/hicjiajia/ar ...
- 禁用滚动视图ListView、ViewPager、ScrollView、HorizontalScrollView、WebView边界颜色渐变
禁用滚动视图ListView.ViewPager.ScrollView.HorizontalScrollView.WebView边界颜色渐变 ListView.ViewPager.ScrollView ...
- Android照片墙加强版,使用ViewPager实现画廊效果
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/12646775 记得关于照片墙的文章我已经写过好几篇了,有最基本的照片墙,有瀑布流模 ...
- 学习bootstrap遇到的问题--001 关于bootstrap中类.disabled不禁用默认行为
自学bootstrap遇到的疑惑篇: 按钮状态--禁用 在Bootstrap框架中,要禁用按钮有两种实现方式: 方法1:在标签中添加disabled属性 方法2:在元素标签中添加类名"dis ...
- 安卓开发笔记——Fragment+ViewPager组件(高仿微信界面)
什么是ViewPager? 关于ViewPager的介绍和使用,在之前我写过一篇相关的文章<安卓开发复习笔记——ViewPager组件(仿微信引导界面)>,不清楚的朋友可以看看,这里就不再 ...
- tomcat 禁用不安全的http请求模式 .
HTTP服务器至少应该实现GET和HEAD方法,其他方法都是可选的.当然,所有的方法支持的实现都应当符合下述的方法各自的语义定义.此外,除了上述方法,特定的HTTP服务器还能够扩展自定义的方法. ht ...
随机推荐
- sed实现文件自我复制
sed -n '1,$'p test >> test
- PCL特征点与配准(1)
关于输入一个具体的物体的点云,从场景中找出与该物体点云相匹配的,这种方法可以用来抓取指定的物体等等,具体的代码的解释如下,需要用到的一些基础的知识,在之前的博客中都有提及,其中用到的一些方法可以翻阅前 ...
- Eclipse配置方法注释模板
Java-->Code Style-->Code Templates-->Comments
- Vue 获取自定义属性的值
在jquery中,如果要获取 data-*** 的值可以通过 $('目标元素').data('属性名') 来获取. 在Vue中如何获取该值呢? 1.换个思路,作为参数传递. 如下代码: <but ...
- mysql导入sql脚本
例如:我的用户名是root 密码是123 sql脚本存在C盘 名字为test.sql 数据库为test 有两种方法可以执行脚本 1:打开CMD输入以下命令(不需要转换目录)>mysql -u r ...
- 【转】Android下使用Properties文件保存程序设置
原文:http://jerrysun.blog.51cto.com/745955/804789 废话不说,直接上代码. 读取.properties文件中的配置: String strValue ...
- mysql insert exists || mysql 判断数据是否存在
情景如下: "今日前端忽然说句, 我需要做个判断, 不能重复收藏, 我犹如颈有寒冰不寒而栗, 于是思考我该怎么做?为什么她都思考到了我没有思考到这是我的工作啊" 思考后得到三种解决 ...
- C语言中 Float 数据结构的存储计算
1.了解float存储结构 float存储结构请看另一篇文章http://blog.csdn.net/whzhaochao/article/details/12885875 2.float最大值 fl ...
- 免费在线直播课,送给所有IT项目经理
[免费在线直播课,送给所有IT项目经理]项目管理培训领域的老资格——光环国际,精心策划了一门一个半小时的在线直播课,送给所有辛苦的IT项目经理们.[直播主题]变化时代IT项目经理的成长要求[直播内容 ...
- mysql 5.1超过默认8小时空闲时间解决办法(错误:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure)
报错: MySQL第二天早上第一次连接超时报错, com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications lin ...