Android 同步ViewPager中的片段滚动

Android 同步ViewPager中的片段滚动,android,android-fragments,android-viewpager,scrollview,Android,Android Fragments,Android Viewpager,Scrollview,我试图复制类似的内容,但我完全不知道如何在ViewPager中同步同一高度上的所有滚动视图 我在片段内部使用一个ScrollListener来设置背景的不透明度并更新其他片段 final ViewTreeObserver.OnScrollChangedListener onScrollChangedListener = new ViewTreeObserver.OnScrollChangedListener() { @Override public void onScrollC

我试图复制类似的内容,但我完全不知道如何在ViewPager中同步同一高度上的所有滚动视图

我在片段内部使用一个ScrollListener来设置背景的不透明度并更新其他片段

final ViewTreeObserver.OnScrollChangedListener onScrollChangedListener = new ViewTreeObserver.OnScrollChangedListener() {

    @Override
    public void onScrollChanged() {
        if(scrollView.getScrollY() > 0 && scrollView.getScrollY() < 1200) {
            overlay.getBackground().setAlpha((scrollView.getScrollY()/4));

            if(isVisible()) {
                Activity parent = getActivity();
                if(parent != null && parent instanceof MainActivity) {
                    ((MainActivity)parent).updateHeight(scrollView.getScrollY());
                }
            }
        }
    }
};
PS:我也很不确定在ScrollView上获得更新的正确模式。OnScrollChangedListener似乎可以工作,但它被调用了很多次,所以我不确定它是否是正确的方法


提前感谢。

使用此方法,仅对屏幕外的视图手动更新scrollView:

public void updateFragmentsScroll(int scrollY) {
    // TODO Auto-generated method stub
    if(pager.getCurrentItem()<adapter.getCount()-1){
        PagerItem nextItem = (PagerItem) adapter.instantiateItem(pager, pager.getCurrentItem()+1);
        if(nextItem!=null && nextItem.isAdded()){
            nextItem.setScrollY(scrollY);
        }
    }
    if(pager.getCurrentItem()>0){
        PagerItem prevItem = (PagerItem) adapter.instantiateItem(pager, pager.getCurrentItem()-1);
        if(prevItem!=null && prevItem.isAdded()){
            prevItem.setScrollY(scrollY);
        }
    }
    currentScrollY = scrollY;   
}
public void updateFragmentsScroll(int scrollY){
//TODO自动生成的方法存根
if(pager.getCurrentItem()0){
PagerItem PreviItem=(PagerItem)adapter.InstanceItem(pager,pager.getCurrentItem()-1);
if(previitem!=null&&previitem.isAdded()){
PreviItem.SetScroly(滚动);
}
}
currentScrollY=scrollY;
}
如果
ViewPager
中的片段未以某种方式添加,或者您滚动多个页面而不滚动页面内容,则在创建片段时传递currentScrollY


FragmentStatePagerAdapter
btw.

更新:

我刚刚在gradle/maven上发布了这个解决方案()
它也有一对夫妇的修正和差异,从上次发布,所以检查代码无论如何

请随意使用它并贡献自己的力量!谢谢。:)


好的,我已经改变了应用程序的所有结构,也修复了这一部分,这比预期的要容易

几分钟后就要测试了,所以这可能有问题,但似乎效果不错。我基本上创建了一个类,它将负责同步所有的ScrollView,ScrollView只在滚动时通知这个同步器

public class Synchronizer {

    private static Synchronizer instance;

    private List<Synchronizable> synchronizableList;

    private Synchronizer() {}

    public static Synchronizer getInstance() {
        if (instance == null)
            instance = new Synchronizer();
        return instance;
    }

    public void registerSynchronizable(Synchronizable synchronizable) {
        if(synchronizableList == null)
            synchronizableList = new ArrayList<>();

        synchronizableList.add(synchronizable);
    }

    public void update(Synchronizable sender, int update) {
        if(update < 0) update = 0;

        for(Synchronizable s : synchronizableList) {
            if(s != sender)
                s.onUpdate(update);
        }
    }

    public interface Synchronizable {
        public void onUpdate(int update);
    }
}

希望这会有帮助

这是一个超级解决方案!谢谢是否有办法取消注册不再需要同步的滚动视图?例如,已销毁的滚动视图?如果不是的话,
synchronizableList
可能会变得非常大。是的,你是对的,它应该是。我可能会把它推到Github上,以获得更多的评论和建议,但谢谢。很乐意帮忙。:)链接我,当你这样做,我会很高兴地作出贡献!嗨@pinkydoe,为了让你不断更新,我刚刚在Github上发布了这个视图,并在gradle/mvn上发布了它。自由投稿!:)我已经搜索了2天这种滚动视图,很好的解决方案:),它正好适合我的要求,非常感谢。
public void updateFragmentsScroll(int scrollY) {
    // TODO Auto-generated method stub
    if(pager.getCurrentItem()<adapter.getCount()-1){
        PagerItem nextItem = (PagerItem) adapter.instantiateItem(pager, pager.getCurrentItem()+1);
        if(nextItem!=null && nextItem.isAdded()){
            nextItem.setScrollY(scrollY);
        }
    }
    if(pager.getCurrentItem()>0){
        PagerItem prevItem = (PagerItem) adapter.instantiateItem(pager, pager.getCurrentItem()-1);
        if(prevItem!=null && prevItem.isAdded()){
            prevItem.setScrollY(scrollY);
        }
    }
    currentScrollY = scrollY;   
}
public class Synchronizer {

    private static Synchronizer instance;

    private List<Synchronizable> synchronizableList;

    private Synchronizer() {}

    public static Synchronizer getInstance() {
        if (instance == null)
            instance = new Synchronizer();
        return instance;
    }

    public void registerSynchronizable(Synchronizable synchronizable) {
        if(synchronizableList == null)
            synchronizableList = new ArrayList<>();

        synchronizableList.add(synchronizable);
    }

    public void update(Synchronizable sender, int update) {
        if(update < 0) update = 0;

        for(Synchronizable s : synchronizableList) {
            if(s != sender)
                s.onUpdate(update);
        }
    }

    public interface Synchronizable {
        public void onUpdate(int update);
    }
}
public class MyScrollView extends ScrollView implements Synchronizer.Synchronizable {

    public MyScrollView(Context context) {
        super(context);
        init();
    }

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

    public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }   

    private void init() {
        // init your ScrollView with style and stuff and then register it

        Synchronizer.getInstance().registerSynchronizable(this);
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);

        // listen for "your" scrolls and notify the Synchronizer
        Synchronizer.getInstance().update(this, getScrollY());
    }

    @Override
    public void onUpdate(int update) {
        // listen for the scrolls of your "siblings" from the Synchronizer
        setScrollY(update);
    }
}