This article describes the Android development of containers that implement custom horizontal scrolling. Share it for your reference, as follows:
public class HorizontalScrollView extends ViewGroup { //gesture private GestureDetector mGestureDetector; private HorizontalScroller mScroller; private int curID; //Swipe fast private boolean isFlying; //-Callback function-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 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) { // Modular movement, for (int i = 0; i < getChildCount(); i++) { View view = getChildAt(i); // Position each view in the horizontal direction (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); (widthMeasureSpec, heightMeasureSpec); } (widthMeasureSpec, heightMeasureSpec); } @Override public boolean onTouchEvent(MotionEvent event) { (event); switch (()) { 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); (getScrollX(), getScrollY(), distance, 0); invalidate(); } /** * invalidate() This method will trigger the following method */ @Override public void computeScroll() { // If there is an offset, it will be refreshed continuously if (()) { scrollTo((), 0); invalidate(); } (); } 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 /** * When swiping quickly */ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { isFlying = true; if (curID > 0 && velocityX > 0) {// means to move left move2dest(curID - 1); } else if (curID < getChildCount() && velocityX < 0) { move2dest(curID + 1);// To the right } else { move2dest();// Move to original position } return false; } @Override public boolean onDown(MotionEvent e) { return false; } }); } }
/** * Displacement calculation tool category * * @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 coordinates * @param scrollY * y coordinates * @param distanceX * Distance moving in the X direction * @param distanceY * Distance moving in the y direction */ public void startScroll(int scrollX, int scrollY, int distanceX, int distanceY) { startX = scrollX; startY = scrollY; = distanceX; = distanceY; isFinish = false; startTime = (); } /** * Calculate the offset, * * @return true Still moving false: the movement has stopped */ public boolean computeScrollOffset() { if (isFinish) { return false; } long timePassed = () - startTime; if (timePassed < duration) { currentX = (int) (startX + distanceX * timePassed / duration); currentY = (int) (startY + distanceY * timePassed / duration); ("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) { = currentX; } public int getCurrentY() { return currentY; } public void setCurrentY(int currentY) { = currentY; } }
How to use
public class ScrollActivity extends Activity implements OnCheckedChangeListener, OnChangeListener { private int[] ids = { .a1, .a2, .a3, .a4, .a5, .a6 }; private HorizontalScrollView mView; private LinearLayout mLayout; private RadioGroup mGroup; @Override protected void onCreate(Bundle savedInstanceState) { requestWindowFeature(Window.FEATURE_NO_TITLE); (savedInstanceState); setContentView(.activity_myscrollview); init(); } private void init() { mLayout = (LinearLayout) findViewById(.body_layout); mGroup = (RadioGroup) findViewById(); mView = new HorizontalScrollView(this); for (int i = 0; i < ; i++) { ImageView imageView = new ImageView(this); (ids[i]); (imageView); } (mView); // Add a view at will View view = getLayoutInflater().inflate(.activity_progressview, null); (view, 3); for (int i = 0; i < (); i++) { RadioButton radioButton = new RadioButton(this); // Set the ID number (i); (); (radioButton); if (i == 0) { (true); } } (this); (this); } @Override public void onCheckedChanged(RadioGroup group, int checkedId) { mView.move2dest(checkedId); } @Override public void move2dest(int curID) { RadioButton radioButton = (RadioButton) (curID); (true); } }
Layout file
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andro android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <RadioGroup android: android:layout_width="wrap_content" android:layout_height="wrap_content" > </RadioGroup> <LinearLayout android: android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > </LinearLayout> </LinearLayout>
For more information about Android related content, please check out the topic of this site:Summary of the usage of basic Android components》、《Android development introduction and advanced tutorial》、《Android layout layout tips summary》、《Android View View Tips Summary》、《Android programming activity operation skills summary》、《Android resource operation skills summary"and"Android control usage summary》
I hope this article will be helpful to everyone's Android programming design.