我试图复制像Yahoo! Weather app这样的内容,但我对如何同步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());
}
}
}
}
};
在MainActivity中,我做了类似的事情:
public void updateHeight(int scroll) {
for(int i = 0; i<mPager.getChildCount(); i++) {
View v = mPager.getChildAt(i);
ScrollView scrollView = (ScrollView) v.findViewById(R.id.frag_scrollview);
scrollView.setScrollY(scroll);
}
}
这几乎是&#34;工作,但不是真的。
我尝试修改代码以避免更新当前的可见页面,但没有成功:
if(i != mPager.getCurrentItem()) {
View v = mPager.getChildAt(i);
ScrollView scrollView = (ScrollView) v.findViewById(R.id.frag_scrollview);
scrollView.setScrollY(scroll);
}
PS:我还非常不确定正确的模式,以便在ScrollView上获得更新。 OnScrollChangedListener似乎有效,但它被称为很多次,所以我不确定它是否是正确的方法。
提前致谢。
答案 0 :(得分:6)
<强>更新强>
我刚刚在gradle / maven上发布了这个解决方案(SynchronizedScrollView)! 它还有一些与上次发布的修复和差异,因此请检查代码!
随意使用它并贡献!谢谢。 :)
好的,我已经更改了应用程序的所有结构并修复了这部分,它比预期的要容易。
刚刚在几分钟内测试过,所以也许这有问题,但似乎工作得很好。我基本上创建了一个类,它将保持同步所有ScrollView的责任,而ScrollViews只需在它们滚动时通知这个Synchronizer。
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);
}
}
并且ScrollView将实现Synchronizable
接口,他们将&#34;注册&#34;在创作
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);
}
}
希望这会有所帮助!
答案 1 :(得分:0)
使用此方法,仅对屏幕外的视图手动更新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;
}
如果ViewPager
中的片段没有以某种方式添加,或者您滚动多个页面而不滚动页面内容,则在创建片段时传递currentScrollY。
FragmentStatePagerAdapter
btw。