рдЪрд╛рд░ рджрд┐рд╢рд╛рдУрдВ рдореЗрдВ рджреЛ - рдирд╣реАрдВ рдореЗрдВ рд╕рд╛рдЗрдбрд┐рдВрдЧ

Android ViewPager рдХреЗ рддрд╣рдд рд╕реНрдХреНрд░реАрди рд╕реНрд▓рд╛рдЗрдбрд┐рдВрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ Habr├й рд▓реЗрдЦ рдкрд░, ViewPagerIndicator рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдмрд╛рд░ рдорд┐рд▓реЗред рдореИрдВ рдЪрд╛рд░ рджрд┐рд╢рд╛рдУрдВ рдореЗрдВ рд╕реНрд▓рд╛рдЗрдб рдХрд╛ рд╡рд┐рдХрд▓реНрдк рджреЗрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред



рдЗрддрдирд╛ рд╕рдордп рдкрд╣рд▓реЗ рдирд╣реАрдВ, рдореБрдЭреЗ рдЪрд╛рд░ рджрд┐рд╢рд╛рдУрдВ рдореЗрдВ рдПрдХ рд╕реНрдХреНрд░реАрди рд╕реНрд▓рд╛рдЗрдб рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереА: рдмрд╛рдПрдВ, рджрд╛рдПрдВ, рдКрдкрд░ рдФрд░ рдиреАрдЪреЗред рдЗрдВрдЯрд░рдиреЗрдЯ рдкрд░ рдЦреЛрдЬреЛрдВ рдиреЗ рд╕рдХрд╛рд░рд╛рддреНрдордХ рдкрд░рд┐рдгрд╛рдо рдирд╣реАрдВ рджрд┐рдпрд╛, рдпрд╛ рд╢рд╛рдпрдж рдореИрдВ рдмреБрд░реА рддрд░рд╣ рд╕реЗ рджреЗрдЦ рд░рд╣рд╛ рдерд╛ред рдЗрд╕рд▓рд┐рдП рдЕрдВрдд рдореЗрдВ рдореИрдВрдиреЗ рд╡рд╣реА рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, рдЬрд┐рд╕рдХреА рдореБрдЭреЗ рдЦреБрдж рдЬрд░реВрд░рдд рд╣реИред

рдореБрдЭреЗ рдХрд╣рдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдореИрдВрдиреЗ рд╕реНрдХреНрд░реИрдЪ рд╕реЗ рд╢реБрд░реВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдерд╛, рдЗрд╕рдХрд╛ рдЖрдзрд╛рд░ рдерд╛ рдпрд╣рд╛рдВ рд╕реЗ RealViewSwitcher рдХрд╛ рдХреНрд╖реИрддрд┐рдЬ рд╕реНрд▓рд╛рдЗрдб рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдиред
рддреЛ, рдкреВрд░реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдПрдХ рдХрдХреНрд╖рд╛ TwoDirectionsViewSwitcher рдореЗрдВ рд░рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рдЬреЛ рдХрд┐ рд╡реНрдпреВрдЧреНрд░реБрдк рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рд╣реИред рдЖрд╡рд╢реНрдпрдХ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЖрдзрд╛рд░ рд╡рд░реНрдЧ рдХреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддрд░реАрдХреЛрдВ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ:

рдСрдирд╕реНрдХреНрд░реАрди рд╡рд┐рдзрд┐ рднрд╡рд┐рд╖реНрдп рдХреЗ рд╕реНрдХреНрд░реАрди рдХреЗ рд▓рд┐рдП рдЖрдпрд╛рдо рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреА рд╣реИ:

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 


OnLayout рд╕реНрдХреНрд░реАрди рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рд▓рд╛рдЗрдиреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рддрд╛ рд╣реИ (рд▓рд╛рдЗрдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ рдкрд╛рд░рд┐рдд рд╣реЛ рдЬрд╛рддреА рд╣реИ):

 protected void onLayout(boolean changed, int l, int t, int r, int b) 


рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рд╕реНрд╡рдпрдВ, рдЬрд┐рд╕рдореЗрдВ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕рдВрджрд░реНрдн рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рд╕реНрдХреНрд░реАрди рдХреА рд╕рд╛рдорд╛рдиреНрдп рд╕реВрдЪреА рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд▓рд╛рдЗрдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛:

 public TwoDirectionsViewSwitcher(Context context, int rows) 


рдСрди-рд╕реНрдХреНрд░реАрди рд╕реНрдХреНрд░реАрди рдХреЛ рдЫреВрдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдореБрдЦреНрдп рд╡рд┐рдзрд┐:

 public boolean onTouchEvent(MotionEvent ev) 


рдФрд░ рдЕрдВрддрд┐рдо, рдЪрд╛рдЗрд▓реНрдб рд╕реНрдХреНрд░реАрди рдХреЗ рд▓рд┐рдП рдХрдореНрдкреНрдпреВрдЯреНрдпреВрдЯ рд╕реНрдХреНрд░реЙрд▓рд┐рдВрдЧ рд╡рд┐рдзрд┐:
 public void computeScroll() 


рдЕрдм рд╣рдо рдХрдХреНрд╖рд╛ рдХреЗ рдХреБрдЫ рдкреНрд░рдореБрдЦ рддрд░реАрдХреЛрдВ рдкрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдзреНрдпрд╛рди рджреЗрдВрдЧреЗред OnLayout рд╡рд┐рдзрд┐ред

рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реИ, рдПрдХ рдиреЗрд╕реНрдЯреЗрдб рд▓реВрдк рдХреЛ рд▓рд╛рдЗрдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рджреНрд╡рд╛рд░рд╛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдмрд╛рдж рдХреА рд╕реНрдХреНрд░реАрди рдХреЗ рд▓рд┐рдП рдСрдлрд╝рд╕реЗрдЯ рд╕реЗрдЯ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред

рдПрдХ рдФрд░ рдЕрдзрд┐рдХ рдкрд░рд┐рд╖реНрдХреГрдд рд╡рд┐рдзрд┐ onTouchEvent рд╕реНрдХреНрд░реАрди рдЯрдЪ рд╣реИрдВрдбрд▓рд░ рд╣реИред

рдпрд╣рд╛рдБ рдпрд╣ рдорд╛рдирдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕реЗ рдЕрд▓рдЧ рд╣реИ, рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ MotionEvent.ACTION_DOW рдореЗрдВ, рд╕реНрдХреНрд░реАрди рдкрд░ рдЖрдВрджреЛрд▓рди рдХреА рд╢реБрд░реБрдЖрдд рдХрд╛ рддрдереНрдп рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╕реНрдХреНрд░реАрди рдХреЗ рд╡рд░реНрддрдорд╛рди рдПрдХреНрд╕ рдФрд░ рд╡рд╛рдИ рдкрджреЛрдВ рдХреЛ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рд╕реНрдХреНрд░реЙрд▓рд┐рдВрдЧ рдХреА рд╢реБрд░реБрдЖрдд рдХрд╛ рд╕рдВрдХреЗрдд рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

MotionEvent.ACTION_MOVE рд╣реИрдВрдбрд▓рд░ рд╕реНрдХреНрд░реАрди рджреНрд╡рд╛рд░рд╛ рд╡рд┐рд╕реНрдерд╛рдкрди рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИ (рд╡рд╣ рдорд╛рдорд▓рд╛ рдЬрдм рд╡рд┐рд╕реНрдерд╛рдкрди ViewConfiguration.get (getContext ()) рд╡рд┐рдзрд┐ рджреНрд╡рд╛рд░рд╛ рд▓реМрдЯрд╛рдП рдЧрдП рдорд╛рди рд╕реЗ рдЕрдзрд┐рдХ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред Get -caledTouchSlop ()), X рдФрд░ Y рдХреЗ рд╕рд╛рде рд╕реНрдХреНрд░реЙрд▓ рдорд╛рди рдХреА рдЧрдгрдирд╛ рдХреА рдЬрд╛рддреА рд╣реИ рдФрд░ рдЖрдВрджреЛрд▓рди рдХреА рджрд┐рд╢рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╣реЛрддреА рд╣реИред

  //   X final int deltaX = (int) (mLastMotionX - x); //   Y final int deltaY = (int) (mLastMotionY - y); mLastMotionX = x; mLastMotionY = y; //  View     final int scrollX = getScrollX(); final int scrollY = getScrollY(); //   ,     if (Math.abs(deltaX) > Math.abs(deltaY) && isMoveBegin) { isMoveBegin = false; isXMove = true; isYMove = false; } else if (Math.abs(deltaX) < Math.abs(deltaY) && isMoveBegin) { isMoveBegin = false; isXMove = false; isYMove = true; } //     if (isXMove) { if (deltaX < 0) { if (scrollX > 0) { scrollBy(Math.max(-scrollX, deltaX), 0); } } else if (deltaX > 0) { final int availableToScroll = getChildAt(getChildCount() / mRows -1).getRight() - scrollX - getWidth(); if (availableToScroll > 0) { scrollBy(Math.min(availableToScroll, deltaX), 0); } } } //     else if (isYMove) { if (deltaY < 0) { if (scrollY > 0) { scrollBy(0, Math.max(-scrollY, deltaY)); } } else if (deltaY > 0) { final int availableToScroll = getChildAt(getChildCount() - 1).getBottom() - scrollY - getHeight(); if (availableToScroll > 0) { scrollBy(0, Math.min(availableToScroll, deltaY)); } } } } break; 


рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рддреАрди рдЪрд░ isXMove, isYMove, isMoveBegin рдХреБрд▓реНрд╣рд╛рдбрд╝рд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдСрд░реНрдереЛрдЧреЛрдирд▓ рдЖрдВрджреЛрд▓рди рдХреЗ рд▓рд┐рдП рдкреЗрд╢ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред MotionEvent.ACTION_DOWN рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддреЗ рд╕рдордп рдЕрдВрддрд┐рдо рдореЗрдВ рд╕реЗ рдХреМрди рд╕рд╛ рд╕рддреНрдп рд╣реИред

рдЕрдЧрд▓рд╛, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрдИ рдЙрдкрдпреЛрдЧрд┐рддрд╛ рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реНрдХреНрд░реАрди рдХреЛ рд╕реНрдХреНрд░реЙрд▓ рдХрд░рдирд╛ред

MotionEvent.ACTION_UP рд╣реИрдВрдбрд▓рд░ рд╕реНрдХреНрд░реАрди рдХреА рд╕реНрдХреНрд░реЙрд▓рд┐рдВрдЧ рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдФрд░ рдХрд╛рд░реНрдпрд╢реАрд▓ рдЪрд░ рдХреЛ рд░реАрд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред рдпрджрд┐ рд╕реНрдХреНрд░реАрди рдЖрдзреЗ рд╕реЗ рдЕрдзрд┐рдХ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рд╣реЛ рдЧрдИ рд╣реИ, рддреЛ рдпрд╣ рдЕрдЧрд▓реА рд╕реНрдХреНрд░реАрди рддрдХ рд╕реНрдХреНрд░реЙрд▓ рдХрд░рддрд╛ рд╣реИ, рдЕрдиреНрдпрдерд╛ рдкреБрд░рд╛рдиреА рд╕реНрдХреНрд░реАрди рдЕрдкрдиреА рдореВрд▓ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд▓реМрдЯ рдЖрддреА рд╣реИред

рдореИрдВ рдЙрд╕ рдХреНрд╖рдг рдкрд░ рднреА рдзреНрдпрд╛рди рджреЗрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдЬрдм рдЖрдкрдХреЛ рдкрд╣рд▓реА рд╕реНрдХреНрд░реАрди рдкрд░ рдирд╣реАрдВ рдмрд▓реНрдХрд┐ рдХрдХреНрд╖рд╛ рдХреА рдПрдХ рдЖрд╡реГрддреНрддрд┐ рдмрдирд╛рддреЗ рд╕рдордп рдордирдорд╛рдиреЗ рдврдВрдЧ рд╕реЗ рдЪрд▓рдирд╛ рд╣реЛрдЧрд╛ред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛:
  public TwoDirectionsViewSwitcher(Context context, int rows, int currentScreen) { super(context); mCurrentScreen = currentScreen; mRows = rows; init(); } 

рдСрдирдорд╛рд░реНрдЯ рд╡рд┐рдзрд┐ рдореЗрдВ , рдкрд╣рд▓реЗ рдЦреЛрд▓рдиреЗ рдкрд░, рд╢реБрд░реВ рдореЗрдВ рд╕реЗрдЯ рдХреА рдЧрдИ рд╕реНрдерд┐рддрд┐ рд╕рдВрд╕рд╛рдзрд┐рдд рд╣реЛрддреА рд╣реИ:
  if (mFirstLayout) { int row = mCurrentScreen / (getChildCount() / mRows); int cell = mCurrentScreen % (getChildCount() / mRows); scrollTo(cell * width, row * height); mFirstLayout = false; } 

рдмреЗрд╢рдХ, рдпрд╣ рд╡рд░реНрдЧ рдкреВрд░реНрдг рд╣реЛрдиреЗ рдХрд╛ рджрд┐рдЦрд╛рд╡рд╛ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рдореЗрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕реНрдХреНрд░реАрди рд▓реЗрдЖрдЙрдЯ (рдЕрдм рдпрд╣ рд▓реИрдВрдбрд╕реНрдХреЗрдк рдореЛрдб рдореЗрдВ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ) рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╛рд░реНрдердХ рд╣реЛрдЧрд╛, рдкреНрд░рднрд╛рд╡ рдЬреЛрдбрд╝реЗрдВ, рд╕реНрдХреНрд░реАрди рдХреА рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛ рдФрд░ рд▓рд╛рдЗрдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреА рдмрд╣реБрд▓рддрд╛ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦреЗрдВ, рд▓реЗрдХрд┐рди рдЗрд╕ рд░реВрдк рдореЗрдВ рднреА рдпрд╣ рдкреНрд░рджрд░реНрд╢рди рдХрд░рддрд╛ рд╣реИ рд╡реЗ рдХрд╛рд░реНрдп рдЬрд┐рдирдХреЗ рд▓рд┐рдП рдореИрдВрдиреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕реЗ рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдпрд╛ рдерд╛ - рдЪрд╛рд░ рджрд┐рд╢рд╛рдУрдВ рдореЗрдВ рдЪрд▓рддреЗ рд╣реБрдПред

рдЙрдкрдпреЛрдЧ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдкреВрд░рд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЛрдб github TwoDirectionsViewSwitcher рдкрд░ рдкреНрд░рдХрд╛рд╢рд┐рдд рд╣реБрдЖ рд╣реИред

Source: https://habr.com/ru/post/In137339/


All Articles