jjzjj

Android - 类似旋转木马的小部件,显示左右元素的一部分

coder 2023-11-18 原文

所以我到处搜索,但找不到问题的答案。我基本上需要的是 Android 的 ViewFlipper 或 ViewPager 提供的行为,但我想显示左右 View 的部分,以指示用户有要滚动的元素,而不是让所选 View 占据整个屏幕。

我还想为左 View 和侧 View 添加一些效果,例如调暗和缩放然后缩小一点。是否可以使用现有的 ViewFlipper 或 ViewPager 来完成,还是我必须推出自己的 View 组,就像封面流程 (http://www.inter-fuser.com/2010/01/android-coverflow-widget.html)?

(附言,我不想使用 Gallery 小部件,那个组件很糟糕)。

这是我们需要在选择 View 后显示的内容(仍然显示左右 View ):

向左或向右滑动会将主视图移出,使其变暗并稍微缩小,并对下一个或上一个 View 执行相反的操作。

最佳答案

我想向可能需要相同功能的任何人提供更新。到目前为止,在实现此功能方面已经取得了很大进展,现在该 View 完全按照我们的需要工作。

ViewPager 有一个名为 setPageMargin() 的方法。此方法可以接收负值,这将使 fragment/ View 相互重叠。为了获得所需的布局,我们首先按屏幕的百分比动态计算左右边距。这也可以静态完成,但由于我们将针​​对一系列不同的屏幕尺寸,这似乎是最好的方法。

稍后我们将 ViewPager 的页边距设置为侧边距大小的 2 倍。这使得 View 重新组合在一起。但是,此时,ViewPager 将显示多个 View 。

您剩下要做的就是对左右 View (Android 3.0+) 应用变换(缩放),或者在它们周围添加更多边距以将它们缩小到合适的大小(3.0 之前)。

OnPageChangeListener.onPageScrolled() 可用于跟踪 ViewPager 的滚动。顺利 可以实现转型。代码如下所示:

private OnPageChangeListener onPageChangeListener = new OnPageChangeListener() {

    @Override
    public void onPageSelected(int position) {
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        // positionOffset varies from 0 to 1 and indicates how far the view is
        // from the center of the ViewPager. When a view is selected (centered), this
        // value is 0.

        // Fades the text in an out while the ViewPager scrolls from one view to another.
        // On our final design the text views are fixed to the center of the screen and
        // do not scroll along with the views.
        if (positionOffset < 0.5) {
            setTextViewAlpha(1 - positionOffset * 2);
        } else {
            setTextViewAlpha((positionOffset - 0.5f) * 2);
        }

        // It's surprisingly complicated to get the current object being displayed by
        // a ViewPager (there's no getCurrentObject method). ScaleableFragment is just
        // a custom class to allow an adapter to cache it internally and also correctly
        // manage a fragment's lifecycle and restore from a saved state.
        ScaleableFragment sampleFragment = (ScaleableFragment) ((ShowHeroShotImageFragmentPagerAdapter) pager
                .getAdapter()).getItem(position);

        // Calculates by how much the current view will be scaled down. The RATIO_SCALE
        // is 0.3 in our case, which makes the side views 70% of the size of the
        // center view. When centered, the scale will be 1. When
        // fully scrolled, the scale will be 0.7.
        float scale = 1 - (positionOffset * RATIO_SCALE);

        // Just a shortcut to findViewById(R.id.image).setScale(scale);
        sampleFragment.scaleImage(scale);


        // Now, if not in the last element, scale the next one up (in opposite direction).
        if (position + 1 < pager.getAdapter().getCount()) {
            sampleFragment = (ScaleableFragment) ((ShowHeroShotImageFragmentPagerAdapter) pager.getAdapter())
                    .getItem(position + 1);
            scale = positionOffset * RATIO_SCALE + (1 - RATIO_SCALE);
            sampleFragment.scaleImage(scale);
        }
    }

    // Once scrolling is done. Make sure the views are in the right scale (1 for center,
    // 0.7 for sides). Required as the onPageScrolled() method does not guarantee it
    // will interpolate to 1.0 precisely.
    @Override
    public void onPageScrollStateChanged(int state) {
        if (state == ViewPager.SCROLL_STATE_IDLE) {
            setTextViewAlpha(1);
            ScaleableFragment sampleFragment = (ScaleableFragment) ((ShowHeroShotImageFragmentPagerAdapter) pager
                    .getAdapter()).getItem(pager.getCurrentItem());
            sampleFragment.scaleImage(1);
            sampleFragment.enableClicks();

            if (pager.getCurrentItem() > 0) {
                sampleFragment = (ScaleableFragment) ((ShowHeroShotImageFragmentPagerAdapter) pager.getAdapter())
                        .getItem(pager.getCurrentItem() - 1);
                sampleFragment.scaleImage(1 - RATIO_SCALE);
                sampleFragment.disableClicks();
            }

            if (pager.getCurrentItem() + 1 < pager.getAdapter().getCount()) {
                sampleFragment = (ScaleableFragment) ((ShowHeroShotImageFragmentPagerAdapter) pager.getAdapter())
                        .getItem(pager.getCurrentItem() + 1);
                sampleFragment.scaleImage(1 - RATIO_SCALE);
                sampleFragment.disableClicks();
            }
        }
    }
};

就是这样。我没有发布完整的解决方案,但我希望这足以让其他人开始。

附言在 3.0+ 上启用硬件加速。没有它,滚动在三星 galaxy tab 10.1 上看起来很不稳定。

关于Android - 类似旋转木马的小部件,显示左右元素的一部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10001503/

有关Android - 类似旋转木马的小部件,显示左右元素的一部分的更多相关文章

  1. ruby - 在哈希的键数组中追加元素 - 2

    查看我的Ruby代码:h=Hash.new([])h[0]=:word1h[1]=h[1]输出是:Hash={0=>:word1,1=>[:word2,:word3],2=>[:word2,:word3]}我希望有Hash={0=>:word1,1=>[:word2],2=>[:word3]}为什么要附加第二个哈希元素(数组)?如何将新数组元素附加到第三个哈希元素? 最佳答案 如果您提供单个值作为Hash.new的参数(例如Hash.new([]),完全相同的对象将用作每个缺失键的默认值。这就是您所拥有的,那是你不想要的。您可以改用

  2. 旋转矩阵的几何意义 - 2

    点向量坐标矩阵的几何意义介绍旋转矩阵的几何含义之前,先介绍一下点向量坐标矩阵的几何含义点:在一维空间下就是一个标量,如同一条直线上,以任意某一个位置为0点,以一定的尺度间隔为1,2,3...,相反方向为-1,-2,-3...;如此就形成了一维坐标系,这时候任何一个点都可以用一个数值表示,如点p1=5,即即从原点出发沿着x轴正方向移动5个尺度;点p2=-3,负方向移动3个尺度;     在一维坐标系上过原点做垂直于一维坐标系的直线,则形成了二维坐标系,此时描述一个点需要两个数值来表示点p3=(3,2),即从原点出发沿着x轴正方向移动3个尺度,在此基础上沿着y轴正方向移动两个尺度的位置就是点p3。

  3. Unity 3D 制作开关门动画,旋转门制作,推拉门制作,门把手动画制作 - 2

    Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u

  4. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  5. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  6. ruby - Hanami link_to 助手只呈现最后一个元素 - 2

    我是HanamiWorld的新人。我已经写了这段代码:moduleWeb::Views::HomeclassIndexincludeWeb::ViewincludeHanami::Helpers::HtmlHelperdeftitlehtml.headerdoh1'Testsearchengine',id:'title'hrdiv(id:'test')dolink_to('Home',"/",class:'mnu_orizontal')link_to('About',"/",class:'mnu_orizontal')endendendendend我在模板上调用了title方法。htm

  7. ruby - Ruby 是否有类似于 Perl 的 "perl -d"的逐步调试器? - 2

    Ruby是否有逐步调试器,类似于Perl的“perl-d”? 最佳答案 ruby-debug(对于ruby1.8),debugger(对于ruby1.9),byebug(对于ruby​​2.0)以及trepanning系列都有一个-x或--trace选项。在调试器内部,命令setlinetrace将打开或关闭线路跟踪。这是themanualforruby-debug原来的答案已经修改,因为数据噪声文章的链接,唉,不再有效了。还添加了ruby​​-debug的后继者 关于ruby-Ruby

  8. ruby - 使对象的行为类似于 ruby​​ 中并行分配的数组 - 2

    假设您在Ruby中执行此操作:ar=[1,2]x,y=ar然后,x==1和y==2。是否有一种方法可以在我自己的类中定义,从而产生相同的效果?例如rb=AllYourCode.newx,y=rb到目前为止,对于这样的赋值,我所能做的就是使x==rb和y=nil。Python有这样一个特性:>>>classFoo:...def__iter__(self):...returniter([1,2])...>>>x,y=Foo()>>>x1>>>y2 最佳答案 是的。定义#to_ary。这将使您的对象被视为要分配的数组。irb>o=Obje

  9. ruby - 将n维数组的每个元素乘以Ruby中的数字 - 2

    在Ruby中,是否有一种简单的方法可以将n维数组中的每个元素乘以一个数字?这样:[1,2,3,4,5].multiplied_by2==[2,4,6,8,10]和[[1,2,3],[1,2,3]].multiplied_by2==[[2,4,6],[2,4,6]]?(很明显,我编写了multiplied_by函数以区别于*,它似乎连接了数组的多个副本,不幸的是这不是我需要的)。谢谢! 最佳答案 它的长格式等价物是:[1,2,3,4,5].collect{|n|n*2}其实并没有那么复杂。你总是可以使你的multiply_by方法:c

  10. 语法类似于 GitHub Flavored Markdown 的 Ruby markdown 解释器? - 2

    我使用Jekyll运行博客,并认为我会解决RedcarpetMarkdown解释器,因为它是developedandusedbyGitHub.好吧,我只是碰巧遇到了一个错误,去检查问题,然后foundthis.Maintainersays,"Asyouprobablyhavenoticed(harharharhar)Idon'thavetimetomaintainRedcarpetanymore.It'snotapriorityforme(IfindMarkdownthoroughlyboring)andit'snotapriorityforGitHub,becausewenolong

随机推荐