[英]Synchronize fragment scroll in ViewPager
我正在嘗試復制類似Yahoo!的內容。 天氣應用程序 ,但是我對如何在ViewPager中的相同高度上同步所有滾動視圖一無所知。
我在Fragments中使用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);
}
}
這是“幾乎”有效的,但並非如此。
我試圖修改代碼以避免更新當前可見頁面,但是沒有成功:
if(i != mPager.getCurrentItem()) {
View v = mPager.getChildAt(i);
ScrollView scrollView = (ScrollView) v.findViewById(R.id.frag_scrollview);
scrollView.setScrollY(scroll);
}
PS:我也不太確定要在ScrollView上獲取更新的正確模式。 OnScrollChangedListener似乎可以正常工作,但是它被稱為LOTS時代,所以我不確定這是否是正確的方法。
提前致謝。
更新:
我剛剛在gradle / maven上發布了此解決方案( SynchronizedScrollView )!
它也有一些修復和與上次發布的不同,所以還是請檢查代碼!
隨時使用它並做出貢獻! 謝謝。 :)
好的,我更改了應用程序的所有結構,並修復了此部分,這比預期的要容易。
剛剛在幾分鍾內進行了測試,因此可能存在一些問題,但似乎效果很好。 我基本上制作了一個類,該類將負責同步所有ScrollView,並且ScrollView在滾動時僅通知此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
接口,並且它們將在創建時“注冊”
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);
}
}
希望這會有所幫助!
使用此方法,僅針對屏幕外的視圖手動更新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。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.