[關鍵字] 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,
做你想做的事情,這樣才可以達到我們想要的結果。
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:
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:
所以如果你想要多做一些變化,就自行在 onScrollChanged 裡頭
做你想做的事情,可以同步,當然也可以反向移動,在下一篇裡頭我會
再介紹加強版的橫向鏡象移動的 ScrollView ,可以延伸研究喔~
還不甚了解嗎? 由此下載整包APP以方便套用!
http://fiberupload.net/xm7falaydv1s/SyncScrollView.7z