在机器人上滚动的可视指示(visual indication of over scroll in a

2019-07-29 14:24发布

我想添加一些视觉指示,有在ViewPager所期望的方向一扔没有更多的网页。 不过我在努力寻找一个地方,在那里把相关代码。

我曾尝试与下面的代码扩展ViewPager类,但是面包不显示( ev.getOrientation()返回始终为0)。 我也曾尝试用历史点相同,但ev.getHistorySize()也返回0。

我在想什么?

类例如:

public class CustomViewPager extends ViewPager {

    public CustomViewPager(Context context) {
        super(context);
    }

    public CustomViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * @see android.support.v4.view.ViewPager#onTouchEvent(android.view.MotionEvent)
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        boolean result = super.onTouchEvent(ev);

        switch (ev.getAction() & MotionEventCompat.ACTION_MASK) {
            case MotionEvent.ACTION_MOVE:
                if (ev.getOrientation() > 0) {
                    Toast.makeText(getContext(), "left", 0).show();
                }
        }

        return result;
    }
}

Answer 1:

如果你看一下V4支持库,你会看到有由ViewPager使用的类名为EdgeEffectCompat (当你到达在ICS +视图寻呼机的开头或结尾,这提供了光晕效果),如果你看一下在compat的图书馆实现你会看到它有一个if语句,看看内部版本是14+(ICS)或没有。 如果是的话,就使用正常结束了最后(如果你追踪足够长的时间) EdgeEffect这是在ICS inroduced类。 否则,它使用了基本无关,在它BaseEdgeEffectImpl。

如果你愿意,你可以让自己的自定义ViewPager使用自己的EdgeEffect。 你可以看一下Android的源代码,看看他们是如何实现的EdgeEffect 在这里 ,你几乎可以复制(只是确保将复制overscroll_edge和overscroll_glow可绘制在AOSP / RES /绘制资源目录到自己的项目,因为它们是内部到Android )或继续前进,创建自己的版本。

祝好运。

(顺便说一句,这就是他们创造在ICS的启动菜单中的很酷的边缘倾斜效果......所以你几乎可以是创意,只要你想用这个;)



Answer 2:

我试图让被问这个问题的确切同样的效果。 我与它的斗争,然后我读@wnafee答案(我不能出它这样做)。

但后来我努力实现什么声音相当的答案很简单。 我有这么多的麻烦,实现它,我可能没有正确理解答案,但有太多不可访问的API的许多问题,因为我不是在同一个封装兼容性库的工作。

我尝试了一些方法(没有一个成功的,他们是相当复杂的)后,我去了一个稍微不同的方向,而现在它的工作原理就像一个魅力。 我使用了一些反思,对谁从来没有使用过它,不要担心,这是真正反映基本的人。

我不知道这是否是最好的解决方案在那里,但它为我工作,所以如果你想使用它,你是受欢迎的。 请阅读Wnafee的例子,因为它说明了一些我做的东西。

为了完成这个任务,你应该只是按照我的三个部分的解决方案。 (会带你3-10分钟之间)

第一部分:

正如Wnafee说,我只是做了一份由我自己EdgeEffect类从粘贴的源代码在这里 ,

(只需确保到overscroll_edge和overscroll_glow可绘绘制资源目录复制在AOSP / RES /到自己的项目,因为它们是内部到Android)

我只做了2个非常小的变化:

  1. 我声明,类扩展EdgeEffectCompat(我叫我的课EdgeEffectForEarlyVersions )。 public class EdgeEffectForEarlyVersions extends EdgeEffectCompat 。 之所以这样做了这种变化的mLeftEdgemRightEdge是类型EdgeEffectCompat
  2. 在“我”的新类的构造函数的第一行我添加到父构造函数的调用super(context); 。 由于没有默认的构造EdgeEffectCompat你必须明确地调用构造函数。

第二部分

除此之外我写的其他功能。 该功能的目的是,在一个早期版本的情况下(ICS)之前,我们想用EdgeEffectForEarlyVersions ,我们只是复制。 为了得到这个目的我用反射。

这是函数:

private static void changeEdgeEffectCompactOnEarlyVersions(ViewPager viewPager, Context context)
{
    /* In case that the version is earlier than 14 there is only empty implementation for the edge effect, therefore we change it.
     * for more information look on the following links:
     * 1. http://stackoverflow.com/questions/10773565/visual-indication-of-over-scroll-in-android
     * 2. http://grepcode.com/file/repo1.maven.org/maven2/com.google.android/support-v4/r7/android/support/v4/view/ViewPager.java#ViewPager.0mLeftEdge
     * 3. http://grepcode.com/file/repo1.maven.org/maven2/com.google.android/support-v4/r7/android/support/v4/widget/EdgeEffectCompat.java#EdgeEffectCompat
     */

    if (Build.VERSION.SDK_INT < 14)
    {
        try
        {
            Class<ViewPager> viewPagerClass = ViewPager.class;
            //Get the left edge field, since it is private we used getDeclaredField and not getDeclared 
            Field leftEdge = viewPagerClass.getDeclaredField("mLeftEdge");
            leftEdge.setAccessible(true);
            //Get the right edge field, since it is private we used getDeclaredField and not getDeclared
            Field rightEdge = viewPagerClass.getDeclaredField("mRightEdge");
            rightEdge.setAccessible(true);

            EdgeEffectForEarlyVersions leftEdgeEffect = new EdgeEffectForEarlyVersions(context);
            EdgeEffectForEarlyVersions rightEdgeEffect = new EdgeEffectForEarlyVersions(context);

            //Set the mLeftEdge memeber of viewPager not to be the default one, but to be "our" edgeEffect  
            leftEdge.set(viewPager, leftEdgeEffect);
            //Set the mRightEdge memeber of viewPager not to be the default one, but to be "our" edgeEffect
            rightEdge.set(viewPager, rightEdgeEffect);              
        }
        catch (Exception ex)
        {
            Log.e("refelection", ex.getMessage());
        }

    }
}

第三部分

现在,所有有剩下要做的,就是调用该函数你有ViewPager实例,仅此而已了。

我希望这会帮助别人。



Answer 3:

wnafee解释了解决方案很好,但我们之间的懒惰,我前一段时间做了实际工作的落实。

https://github.com/inovex/ViewPager3D

如果你只是想反弹时这里看看:

https://github.com/inovex/ViewPager3D/issues/1



Answer 4:

你有很多选择,可以显示敬酒,显示一个对话框,让一个TextView或图片出现在你的UI,等等。或者因为你知道在ViewPager查看项目的金额,你可以在位置添加不同的视图0和/或n + 1的消息,使反弹到实际包含数据的最后一个视图。

您可以实现:

viewPager.setOnPageChangeListener(new OnPageChangeListener() {
    public void onPageSelected(int position) {
        //TODO If position is the 0 or n item, add a view at 0 or at n+1 to indicate there is no more pages with data.
    }

    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        // TODO Show a Toast, View or do anything you want when position = your first/last  item;
    }

    public void onPageScrollStateChanged(int state) {
    }
});


Answer 5:

只是补充,当你创建你自己的edgeffect类@goBeepit DEV回答,你从延长一些EdgeEffectCompat方法都需要为布尔。 你可以改变这些方法来布尔类型,然后使在任何情况下返回true,这一切的方式工作正常



Answer 6:

您可以在片段超载setUserVisibleHint(布尔)函数。 伪代码:

    void setUserVisibleHint(boolean isVisibleToUser) {
        // If this fragment is becoming visible
        if (isVisibleToUser == true) {
             // Check if it is the last fragment in the viewpager
             if (indexOfThis == getActivity().indexOfLast) {
                // Display right limit reached
                Toast(..., "No more Frags to right",...)
                }
             // Check if it is the first fragment in the viewpager
             else if (indexOfThis == getActivity().indexOfFirst) {
                // Display Left Limit reached
                Toast(..., "No more Frags to left",...)
             }
        }
    }

我没有用过这个功能用于此目的,但是已经使用了其他的原因,它并触发适当。 希望这可以帮助...



Answer 7:

我已经实现了基于雷纳的ViewPager3D一个反弹效应: https://stackoverflow.com/a/17425468/973379



Answer 8:

通常与ViewPager,一个使用PagerAdapterFragmentPagerAdapterFragmentStatePagerAdapter与内容充斥ViewPager( 你的内容将是视图 )。

现在,当您使用PagerAdapter ,你叫一个方法getCount() http://developer.android.com/reference/android/support/v4/view/PagerAdapter.html#getCount%28%29 ,这将给你的内容的大小。

既然你现在知道的大小,你可以很容易地用if控制语句显示一条消息。

试试这个代码: http://developer.android.com/reference/android/support/v4/view/ViewPager.html

注:我不认为你需要一个定制ViewPager。 您还需要了解片段的ViewPager。 看看ApiDemos样本。 它的一个重要来源。



文章来源: visual indication of over scroll in android