我有一个使用ViewPager和FragmentStatePagerAdapter的Android应用。然而,我需要添加一个新功能,我必须知道滑动方向从一个片段视图移动到另一个,左或右。 (即,当我向左滑动时,我会做一件事,当我向右滑动时,我会做其他事情。)
请注意,我不需要在滑动结束后发生事件。滑动发生时我必须做这些事件。我想过使用setOnPageChangeListener()
,但它并没有告诉我滑动方向。你能告诉我如何找出滑动方向吗?
感谢。
答案 0 :(得分:6)
查看ViewPager.OnPageChangeListener的onPageSelected(int position)
方法。 position
给出了新选择页面的索引。如果您跟踪当前页面索引,则可以将其与position
索引进行比较,以获得滑动的左/右方向。
既然您提到OnPageChangeListener没有帮助,请考虑onInterceptTouchEvent (MotionEvent ev)
的{{1}}方法。考虑到MotionEvent的ACTION_DOWN,ACTION_MOVE和ACTION_UP。希望这会有所帮助。
答案 1 :(得分:5)
我遇到了这个问题,需要知道正在发生的滑动的方向,以防止在某个方向滑动。这是我如何解决我的问题,希望它对某人有帮助。我发现前面的所有例子都不符合我的要求。
如果您继承了ViewPager,则可以回复onInterceptTouchEvent(MotionEvent event)
onTouchEvent(MotionEvent event)
和ViewPager
方法
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
boolean wasSwipeToRight = this.wasSwipeToRightEvent(event));
// Do what you want here with left/right swipe
return super.onInterceptTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean wasSwipeToRight = this.wasSwipeToRightEvent(event));
// Do what you want here with left/right swipe
return super.onTouchEvent(event);
}
这是调用事件方向的方法。
// Stores the starting X position of the ACTION_DOWN event
float downX;
/**
* Checks the X position value of the event and compares it to
* previous MotionEvents. Returns a true/false value based on if the
* event was an swipe to the right or a swipe to the left.
*
* @param event - Motion Event triggered by the ViewPager
* @return - True if the swipe was from left to right. False otherwise
*/
private boolean wasSwipeToRightEvent(MotionEvent event){
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = event.getX();
return false;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
return downX - event.getX() > 0;
default:
return false;
}
}
答案 2 :(得分:3)
这很简单,引入了一个实例变量来跟踪当前页面。
public class MyActivity extends Activity implements ViewPager.OnPageChangeListener {
private ViewPager viewPager;
private int currentPosition;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Do trivial stuff
.
.
.
viewPager.setOnClickListener(this); // doesnt have to be in onCreate
}
@Override
public void onPageSelected(int position) {
if(currentPosition < position) {
// handle swipe LEFT
} else if(currentPosition > position){
// handle swipe RIGHT
}
currentPosition = position; // Update current position
}
}
答案 3 :(得分:2)
也许你可以建立一个这样的监听器:
buttonIcons.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(final View v, final MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = event.getX();
return true;
case MotionEvent.ACTION_UP:
upX = event.getX();
final float deltaX = downX - upX;
if (deltaX > 0 && deltaX > SWIPE_MIN_DISTANCE) {
final Animation loadInAnimation = AnimationUtils
.loadAnimation(
activity.this,
R.anim.slide_in_right);
final Animation loadOutAnimation = AnimationUtils
.loadAnimation(
activity.this,
R.anim.slide_out_left);
viewFlipper.setInAnimation(loadInAnimation);
viewFlipper.setOutAnimation(loadOutAnimation);
viewFlipper.showPrevious();
startSaveButtonAnimation();
}
if (deltaX < 0 && -deltaX > SWIPE_MIN_DISTANCE) {
final Animation loadInAnimation = AnimationUtils
.loadAnimation(
activity.this,
R.anim.slide_in_left);
final Animation loadOutAnimation = AnimationUtils
.loadAnimation(
activity.this,
R.anim.slide_out_right);
viewFlipper.setInAnimation(loadInAnimation);
viewFlipper.setOutAnimation(loadOutAnimation);
viewFlipper.showNext();
startSaveButtonAnimation();
}
return true;
}
return false;
}
});
答案 4 :(得分:2)
通过使用Kotlin和ViewPager2,这是我的解决方案,您可以将OnPageChangeCallback侦听器注册为下面的代码片段(仅向右滑动)
<Formik
initialValues={{
patients: [
{
id: "1",
firstName: "",
lastName: "",
items: "",
},
],
phoneNumber: "",
peopleOrdering: 1,
monthOrder: "1",
collectionOrDelivery: "",
waitingOrLater: "",
address: "",
staffMember: "",
claimReceipt: "",
whereIsPrescription: "",
keepSubscription: "",
}}
validationSchema={OrderSchema}
onSubmit={() => {}}
>
{({ values }) => (
<Form>
<FormItem name="patients">
{values.patients.map((patient, i) => (
<div key={patient}>
<Input name={`patients[${i}].firstName`}></Input>
<Input name={`patients[${i}].lastName`}></Input>
<Input name={`patients[${i}].items`}></Input>
</div>
))}
</FormItem>
// ... REST OF THE FORM
</Form>
)}
</Formik
答案 5 :(得分:1)
您实际上可以使用onPageScrolled
的参数找到方向
以下监听器设置为每个净片段更改方向显示一次日志消息(如果左片段显示则离开,如果没有片段显示则为中心,如果右片段显示则为右)。
类变量,需要跟踪
// -1 - left, 0 - center, 1 - right
private int scroll = 0;
// set only on `onPageSelected` use it in `onPageScrolled`
// if currentPage < page - we swipe from left to right
// if currentPage == page - we swipe from right to left or centered
private int currentPage = 0;
// if currentPage < page offset goes from `screen width` to `0`
// as you reveal right fragment.
// if currentPage == page , offset goes from `0` to `screen width`
// as you reveal right fragment
// You can use it to see
//if user continue to reveal next fragment or moves it back
private int currentOffset = 0;
// behaves similar to offset in range `[0..1)`
private float currentScale = 0;
听众
pager.addOnPageChangeListener(
new OnPageChangeListener(){
@Override
public void onPageScrolled(int page, float scale, int offset){
if(scale != 0f && offset > 10){
if(currentOffset > offset && currentScale > scale && (page + 1) == currentPage){
if(scroll != -1){
newImageSet = true;
scroll = -1;
Log.e("scroll", "left");
}
} else if(currentOffset < offset && currentScale < scale && page == currentPage){
if(scroll != 1){
newImageSet = true;
scroll = 1;
Log.e("scroll", "right");
}
}
currentOffset = offset;
currentScale = scale;
}
@Override
public void onPageSelected(int i){
Log.e("scroll","centre");
// we are centerd, reset class variables
currentPage = i;
currentScale = 0;
currentOffset = 0;
scroll = 0;
}
@Override
public void onPageScrollStateChanged(int i){
}
}
);
答案 6 :(得分:1)
您可以将OnPageChangeListner添加到ViewPager并执行以下操作:
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
float tempPositionOffset = 0;
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (position == 0) {
if (tempPositionOffset < positionOffset) {
Log.d("eric", "scrolling left ...");
} else {
Log.d("eric", "scrolling right ...");
}
tempPositionOffset = positionOffset;
Log.d("eric", "position " + position + "; " + " positionOffset " + positionOffset + "; " + " positionOffsetPixels " + positionOffsetPixels + ";");
}
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
答案 7 :(得分:0)
我使用这个小实现来检测用户在滚动期间是向右滚动还是向左滚动。在某些我不知道的情况下,我可能会遇到一些错误但是我可以根据需要提出一些错误,而不必添加触摸监听器:
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
int SCROLLING_RIGHT = 0;
int SCROLLING_LEFT = 1;
int SCROLLING_UNDETERMINED = 2;
int currentScrollDirection = 2;
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (isScrollDirectionUndetermined()){
setScrollingDirection(positionOffset);
}
if (isScrollingLeft()){
Log.i("TabLayout","Scrolling LEFT");
}
if (isScrollingRight()){
Log.i("TabLayout","Scrolling RIGHT");
}
}
private void setScrollingDirection(float positionOffset){
if ((1-positionOffset)>= 0.5){
this.currentScrollDirection = SCROLLING_RIGHT;
}
else if ((1-positionOffset)<= 0.5){
this.currentScrollDirection = SCROLLING_LEFT;
}
}
private boolean isScrollDirectionUndetermined(){
return currentScrollDirection == SCROLLING_UNDETERMINED;
}
private boolean isScrollingRight(){
return currentScrollDirection == SCROLLING_RIGHT;
}
private boolean isScrollingLeft(){
return currentScrollDirection == SCROLLING_LEFT;
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE){
this.currentScrollDirection = SCROLLING_UNDETERMINED;
}
}
});
我们可以检测滚动方向,因为当用户从左向右滚动时,positionOffset
从0开始 - > 1,当从右向左滚动时,它从1 - >开始。我们可以在滚动的最开始检查一次该值,并仅在滚动结束时重置该标志。
我们将currentScrollDirection
设置为空闲位置而不是onPageSelected
,因为如果用户在滚动中间释放然后您将获得错误读取,则可以调用onPageSelected
答案 8 :(得分:-2)
您可以使用setOnPageChangeListener()
并正确实施onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
。
您可以通过positionOffset和位置变量检测方向:
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
{
if(position == mCurrentPosition && positionOffset > 0)
{
//swipe right
}
else if (positionOffset > 0)
{
//swipe left
}
}