解决。查看标记为正确的答案以及我的评论。可以在必要时发布示例代码
我正在使用VelocityViewPager来实现“投掷”行为。如果您将页面拖动一定量,页面就不会捕捉,这是一种已知的行为。我试图绕过它但收效甚微......
尝试1
我可以使用setCurrentItem
让快照操作正常工作。需要注意的是,如果我在当前页面之前或之后调用项目上的函数,它只会捕捉,例如setCurrentItem(getCurrentItem()+1)
所以这个解决方案有效,但如果我必须将当前项目设置得比预期的更远,它会给用户带来糟糕的用户体验。
有没有人对如何调用setCurrentItem(getCurrentItem())
并让它实际动画/滚动/捕捉有任何建议? 来源暗示它应该。 r7 code似乎总是调用滚动函数。
尝试2
作为另一个测试,我做了很多fakeDragBy(1)
次调用来拖动ViewPager
,认为它会在达到某个阈值后突然捕捉,但事实并非如此。 是什么阻止了ViewPager的捕捉?
如果您有兴趣,下面是重现此内容的代码。我使用了相同的VelocityViewPager代码并进行了以下更改
VelocityViewPager.java
public class VelocityViewPager extends ViewPager implements GestureDetector.OnGestureListener {
...
@Override
public boolean onTouchEvent(MotionEvent event) {
// give all the events to the gesture detector. I'm returning true here so the viewpager doesn't
// get any events at all, I'm sure you could adjust this to make that not true.
mGestureDetector.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_UP) {
setCurrentItem(getCurrentItem(), true);
Log.d("VelocityViewPager", "Setting to item " + getCurrentItem());
}
return true;
}
....
}
MainActivity.java
package com.example.velocityviewpager;
import android.graphics.Color;
import android.os.Bundle;
import android.app.Activity;
import android.support.v4.view.PagerAdapter;
import android.view.Gravity;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
VelocityViewPager pager = (VelocityViewPager)findViewById(R.id.view);
PagerAdapter adapter = new PagerAdapter() {
@Override
public int getCount() {
return 20;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
TextView view = new TextView(MainActivity.this);
view.setText("Item "+position);
view.setGravity(Gravity.CENTER);
view.setBackgroundColor(Color.argb(255, position * 10, position * 10, position * 10));
view.setTextColor(Color.argb(255, 200, 200, 200));
container.addView(view);
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View)object);
}
@Override
public boolean isViewFromObject(View view, Object o) {
return (view == o);
}
};
pager.setAdapter(adapter);
adapter.notifyDataSetChanged();
pager.setOffscreenPageLimit(3);
pager.setCurrentItem(0, true);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
activity_main.xml中
<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"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<view
android:layout_width="300dip"
android:layout_height="300dip"
class="com.example.velocityviewpager.VelocityViewPager"
android:id="@+id/view"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"/>
</RelativeLayout>
答案 0 :(得分:4)
我找到了一个解决方法。我跟踪之前完成的动作,当MotionEvent.ACTION_UP
发生时,我触发了一个新的动作。我不确定,如果它在逻辑上是正确的(这是一个好的方向吗?这是一个新的推进的好速度?),但我测试了它,它的工作原理:
private boolean isLeftDirection = false;
@Override
public boolean onTouchEvent(MotionEvent event) {
// give all the events to the gesture detector. I'm returning true here
// so the viewpager doesn't
// get any events at all, I'm sure you could adjust this to make that
// not true.
if (event.getAction() == MotionEvent.ACTION_UP) {
int id = getCurrentItem();
setCurrentItem(id, true);
if (isLeftDirection){
mFlingRunnable.startUsingVelocity((int) 1);
} else {
mFlingRunnable.startUsingVelocity((int) -1);
}
}
mGestureDetector.onTouchEvent(event);
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distX,
float distY) {
trackMotion(-distX);
if (distX > 0){
isLeftDirection = true;}
else{
isLeftDirection = false;
}
return false;
}