安卓中級教程(3):ScrollView



以上是scrollview的圖例,可見srollview是一種滑動功能的控件,亦是非常常見的控件。
一般寫法如下:
package com.mycompany.viewscroller; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; import android.view.ViewGroup; import android.view.animation.Interpolator; import android.widget.Scroller; import android.widget.Toast; /** * 實現上下滑動的效果,主要利用了屏幕坐標系和滾動條,有五個參數必須預先設置 * @author Administrator * */ public class VerticalPager extends ViewGroup{ private Scroller mScroller; //第一個參數:滾動條 private Context mContext; //第二個參數:滾動內容 private final static int RATE = 5; //第三個參數:速率標準 private final static int DISTANCE = 300;//需要滾動的距離 private VelocityTracker mVelocityTracker;//通過此方法可以計算速度 public VerticalPager(Context context, AttributeSet attrs) { super(context, attrs); this.mContext=context; mScroller=new Scroller(context); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int totalHeight=0; int count=getChildCount(); for(int i=0;i<count;i++){ View childView=getChildAt(i); childView.layout(l, totalHeight, r, totalHeight+b); totalHeight+=b; } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width=MeasureSpec.getSize(widthMeasureSpec); int height=MeasureSpec.getSize(heightMeasureSpec); int count=getChildCount(); for(int i=0;i<count;i++){ getChildAt(i).measure(width, height); } setMeasuredDimension(width, height); } private int mLastMotionY; @Override public boolean onTouchEvent(MotionEvent event) { if(mVelocityTracker==null){ mVelocityTracker=VelocityTracker.obtain(); } mVelocityTracker.addMovement(event); int action=event.getAction(); float y=event.getY(); switch(action){ case MotionEvent.ACTION_DOWN: if(!mScroller.isFinished()){ mScroller.abortAnimation(); } mLastMotionY=(int) y; Log.d("montion", ""+getScrollY()); break; case MotionEvent.ACTION_MOVE: int deltaY=(int) (mLastMotionY-y); scrollBy(0,deltaY); invalidate(); mLastMotionY=(int) y; break; case MotionEvent.ACTION_UP: // if(mVelocityTracker!=null){ // mVelocityTracker.recycle(); // mVelocityTracker=null; // } mVelocityTracker.computeCurrentVelocity(1, 1000); //單位為1說明,一秒一個像素,最大值為1000 float vy = mVelocityTracker.getYVelocity(); //vy代表Y軸方向的速率 Log.i("test","velocityTraker : "+mVelocityTracker.getYVelocity()); if(getScrollY()<0){ mScroller.startScroll(0, -DISTANCE, 0, DISTANCE); }else if(getScrollY()>(getHeight()*(getChildCount()-1))){ View lastView=getChildAt(getChildCount()-1); mScroller.startScroll(0,lastView.getTop()+DISTANCE, 0, -DISTANCE); }else{ int position=getScrollY()/getHeight(); View positionView = null; if(vy<-RATE){ //下滑 positionView=getChildAt(position+1); mScroller.startScroll(0, positionView.getTop()-DISTANCE, 0, +DISTANCE); }else if(vy>RATE){//上滑 positionView=getChildAt(position); mScroller.startScroll(0, positionView.getTop()-DISTANCE, 0, +DISTANCE); }else { int mod=getScrollY()%getHeight(); if(mod>getHeight()/2){ positionView=getChildAt(position+1); mScroller.startScroll(0, positionView.getTop()-DISTANCE, 0, +DISTANCE); }else{ positionView=getChildAt(position); mScroller.startScroll(0, positionView.getTop()+DISTANCE, 0, -DISTANCE); } } } invalidate(); break; } return true; //返回true表示事件由本View消費掉 } @Override public void computeScroll() { super.computeScroll(); if(mScroller.computeScrollOffset()){ scrollTo(0, mScroller.getCurrY()); } } }
xml.格式如下:
<?xml version="1.0" encoding="UTF-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <com.example.viewpagervertical.VerticalPager android:id="@+id/vertyPager1" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/textView1" android:layout_width="match_parent" android:layout_height="100dp" android:text="TextView1111" /> <TextView android:id="@+id/textView2" android:layout_width="fill_parent" android:layout_height="100dp" android:text="TextView2222" /> <TextView android:id="@+id/textView3" android:layout_width="fill_parent" android:layout_height="100dp" android:text="TextView2222" /> <TextView android:id="@+id/textView4" android:layout_width="fill_parent" android:layout_height="100dp" android:text="TextView2222" /> </com.example.viewpagervertical.VerticalPager> </LinearLayout>
掌握簡單的scroll滾動功能是遠遠不足以應付我們現實上的需要,為了可以深入地深討scroll滾動功能的中級應用,我在下面先提供一條鏈結,大家可以嘗試將各種滾動功能併合在一起,測試其兼容。
http://xm.cmgine.net/archives/10052.html
在這一中級教程的章節中,我們首先會探討:如何測試ListView是否已經滾動到底部的問題。因為在ListView和ScrollView之間經常會出錯,出錯當然是指ListView無法顯示到底的問題。這是我們中竹竹一月金要解沫的問題。
//我們可以用如下方法去測試是否已經滾動到最下方 if(getScrollY() + getHeight() >= computeVerticalScrollRange()) { Log.d(TAG,"------滾動到最下方------"); } else { Log.d(TAG,"没有到最下方"); } //在實際應用中,可以矕繼承ScrollView,來實現這個功能,如下: public class XScrollView extends ScrollView { protected Context ctx=null; public XScrollView(Context context) { super(context); ctx=context; // TODO Auto-generated constructor stub } protected OnScrollStateChanged sc=null; public void setOnScrollStateChanged(OnScrollStateChanged _sc) { sc=_sc; } @Override protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) { // TODO Auto-generated method stub if(getScrollY() + getHeight() >= computeVerticalScrollRange()) { sc.ScrollBottom(); } super.onOverScrolled(scrollX, scrollY, clampedX, clampedY); } } public interface OnScrollStateChanged { public void ScrollTop(); public void ScrollBottom(); }
 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号