public class HorizontalScrollView extends ViewGroup {    //手势    private GestureDetector mGestureDetector;    private HorizontalScroller mScroller;    private int curID;    //快速滑动    private boolean isFlying;    //--回调函数-------------------------------------    private OnChangeListener mListener;    public void setOnChangeListener(OnChangeListener listener) {        if (listener != null) {            mListener = listener;        }    }    public interface OnChangeListener{        void move2dest(int curID);    }    public HorizontalScrollView(Context context) {        this(context, null);    }    public HorizontalScrollView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public HorizontalScrollView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        mScroller = new HorizontalScroller();        isFlying = false;        initGesture(context);    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        // 模向移动,        for (int i = 0; i < getChildCount(); i++) {            View view = getChildAt(i);            //给水平方向的每个view定位            view.layout(i * getWidth(), 0, getWidth() + i * getWidth(), getHeight());        }    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        for (int i = 0; i < getChildCount(); i++) {            View view = getChildAt(i);            view.measure(widthMeasureSpec, heightMeasureSpec);        }        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        mGestureDetector.onTouchEvent(event);        switch (event.getAction()) {        case MotionEvent.ACTION_DOWN:            if (!isFlying) {                move2dest();            }            isFlying = false;            break;        case MotionEvent.ACTION_MOVE:            break;        case MotionEvent.ACTION_UP:            break;        default:            break;        }        return true;    }    public void move2dest() {        //        int destID = (getScrollX() + getWidth() / 2) / getWidth();        move2dest(destID);    }    public void move2dest(int destID) {        curID = destID;        if (destID > getChildCount() - 1) {            destID = getChildCount() - 1;        }        if (mListener != null) {            mListener.move2dest(curID);        }        int distance = (int) (destID * getWidth() - getScrollX());        // scrollBy(distance, 0);        mScroller.startScroll(getScrollX(), getScrollY(), distance, 0);        invalidate();    }    /** * invalidate()此方法会触发下面的方法 */    @Override    public void computeScroll() {        // 如果存在偏移,就不断刷新        if (mScroller.computeScrollOffset()) {            scrollTo(mScroller.getCurrX(), 0);            invalidate();        }        super.computeScroll();    }    private void initGesture(Context context) {        mGestureDetector = new GestureDetector(context, new OnGestureListener() {            @Override            public boolean onSingleTapUp(MotionEvent e) {                return false;            }            @Override            public void onShowPress(MotionEvent e) {            }            @Override            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {                scrollBy((int) distanceX, 0);                return false;            }            @Override            public void onLongPress(MotionEvent e) {            }            @Override            /** * 快速滑动时 */            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {                isFlying = true;                if (curID > 0 && velocityX > 0) {// 表示向左移                    move2dest(curID - 1);                } else if (curID < getChildCount() && velocityX < 0) {                    move2dest(curID + 1);// 向右                } else {                    move2dest();// 移到原位                }                return false;            }            @Override            public boolean onDown(MotionEvent e) {                return false;            }        });    }}
/** * 位移计算工具类 * * @author chenlin * */public class HorizontalScroller {    private int startX;    private int startY;    private int distanceX;    private int distanceY;    private int currentX;    private int currentY;    private long startTime;    private long duration = 1000L;    private boolean isFinish;    /** * * @param scrollX * x坐标 * @param scrollY * y坐标 * @param distanceX * X方向移动的距离 * @param distanceY * y方向移动的距离 */    public void startScroll(int scrollX, int scrollY, int distanceX, int distanceY) {        startX = scrollX;        startY = scrollY;        this.distanceX = distanceX;        this.distanceY = distanceY;        isFinish = false;        startTime = SystemClock.uptimeMillis();    }    /** * 计算偏移量, * * @return true 还在移动 false:移动已经停止 */    public boolean computeScrollOffset() {        if (isFinish) {            return false;        }        long timePassed = SystemClock.uptimeMillis() - startTime;        if (timePassed < duration) {            currentX = (int) (startX + distanceX * timePassed / duration);            currentY = (int) (startY + distanceY * timePassed / duration);            System.out.println("currentX:::" + currentX);        } else if (timePassed >= duration) {            currentX = startX + distanceX;            currentY = startY + distanceY;            isFinish = true;        }        return true;    }    public int getCurrX() {        return currentX;    }    public void setCurrentX(int currentX) {        this.currentX = currentX;    }    public int getCurrentY() {        return currentY;    }    public void setCurrentY(int currentY) {        this.currentY = currentY;    }}

使用方法

public class ScrollActivity extends Activity implements OnCheckedChangeListener, OnChangeListener {    private int[] ids = { R.drawable.a1, R.drawable.a2, R.drawable.a3, R.drawable.a4, R.drawable.a5, R.drawable.a6 };    private HorizontalScrollView mView;    private LinearLayout mLayout;    private RadioGroup mGroup;    @Override    protected void onCreate(Bundle savedInstanceState) {        requestWindowFeature(Window.FEATURE_NO_TITLE);        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_myscrollview);        init();    }    private void init() {        mLayout = (LinearLayout) findViewById(R.id.body_layout);        mGroup = (RadioGroup) findViewById(R.id.radiogroup);        mView = new HorizontalScrollView(this);        for (int i = 0; i < ids.length; i++) {            ImageView imageView = new ImageView(this);            imageView.setBackgroundResource(ids[i]);            mView.addView(imageView);        }        mLayout.addView(mView);        // 随便添加一个view        View view = getLayoutInflater().inflate(R.layout.activity_progressview, null);        mView.addView(view, 3);        for (int i = 0; i < mView.getChildCount(); i++) {            RadioButton radioButton = new RadioButton(this);            // 设置id的编号            radioButton.setId(i);            mGroup.setOrientation(LinearLayout.HORIZONTAL);            mGroup.addView(radioButton);            if (i == 0) {                radioButton.setChecked(true);            }        }        mGroup.setOnCheckedChangeListener(this);        mView.setOnChangeListener(this);    }    @Override    public void onCheckedChanged(RadioGroup group, int checkedId) {        mView.move2dest(checkedId);    }    @Override    public void move2dest(int curID) {        RadioButton radioButton = (RadioButton) mGroup.getChildAt(curID);        radioButton.setChecked(true);    }}

布局文件

<?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" >    <RadioGroup  android:id="@+id/radiogroup" android:layout_width="wrap_content" android:layout_height="wrap_content" >    </RadioGroup>    <LinearLayout  android:id="@+id/body_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" >    </LinearLayout></LinearLayout>

更多相关文章

  1. android 获取屏幕的方向
  2. android 动态设置Activity 的切换方向
  3. android 坐标布局 AbsoluteLayout
  4. android 传感器使用与开发----方向传感器
  5. Android 屏幕(View)坐标系统
  6. gridview第一行与顶端有一定的距离

随机推荐

  1. android 镜像制作方法
  2. AIDL使用学习(一):基础使用学习
  3. Android(安卓)下载Zip文件,并解压到本地,
  4. Android主题换肤 无缝切换
  5. 《深入浅出Android多媒体编程》即将出版,
  6. [RK3288][Android6.0] 调试笔记 --- user
  7. Android 关于RemoteViews的理解(一)
  8. android 控件在不同状态下的内容样式与背
  9. Android服务器——TomCat服务器的搭建
  10. android:m/mm/mmm