viewpager 禁用滑到两边的颜色
来源:互联网 发布:高仿永硕e盘源码下载 编辑:程序博客网 时间:2024/05/01 06:50
与listview不同的是:fadeingedge=none即可。
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, floatpositionOffset, int positionOffsetPixels){
if(leftEdge != null && rightEdge != null){
leftEdge.finish();
rightEdge.finish();
leftEdge.setSize(0, 0);
rightEdge.setSize(0, 0);
}
- viewpager 禁用滑到两边的颜色
- ViewPager显示两边的item
- 禁用ViewPager左右两侧拉到边界的渐变颜色
- 禁用ViewPager左右两侧拉到边界的渐变颜色
- Android-viewpager显示左右两边的View
- ViewPager的应用以及禁用滑向下一页
- ViewPager的应用以及禁用滑向下一页
- ViewPager的应用以及禁用滑向下一页
- ViewPager中间大两边小效果的实现
- 禁用viewPager的触摸滑动事件
- 不一样的布局方式 - 从中间到两边
- ViewPager实现Gallery的画廊效果 突显中间 虚化两边的界面
- 禁用滚动视图ListView、ViewPager、ScrollView、HorizontalScrollView、WebView边界颜色渐变
- ViewPager + Fragment两边留白问题
- ViewPager 实现 GallerView 效果, 显示左右两边
- ViewPager 两边显示部分其他页
- viewpager禁用左右滑动
- ViewPager滑动切换禁用
- linux特点
- 使用UITextView的dataDetectorTypes实现超链接,及uiwebview的dataDetectorTypes
- Servlet API
- msdn中关于TimeSetEvent回调函数的说明
- robots.txt
- viewpager 禁用滑到两边的颜色
- xUtils的使用总结
- 如何在Java 8中愉快地处理日期和时间
- xampp 数据库使用
- 设计模式之策略模式
- 增强学习
- 让人看出强势你就输了
- HTML <!DOCTYPE> 标签
- 算法复杂度的计算