在用户滚动页面时移动Fragment中的元素

时间:2015-01-23 12:46:50

标签: android android-activity android-fragments android-viewpager android-animation

我有3个片段的ViewPager。 我只是想知道当用户开始滚动页面并转到另一个页面时,是否可以在Fragment中移动元素(ImageView,TextView,e.t.c)?最好的方法是什么?这是我之前使用过的代码。我在MainActivity中使用它。只有经过测试我才明白我的方法是错误的,因为每次用户滚动时这些代码都会起作用。那么可以在Fragment中设置它吗?

我之前在MainActivity中使用的代码:

@Override
public void transformPage(View page, float position) {
        // transformation here
        int pageWidth = page.getWidth();
        ImageView mImageViewCloud = (ImageView) getView().findViewById(R.id.cloud);
        ImageView mImageButterfly = (ImageView) getView().findViewById(R.id.butterfly);

        if (position < -1) { // [-Infinity,-1)
            // This page is way off-screen to the left.
            page.setAlpha(0);

        } else if (position <= 1) { // [-1,1]

            if(mImageViewCloud!=null)mImageViewCloud.setTranslationX((float) (-(1 - position) * 0.5 * pageWidth));
            if(mImageButterfly!=null)mImageButterfly.setTranslationX((float) ((1 - position) * 1.5 * pageWidth));
            // The 0.5, 1.5, 1.7 values you see here are what makes the view move in a different speed.
            // The bigger the number, the faster the view will translate.
            // The result float is preceded by a minus because the views travel in the opposite direction of the movement.


        } else { // (1,+Infinity]
            // This page is way off-screen to the right.
            page.setAlpha(0);
        }
}

感谢任何帮助。谢谢!

修改 AdapterFragment.java

public abstract class AdapterFragment extends Fragment {

    SparseArray<AdapterFragment> registeredFragments = new SparseArray<AdapterFragment>();

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        AdapterFragment fragment = (AdapterFragment) super.instantiateItem(container, position);
        registeredFragments.put(position, fragment);
        return fragment;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        registeredFragments.remove(position);
        super.destroyItem(container, position, object);
    }

    public void pass(int farFarAway) {
        for(int i = 0, nSize = registeredFragments.size(); i < nSize; i++)
            registeredFragments.valueAt(i).pass(farFarAway);
    }

    final int pageWidth = ViewPager.getMeasuredWidth(); //after ViewPager drawn, probably its also screen width
    final int scrollRange = (AdapterFragment.getCount()-1)*pageWidth;

    ViewPager.OnPageChangeListener OPCL = new ViewPager.OnPageChangeListener() {

        @Override
        public void onPageSelected(int position) {
        }

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

            float farFarAway=(float)(position*pageWidth+positionOffsetPixels), scrollToFactor = farFarAway/scrollRange;
            AdapterFragment.pass(farFarAway);
        }

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

2 个答案:

答案 0 :(得分:0)

你试过ViewPager.OnPageChangeListener吗?此接口onPageScrolled(int position, float positionOffset, int positionOffsetPixels)中有一个方法,最后两个变量可能对您有用 - 将移动偏移传递给所有Fragment,其中移动View s

编辑:

final int pageWidth=mainViewPager.getMeasuredWidth(); //after ViewPager drawn, probably its also screen width
final int scrollRange = (viewPagerCustomAdapter.getCount()-1)*pageWidth;

OnPageChangeListener onpcl = new OnPageChangeListener() {

                @Override
                public void onPageSelected(int position) {
                }

                @Override
                public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                    float farFarAway=(float)(position*pageWidth+positionOffsetPixels),
                    scrollToFactor = farFarAway/scrollRange;

                    viewPagerCustomAdapter.pass(farFarAway);
                }

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

viewPagerCustomAdapter是一个调度farFarAway的适配器 - 从0位置片段的左边缘开始移动距离ViewPager。如何将移动的值分配给当前存在的Fragment? - check this并在适配器for内的所有已注册片段上创建pass(int farFarAway)循环。在每个片段中,您可以计算setTranslationX的正确值。您也可以传递并使用scrollToFactor(0.0-1.0)和位置,这些可能很有用。例如位置可能决定您是当前还是下一个Fragment。请注意,默认ViewPager内存设置为1,因此一次注册的Fragment不能超过3个(当前+下一个)

编辑2:

创建新类并扩展适配器中使用的所有Fragment

public abstract class AdapterFragment extends Fragment{
    public abstract pass(int farFarAway);
}

将这些行添加到您的适配器:

SparseArray<AdapterFragment> registeredFragments = new SparseArray<AdapterFragment>();

@Override
public Object instantiateItem(ViewGroup container, int position) {
    AdapterFragment fragment = (AdapterFragment) super.instantiateItem(container, position);
    registeredFragments.put(position, fragment);
    return fragment;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    registeredFragments.remove(position);
    super.destroyItem(container, position, object);
}

public void pass(int farFarAway) {
    for(int i = 0, nsize = registeredFragments.size(); i < nsize; i++)
        registeredFragments.valueAt(i).pass(farFarAway);
}

OnPageChangeListener设置ViewPager以上。这样每个Fragment都会获得当前的滚动位置。以及在Fragment s

之一中使用的示例
public void pass(int farFarAway){
    imageView.setTranslationX(farFarAway/10); //sample value 10, farFarAway is too big value for moving any View
}

ImageView移动ViewPager时应该移动,根据需要进行调整。这整个帖子几乎是完整的解决方案,应该是有用的......

PS。代码未经过测试,可能是一些语法或其他错误

答案 1 :(得分:0)

尝试阅读Fragment共享元素。也许这就是你要找的东西。