ViewPager setCurrentItem Slide

时间:2015-05-03 15:38:51

标签: android android-fragments

我有一个Activity包含ViewPager,此ViewPager中的第一个Fragment包含ListView,当我点击任何Item时,它会用选定的一个替换这个Fragment, 我用setCurrentItem(selectedItem,true)//for smooth scroll 但在选定的片段之前,ViewPager会滑过所有片段 我希望它只滑动到选定的片段而不是所有片段 我尝试使用PageTransfrom.transformPage之类的

@Override
public void transformPage(View page, float position) {
    int currentItem = viewPager.getCurrentItem();
    if (currentItem != selectedItem)
        page.setVisibility(View.GONE);
}

但没有运气

6 个答案:

答案 0 :(得分:4)

一种可能的解决方案是修改PagerAdapter以始终在第2项上返回您想要的页面。

当点击第一页中的任何项目时,首先更改PagerAdapter的方法getItem(int position)的实现(如果您的PagerAdapter在代码的同一个类文件中实现,这很容易),返回position == 2后您想要的页面,然后拨打setCurrentItem(2, true)。这可以直接滚动到所选页面。您可能还需要更改getCount()以将计数限制为仅2,否则下一页可能不是预期的。

但这种方法驳回了其他页面。用户只能滚动回第一页,然后导航到另一页。如果您希望通过手动滚动(而非单击)保持页面的自然顺序,则一旦scoll(通过单击)停止,您可以将getItem(int position)恢复为默认实现,并将停止的当前页面重新加载到自然顺序通过调用setCurrentItem(position, false)(此时立即,不顺利),用户可以手动来回滚动。

答案 1 :(得分:0)

因此,如果我理解正确,您希望平滑滚动到所选片段,但只能从前一个片段滚动。正确?

当您将true传递给setCurrentItem时,它会从当前所选位置平滑滚动。这不能改变。因此,您的问题的解决方案是进行两步设置。

首先使用setCurrentItem(selectedItem-1,false)将其设置为上一个项目。完成转换后,调用setCurrentItem(selectedItem,true)。

我自己没有这样做,但我预见到一些并发症和特殊情况。

如果你把一个调用放在另一个调用setCurrentItem之后它可能不起作用。您可能需要侦听第一页更改(使用OnPageChangeListener)以对setCurrentItem进行第二次调用。

当选定的项目是第一个项目时,也会出现界限。

希望这有帮助。

答案 2 :(得分:0)

ViewPager不适合您要实现的目标。如果您使用ViewPager,请将Fragments添加为页面,并从第0页滚动到3,它肯定会从 Page 0 - >滚动第1页 - >第2页 - >第3页。一般来说,它会一步一步,其中一步对应于移动到下一页。

您要找的是Descendant Navigation

在您的情况下,您可以按原样保留所有片段实现。只需在活动中托管包含Fragment的{​​{1}},当用户选择其中的项目时,请添加带有slide in transition的相应ListView

祝你好运。

答案 3 :(得分:0)

一般情况下,正如许多人已经说过的那样,你不应该使用ViewPager,它绝对是出于其他目的。

我认为最简单的方法是使用简单的片段切换,例如:

yourListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
                switch (position) {
                    case 0:
                        getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right)
                                .replace(R.id.content, MyFirstFragment.newInsance()).commit();
                        break;
                    case 1:
                        getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right)
                                .replace(R.id.content, MySecondFragment.newInsance()).commit();
                        /etc.
                }
            }
        });

因此,您可以完全控制它+为每个片段外观设置适当动画的可能性。

希望你有我的想法。

答案 4 :(得分:0)

我这样解决了这个问题 我有一个ViewPager(vp1)包含两个片段,第一个包含项目的ListView,第二个片段包含另一个ViewPager(vp2) 我滑动到选定的项目而不滑动所有之前的项目 当用户点击Listview上的项目时

listView.setOnItemClickListener(new OnItemClickListener() {
        @Override
    public void onItemClick(AdapterView<?> parent, View view,
            int position, long id) {
SharedPreferences sharedPreferences = getApplicationContext()
                        .getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE);

    sharedPreferences.edit().putInt("color", position).commit();
        if (position == 0) {

            //colorpicker();
        } else {
            Intent intent = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(
                    Intent.createChooser(intent, "Select Picture"), 1);
        }
    }
});

首先在没有幻灯片的情况下在第二个viewpager上设置当前项目,然后滑动第一个viewpager,那就是

答案 5 :(得分:0)

如果您希望幻灯片从一个动画制作到另一个,您必须不仅可以看到所选项目,还可以看到之前选择的项目。致电setCurrentItem(selectedItem,true)后,viewPager.getCurrentItem()内所有对transformPage的调用都会返回您之前设置的相同值,而不是通过平滑滚动进行更改。我想你可以用transformPage:

这样做
int prevSelFrag = 0, currentSelFrag = 0; //member variables

@Override
protected void onCreate(Bundle savedInstanceState) {
    pager.setOnPageChangeListener(new OnPageChangeListener() {
        @Override
        public void onPageSelected(int pos) {
            prevSelFrag = currentSelFrag;
            currentSelFrag = pos;
        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
        }

        @Override
        public void onPageScrollStateChanged(int arg0) {
        }
    });
    pager.setPageTransformer(false, new PageTransformer() {
        @Override
        public void transformPage(View page, float relativePosition) {
            float transDiff = prevSelFrag - currentSelFrag;
            if (transDiff > 1.0f || transDiff < -1.0f) {
                boolean transIsToRight = transDiff < 0.0f;
                if (transIsToRight && relativePosition < -1) {
                    page.setVisibility(View.GONE);
                } else if (relativePosition > 1) { //trans is to left
                    page.setVisibility(View.GONE);
                }else{
                    page.setVisibility(View.VISIBLE);
                }
            }else{
                page.setVisibility(View.VISIBLE);
            }
        }
    });
}

relativePosition是相对于setCurrentItem上设置的页面的页面位置,因此给定的View page必须转到动画中的该位置(但不是真正的寻呼机状态)。例如,如果您在第0页上并在transformPage中调用setCurrentItem(2,true),则可能会收到:

  • 第1页的当前视图,其中relativePosition = -2
  • 第0页的当前视图,其中relativePosition = -1
  • 第2页的当前视图,relativePosition = 0

当然,这些值在它们之间有所不同,以进行过渡效果。 ViewPager smoothScroll对我不起作用,不得不使用此解决方案来解决这个问题 - &gt; https://stackoverflow.com/a/14776244/4282954