[關鍵字] Synchronized ScrollView / Android / Scroll simultaneously / onScrollChanged

 

分享一個自己研究出來的範例 -- 兩個 ScrollView 的同步,

假設現在有兩個 ScrollView A / ScrollView B,

當我捲動 ScrollView A 時,旁邊的 ScrollView B 也有相對應的移動。

如果你有這樣的困擾,那這個範例就是你要的。

 

要做到這樣的 ScrollView 同步,關鍵的 method 是在 ScrollView 之下的

onScrollChanged,可是問題在於,google 的原生程式碼把這個 method 宣告為

受保護的(protected),也就是說一般開發者不能夠直接 new 一個 ScrollView 的實體,

然後就叫用 onSchrollChanged()。

 

那該怎麼做呢?這就是比較麻煩的地方。我們必須自己寫一個 Class,

去繼承 ScrollView 然後再覆寫裡頭的 onScrollChanged,

做你想做的事情,這樣才可以達到我們想要的結果。

Screen Shot 2013-01-06 at 5.19.45 PM  

code:

package com.anythru.syncscrollview;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView;

public class SyncScrollView extends ScrollView {

    private SyncScrollViewListener syncScrollViewListener = null;
    
    public SyncScrollView(Context context) {
        super(context);
        
    }
    
    public SyncScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        
    }
    
    @Override
    protected void onScrollChanged(int x, int y, int oldX, int oldY){
        super.onScrollChanged(x, y, oldX, oldY);
        if (syncScrollViewListener != null){
            syncScrollViewListener.onScrollChanged(this, x, y, oldX, oldY);
        }
    }
    
    public void setScrollViewListener (SyncScrollViewListener syncScrollViewListener){
            this.syncScrollViewListener = syncScrollViewListener;
    }
    
}

 另外,我們需要一個 Listener 去監聽 ScrollChange:

code:

package com.anythru.syncscrollview;

public interface SyncScrollViewListener {
    
    public void onScrollChanged(SyncScrollView ssv, int x, int y, int oldX, int oldY);

}

 

 接下來我們便可以在我們的 Activity 裡頭實作我們自己寫好的這個 Class:

Screen Shot 2013-01-06 at 5.48.34 PM   

Screen Shot 2013-01-06 at 5.53.36 PM   

code:

package com.anythru.syncscrollview;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.Color;
import android.view.Menu;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class MainActivity extends Activity {

    SyncScrollView ssv_A;
    SyncScrollView ssv_B;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        RelativeLayout baseRL = (RelativeLayout) this.findViewById(R.id.baseRL);
        
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                LayoutParams.FILL_PARENT, 
                LayoutParams.FILL_PARENT, 1.0f);
        
        
        ssv_A = new SyncScrollView(getBaseContext());
        ssv_A.setLayoutParams(params);
        ssv_A.setScrollViewListener(new SynchronizedSV());
        ssv_A.setBackgroundColor(Color.RED);
        
        ssv_B = new SyncScrollView(getBaseContext());
        ssv_B.setLayoutParams(params);
        ssv_B.setScrollViewListener(new SynchronizedSV());
        ssv_B.setBackgroundColor(Color.GREEN);
        
        ssv_A.addView(generateLinearLayout("ssv_A item", 50));
        ssv_B.addView(generateLinearLayout("ssv_B item", 50));
        
        LinearLayout linearLayout = new LinearLayout(getBaseContext());
        linearLayout.setLayoutParams(params);
        linearLayout.setOrientation(LinearLayout.HORIZONTAL);
        linearLayout.addView(ssv_A);
        linearLayout.addView(ssv_B);
        
        baseRL.addView(linearLayout);
    }
    
    private LinearLayout generateLinearLayout(String text, int number){
        LinearLayout ll = new LinearLayout(getBaseContext());
        ll.setOrientation(LinearLayout.VERTICAL);
        
        for(int i = 0;i<number;i++){
            TextView tv = new TextView(getBaseContext());
            tv.setText(text + " " + i);
            tv.setTextSize(22);
            ll.addView(tv);
        }
        
        return ll;
    }
    
    private class SynchronizedSV implements SyncScrollViewListener{

        @Override
        public void onScrollChanged(SyncScrollView ssv, int x, int y, int oldX,
                int oldY) {
            if(ssv == ssv_A){
                ssv_B.smoothScrollTo(x, y);
            }
            if(ssv == ssv_B){
                ssv_A.smoothScrollTo(x, y);
            }
            
        }
        
    }
    

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}


根據這一段 code,可以得到兩個同時移動的 ScrollView:

Screen Shot 2013-01-06 at 6.03.10 PM  

所以如果你想要多做一些變化,就自行在 onScrollChanged 裡頭

做你想做的事情,可以同步,當然也可以反向移動,在下一篇裡頭我會

再介紹加強版的橫向鏡象移動的 ScrollView ,可以延伸研究喔~

 

還不甚了解嗎? 由此下載整包APP以方便套用!

http://fiberupload.net/xm7falaydv1s/SyncScrollView.7z

 

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 keep walking 的頭像
    keep walking

    Winner? Loser? No matter

    keep walking 發表在 痞客邦 留言(0) 人氣()