Android Velocity View寻呼机设置CurrentItem不工作
我正在使用VelocityViewPage来实现一个flingable ViewPager。我试图通过在VelocityViewPager的中间显示元素(日期1970)来设置视图寻呼机初始化。因此,在片段的onViewCreated()中,我执行以下操作:Android Velocity View寻呼机设置CurrentItem不工作,android,android-viewpager,Android,Android Viewpager,我正在使用VelocityViewPage来实现一个flingable ViewPager。我试图通过在VelocityViewPager的中间显示元素(日期1970)来设置视图寻呼机初始化。因此,在片段的onViewCreated()中,我执行以下操作: velocityViewPager.setCurrentItem(69); 一位用户建议执行以下操作,以在的评论中修复此问题: 但是,当我尝试此操作时,它不起作用,我将无法看到ViewPager的元素68、69和70,因为scrollX会被
velocityViewPager.setCurrentItem(69);
一位用户建议执行以下操作,以在的评论中修复此问题:
但是,当我尝试此操作时,它不起作用,我将无法看到ViewPager的元素68、69和70,因为scrollX会被卡住,因为偏移量会将scrollX“锁定”到某个范围
我注意到的问题是scrollX被初始化为0,而它实际上应该是一个表示位置69的值。我试图用XML手动设置scrollX,用Java代码设置scrollX,并进行各种偏移量计算,但都无济于事 这就是我最终为一个令人畏惧的视角所做的。这肯定比仅仅从查看寻呼机扩展更痛苦(我需要大量的尝试和错误),但它给了我我想要的。您必须找到一种使用视图的scrollX的方法,以确定要捕捉到的项目以及到达视图的末尾或开头时要执行的操作
public class FlingableScroller extends View implements GestureDetector.OnGestureListener {
public FlingableScroller(Context context, AttributeSet attrs) {
super(context, attrs);
mGestureDetector = new GestureDetector(context, this);
mScroller = new OverScroller(context);
//This is how you "set current item" You will have to calculate INITIAL_SCROLL_X yourself
setScrollX(INITIAL_SCROLL_X);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
animateFlingIfApplicable();
}
private void animateFlingIfApplicable() {
//We have a fling only if computeScrollOffset is true.
if (mScroller.computeScrollOffset()) {
//Flinging passed the start point so continue the fling at the end
if (mScroller.getFinalX() == 0) {
int velocity = getFlingVelocity();
mScroller.forceFinished(true);
mScroller.fling(MAXIMUM_SCROLL_X, 0, velocity / FRICTION_COEFFICIENT, 0, 0, MAXIMUM_SCROLL_X, 0, 0);
//Flinging passed the end point so continue the fling at the start
} else if (mScroller.getFinalX() == MAXIMUM_SCROLL_X) {
int velocity = getFlingVelocity();
mScroller.forceFinished(true);
mScroller.fling(0, 0, velocity / FRICTION_COEFFICIENT, 0, 0, MAXIMUM_SCROLL_X, 0, 0);
} else if (mScroller.getFinalX() == getScrollX() || mScroller.getCurrVelocity() == 0) {
snapToItem();
mScroller.forceFinished(true);
} else {
scrollTo(mScroller.getCurrX(), 0);
}
}
invalidate();
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
//This logic handles the case when you scroll pass the beginning or the end of the scroller
if (getScrollX() > MAXIMUM_SCROLL_X) {
scrollTo(0, 0);
} else if (getScrollX() >= 0) {
scrollBy(distance, 0);
} else {
scrollTo(MAXIMUM_SCROLL_X, 0);
}
invalidate();
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
//This is to prevent low velocity "flings"
if (Math.abs(velocityX) < 400 * SCREEN_DENSITY) {
return false;
}
mScroller.forceFinished(true);
//Define friction_coefficient to a value that gives you desirable flinging.
mScroller.fling(getScrollX(), getScrollY(), (int) -velocityX / FRICTION_COEFFICIENT, 0, 0, MAXIMUM_SCROLL_X, 0, 0);
invalidate();
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mScroller.forceFinished(true);
break;
case MotionEvent.ACTION_UP:
snapToItem();
invalidate();
break;
}
return mGestureDetector.onTouchEvent(event);
}
private void snapToItem() {
//The the user lifts up their finger from a scroll or when a fling finishes determine what item to snap to. See the ViewPager source code to emulate the "fake drag"
int scrollByValue = getScrollX() / SOME_VALUE
scrollTo(scrollByValue, 0);
}
}
公共类FlingableScroller扩展视图实现GestureDetector.OnTestureListener{
公共属性集(上下文、属性集属性){
超级(上下文,attrs);
mGestureDetector=新的GestureDetector(上下文,本);
mScroller=新的OverScroller(上下文);
//这是您“设置当前项目”的方式,您必须自己计算初始滚动
设置滚动条(初始滚动条);
}
@凌驾
受保护的void onDraw(画布){
super.onDraw(帆布);
animateflingifapplicate();
}
私有void animateflingifapplicate(){
//只有当computeScrollOffset为真时,我们才有机会。
if(mScroller.computeScrollOffset()){
//投掷已经过了起点,所以在终点继续投掷
if(mScroller.getFinalX()==0){
int velocity=getFlingVelocity();
mScroller.forceFinished(真);
mScroller.fling(最大滚动次数,0,速度/摩擦系数,0,0,最大滚动次数,0,0);
//投掷已过终点,因此在起点继续投掷
}else if(mScroller.getFinalX()==最大滚动次数){
int velocity=getFlingVelocity();
mScroller.forceFinished(真);
mScroller.fling(0,0,速度/摩擦系数,0,0,最大滚动X,0,0);
}else if(mScroller.getFinalX()==getScrollX()| | mScroller.getCurrVelocity()==0){
snapToItem();
mScroller.forceFinished(真);
}否则{
scrollTo(mScroller.getCurrX(),0);
}
}
使无效();
}
@凌驾
公共布尔onScroll(MotionEvent e1、MotionEvent e2、浮点距离X、浮点距离Y){
//当滚动通过滚动条的开始或结束时,此逻辑处理该情况
如果(getScrollX()>最大滚动次数){
滚动到(0,0);
}else if(getScrollX()>=0){
滚动(距离,0);
}否则{
滚动至(最大滚动次数,0);
}
使无效();
返回true;
}
@凌驾
公共布尔onFling(MotionEvent e1、MotionEvent e2、float-velocityX、float-velocityY){
//这是为了防止低速“抛掷”
if(数学绝对值(速度x)<400*屏幕密度){
返回false;
}
mScroller.forceFinished(真);
//将摩擦系数定义为可提供理想抛撒的值。
mScroller.fling(getScrollX(),getScrollY(),(int)-velocityX/摩擦系数,0,0,最大滚动系数,0,0);
使无效();
返回true;
}
@凌驾
公共布尔onTouchEvent(运动事件){
开关(event.getAction()){
case MotionEvent.ACTION\u DOWN:
mScroller.forceFinished(真);
打破
case MotionEvent.ACTION\u UP:
snapToItem();
使无效();
打破
}
返回mGestureDetector.onTouchEvent(事件);
}
私有void snapToItem(){
//用户从卷轴上抬起手指或在投掷完成时确定要捕捉到的项目。请参阅ViewPager源代码以模拟“假拖动”
int scrollByValue=getScrollX()/SOME\u值
scrollTo(scrollByValue,0);
}
}
public class FlingableScroller extends View implements GestureDetector.OnGestureListener {
public FlingableScroller(Context context, AttributeSet attrs) {
super(context, attrs);
mGestureDetector = new GestureDetector(context, this);
mScroller = new OverScroller(context);
//This is how you "set current item" You will have to calculate INITIAL_SCROLL_X yourself
setScrollX(INITIAL_SCROLL_X);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
animateFlingIfApplicable();
}
private void animateFlingIfApplicable() {
//We have a fling only if computeScrollOffset is true.
if (mScroller.computeScrollOffset()) {
//Flinging passed the start point so continue the fling at the end
if (mScroller.getFinalX() == 0) {
int velocity = getFlingVelocity();
mScroller.forceFinished(true);
mScroller.fling(MAXIMUM_SCROLL_X, 0, velocity / FRICTION_COEFFICIENT, 0, 0, MAXIMUM_SCROLL_X, 0, 0);
//Flinging passed the end point so continue the fling at the start
} else if (mScroller.getFinalX() == MAXIMUM_SCROLL_X) {
int velocity = getFlingVelocity();
mScroller.forceFinished(true);
mScroller.fling(0, 0, velocity / FRICTION_COEFFICIENT, 0, 0, MAXIMUM_SCROLL_X, 0, 0);
} else if (mScroller.getFinalX() == getScrollX() || mScroller.getCurrVelocity() == 0) {
snapToItem();
mScroller.forceFinished(true);
} else {
scrollTo(mScroller.getCurrX(), 0);
}
}
invalidate();
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
//This logic handles the case when you scroll pass the beginning or the end of the scroller
if (getScrollX() > MAXIMUM_SCROLL_X) {
scrollTo(0, 0);
} else if (getScrollX() >= 0) {
scrollBy(distance, 0);
} else {
scrollTo(MAXIMUM_SCROLL_X, 0);
}
invalidate();
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
//This is to prevent low velocity "flings"
if (Math.abs(velocityX) < 400 * SCREEN_DENSITY) {
return false;
}
mScroller.forceFinished(true);
//Define friction_coefficient to a value that gives you desirable flinging.
mScroller.fling(getScrollX(), getScrollY(), (int) -velocityX / FRICTION_COEFFICIENT, 0, 0, MAXIMUM_SCROLL_X, 0, 0);
invalidate();
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mScroller.forceFinished(true);
break;
case MotionEvent.ACTION_UP:
snapToItem();
invalidate();
break;
}
return mGestureDetector.onTouchEvent(event);
}
private void snapToItem() {
//The the user lifts up their finger from a scroll or when a fling finishes determine what item to snap to. See the ViewPager source code to emulate the "fake drag"
int scrollByValue = getScrollX() / SOME_VALUE
scrollTo(scrollByValue, 0);
}
}