android - 有没有办法在android中创建预览 slider

标签 android android-viewpager android-view android-recyclerview

我正在尝试创建类似

的界面

here .

中心元素是带有全尺寸图像的 ViewPager,顶部元素是带有预览图像的 RecyclerView。但是我找不到让磁铁元素居中的方法。有没有办法覆盖 RecyclerView 的行为?

最佳答案

我找到了您所需要的解决方案。我在 github.com 上创建了一个小例子:AndroidPreviewSlider

Preview

问题是顶部 View 是 ViewPager 并且中心 View 也是 ViewPager。 详细代码如下:

顶部预览适配器

public class PhotoPreviewAdapter extends FragmentPagerAdapter {

    private static final int DEFAULT_SIDE_PREVIEW_COUNT = 3;

    private final int sidePreviewCount;

    private final List<PhotoInfo> photoInfos;

    public PhotoPreviewAdapter(FragmentManager fm, List<PhotoInfo> photoInfos) {
        this(fm, DEFAULT_SIDE_PREVIEW_COUNT, photoInfos);
    }

    public PhotoPreviewAdapter(FragmentManager fm, int sidePreviewCount, List<PhotoInfo> photoInfos) {
        super(fm);
        this.sidePreviewCount = sidePreviewCount;
        this.photoInfos = photoInfos;
    }

    public int getSidePreviewCount() {
        return sidePreviewCount;
    }

    @Override
    public Fragment getItem(int position) {
        if (isDummy(position)) {
            return DummyPreviewFragment.newInstance();
        } else {
            return PhotoPreviewFragment.newInstance(photoInfos.get(getRealPosition(position)));
        }
    }

    private boolean isDummy(int position) {
        return position < sidePreviewCount || position > photoInfos.size() - 1 + sidePreviewCount;
    }

    private int getRealPosition(int position) {
        return position - sidePreviewCount;
    }

    @Override
    public int getCount() {
        return photoInfos.size() + (sidePreviewCount * 2);
    }

    @Override
    public float getPageWidth(int position) {
        return 1.0f / getElementsPerPage();
    }

    private int getElementsPerPage() {
        return (sidePreviewCount * 2) + 1;
    }
}

中央 View 适配器很简单

public class PhotoViewAdapter extends FragmentPagerAdapter {

    private final List<PhotoInfo> photoInfos;

    public PhotoViewAdapter(FragmentManager fm, List<PhotoInfo> photoInfos) {
        super(fm);
        this.photoInfos = photoInfos;
    }

    @Override
    public Fragment getItem(int position) {
        return PhotoViewFragment.newInstance(photoInfos.get(position));
    }

    @Override
    public int getCount() {
        return photoInfos.size();
    }
}

其中一个主要的是同步监听器

public class OnSyncPageChangeListener implements ViewPager.OnPageChangeListener {

    private int scrollState = ViewPager.SCROLL_STATE_IDLE;

    private final ViewPager syncToViewPager;
    private final ViewPager syncWithViewPager;

    public OnSyncPageChangeListener(ViewPager syncToViewPager, ViewPager syncWithViewPager) {
        this.syncToViewPager = syncToViewPager;
        this.syncWithViewPager = syncWithViewPager;
    }

    @Override
    public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {
        if (scrollState != ViewPager.SCROLL_STATE_IDLE) {
            final float ratio = calculateRatioForPosition(position);
            final float scrollX = syncWithViewPager.getScrollX();
            final float scrollY = syncWithViewPager.getScrollY();
            syncToViewPager.scrollTo((int) (scrollX * ratio), (int) scrollY);
        }
    }

    private float calculateRatioForPosition(int position) {
        final float syncToViewPagerWidth = syncToViewPager.getWidth();
        final float syncWithViewPagerWidth = syncWithViewPager.getWidth();

        final float syncToViewPagerElementWeight = syncToViewPager.getAdapter().getPageWidth(position);
        final float syncWithViewPagerElementWeight = syncWithViewPager.getAdapter().getPageWidth(position);

        final float syncToViewPagerElementsCount = (1.0f / syncToViewPagerElementWeight);
        final float syncWithViewPagerElementsCount = (1.0f / syncWithViewPagerElementWeight);

        final float syncToViewPagerElementWidth = syncToViewPagerWidth / syncToViewPagerElementsCount;
        final float syncWithViewPagerElementWidth = syncWithViewPagerWidth / syncWithViewPagerElementsCount;

        return syncToViewPagerElementWidth / syncWithViewPagerElementWidth;
    }

    @Override
    public void onPageSelected(final int position) {

    }

    @Override
    public void onPageScrollStateChanged(final int state) {
        scrollState = state;
        if (state == ViewPager.SCROLL_STATE_IDLE) {
            syncToViewPager.setCurrentItem(syncWithViewPager.getCurrentItem(), false);
        }
    }
}

最后初始化ViewPager

@Bind(R.id.photoPreviewPager)
ViewPager photoPreviewPager;

@Bind(R.id.photoViewPager)
ViewPager photoViewPager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.bind(this);

    final List<PhotoInfo> photoInfos = PhotoInfosProvider.generate();

    final PhotoPreviewAdapter photoPreviewAdapter = new PhotoPreviewAdapter(getSupportFragmentManager(), photoInfos);
    final PhotoViewAdapter photoViewAdapter = new PhotoViewAdapter(getSupportFragmentManager(), photoInfos);

    photoPreviewPager.setAdapter(photoPreviewAdapter);
    photoPreviewPager.addOnPageChangeListener(new OnSyncPageChangeListener(photoViewPager, photoPreviewPager));

    photoViewPager.setAdapter(photoViewAdapter);
    photoViewPager.setOffscreenPageLimit(photoPreviewAdapter.getSidePreviewCount() * 2 + 1);
    photoViewPager.addOnPageChangeListener(new OnSyncPageChangeListener(photoPreviewPager, photoViewPager));
}

更详细的代码在repo

关于android - 有没有办法在android中创建预览 slider ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33971817/

相关文章:

Android:使用动态子布局(ViewHolder 和 SubViewHolder)绑定(bind)布局

java - 不支持 Path.isConvex。 Android Studio - 切换按钮

java - Android ViewPager 问题

java - FragmentPagerAdapter - 左侧始终相同的 Fragment

android - 从 viewPager 中的 fragment 隐藏父 fragment

android - 在心形/框架中裁剪/调整图像

android - 按顺序将动画应用到多个 View

android - 用于跟踪对话中哪个人说话最多的应用程序

java - 切换按钮不适用于 SharedPreferences

Android:如何正确隐藏系统用户界面