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左右两侧拉到边界的渐变颜色的更多相关文章

  1. 禁用ViewPager边界滑动效果(转)

    反射设置方法 private EdgeEffectCompat leftEdge; private EdgeEffectCompat rightEdge; public void DisableLRS ...

  2. 禁用ViewPager的滑动事件

    public class NoScrollViewPager extends ViewPager { private boolean noScroll = false; public NoScroll ...

  3. 禁用ipv6的两种方法

    1 通过系统配置文件/etc/sysctl.conf 在sysctl.conf文件中添加行 # 禁用整个系统所有接口的IPv6 net.ipv6.conf.all.disable_ipv6 = 1 # ...

  4. 通过focusInEvent和eventFilter两种方法改写控件颜色(自定义控件就是这么来的)

    http://www.cnblogs.com/hicjiajia/archive/2012/05/30/2526768.html http://www.cnblogs.com/hicjiajia/ar ...

  5. 禁用滚动视图ListView、ViewPager、ScrollView、HorizontalScrollView、WebView边界颜色渐变

    禁用滚动视图ListView.ViewPager.ScrollView.HorizontalScrollView.WebView边界颜色渐变 ListView.ViewPager.ScrollView ...

  6. Android照片墙加强版,使用ViewPager实现画廊效果

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/12646775 记得关于照片墙的文章我已经写过好几篇了,有最基本的照片墙,有瀑布流模 ...

  7. 学习bootstrap遇到的问题--001 关于bootstrap中类.disabled不禁用默认行为

    自学bootstrap遇到的疑惑篇: 按钮状态--禁用 在Bootstrap框架中,要禁用按钮有两种实现方式: 方法1:在标签中添加disabled属性 方法2:在元素标签中添加类名"dis ...

  8. 安卓开发笔记——Fragment+ViewPager组件(高仿微信界面)

    什么是ViewPager? 关于ViewPager的介绍和使用,在之前我写过一篇相关的文章<安卓开发复习笔记——ViewPager组件(仿微信引导界面)>,不清楚的朋友可以看看,这里就不再 ...

  9. tomcat 禁用不安全的http请求模式 .

    HTTP服务器至少应该实现GET和HEAD方法,其他方法都是可选的.当然,所有的方法支持的实现都应当符合下述的方法各自的语义定义.此外,除了上述方法,特定的HTTP服务器还能够扩展自定义的方法. ht ...

随机推荐

  1. FileTable使用总结

    sqlsever2012以后才开始支持FileTable,具体的FileTable的介绍可以参考微软的官网 http://msdn.microsoft.com/zh-cn/library/gg5090 ...

  2. python多进程并发

    由于Python下调用Linux的Shell命令都需要等待返回,所以常常我们设置的多线程都达不到效果,因此在调用shell命令不需要返回时,使用threading模块并不是最好的方法.   http: ...

  3. Urllib3 库详解

    文档:http://urllib3.readthedocs.io/en/latest/

  4. js关于弹也遮罩层

    1:什么是遮罩层 遮罩层:我是弹也一个(遮罩层)还有一个(内容层),下面上图片看一效果 我们看到一个灰蒙蒙的遮盖(其实也是一个层)还有一个层(也就是我们展示的内容). 2:  弹出层效果居中分析 在这 ...

  5. R语言-向量化操作(apply、tapply、lapply、sapply、mapply、table等)

    一.apply函数(对一个数组按行或者按列进行计算): 使用格式为:apply(X, MARGIN, FUN, ...) 其中X为一个数组:MARGIN为一个向量(表示要将函数FUN应用到X的行还是列 ...

  6. MySQL 先按某字段分组,再取每组中前N条记录

    按 gpcode每组 取每组 f4 最大的那条记录: 方法一: select * from calcgsdataflash a where gscode = 'LS_F' and ymd >= ...

  7. elasticsearch系列四:搜索详解(搜索API、Query DSL)

    一.搜索API 1. 搜索API 端点地址 从索引tweet里面搜索字段user为kimchy的记录 GET /twitter/_search?q=user:kimchy 从索引tweet,user里 ...

  8. 多媒体开发之rtmp---rtmp client 编译

    静态库连接编译问题: assert 原来在c编译器下没定义 ceill 没连接没加 -lm http://blog.chinaunix.net/uid-20681545-id-3786786.html ...

  9. Build opencv libraries for android arm, x86 ubuntu

    废话不多说. 准备工作: 1. 下载源代码: http://opencv.org/ 编译平台:ubuntu14.04 opencv 2.4.6.1 本人用这样的办法编译了opecv 2.4.9 的没有 ...

  10. perl 读取json 格式的文件

    使用JSON 模块中的 decode_json 函数,将json文件中的数据解码为perl 中的对象,然后进行处理 代码如下: #!/usr/bin/env perl use JSON; use En ...