Android рдореЗрдВ SlideStackView рдпрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рджреГрд╢реНрдп рд╕рдореВрд╣ (рднрд╛рдЧ 2)



рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рдореИрдВрдиреЗ Android рдХреЗ рд▓рд┐рдП Mail.Ru рдореЛрдмрд╛рдЗрд▓ рдореЗрд▓ рдореЗрдВ SlideStackView рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдореЗрдВ рдЕрдкрдиреЗ рдЕрдиреБрднрд╡ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХреА ред рддрдм рдореИрдВрдиреЗ рд╡рд╛рджрд╛ рдХрд┐рдпрд╛ рдХрд┐ рдирд┐рдХрдЯ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдореИрдВ рджреВрд╕рд░рд╛ рднрд╛рдЧ рддреИрдпрд╛рд░ рдХрд░реВрдВрдЧрд╛, рдЬрд┐рд╕рдореЗрдВ рдореИрдВ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реВрдВрдЧрд╛ рдХрд┐ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рд╡рд┐рдЬрд╝реБрдЕрд▓ рдШрдЯрдХреЛрдВ рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рднрд╛рдЧ рдХреЛ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПред рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ, рд╣рдо рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗ рдХрд┐ рдЖрд╡реЗрджрди рдореЗрдВ рдЕрдиреНрддрд░рдХреНрд░рд┐рдпрд╛рд╢реАрд▓рддрд╛ рдХреНрдпрд╛ рд╣реИ - рдПрдиреАрдореЗрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВред рд╣рд░ рдХреЛрдИ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рдЗрд╕ рддрдереНрдп рдХрд╛ рдЖрджреА рд╣реИ рдХрд┐ рдореЛрдмрд╛рдЗрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЗ рд▓рд┐рдП рдЙрддреНрддрд░рджрд╛рдпреА рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдЕрдкрдиреЗ рдЖрд╡реЗрджрди рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рдиреЗ рдХрд╛ рдореБрдЦреНрдп рддрд░реАрдХрд╛ рдЯрдЪ рд╕реНрдХреНрд░реАрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИред

рдЪреВрдВрдХрд┐ рд╣рдо рдПрдХ рдиреЗрд╡рд┐рдЧреЗрд╢рди рдХрдВрдЯреНрд░реЛрд▓рд░ - рд╕реНрд▓рд╛рдЗрдбрд╕реНрдЯреИрдХ рд╡реНрдпреВ рд▓рд┐рдЦ рд░рд╣реЗ рд╣реИрдВ - рд╣рдо рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдореБрдЦреНрдп рднрд╛рдЧреЛрдВ рдХреЗ рдмреАрдЪ рдПрдирд┐рдореЗрдЯреЗрдб рдмрджрд▓рд╛рд╡реЛрдВ рдХреЗ рд╕рд╛рде рдЕрдиреНрддрд░рдХреНрд░рд┐рдпрд╛рд╢реАрд▓рддрд╛ рдХреЛ рдЬреЛрдбрд╝реЗрдВрдЧреЗред Mail.Ru рдореЛрдмрд╛рдЗрд▓ рдореЗрд▓ рдореЗрдВ, рдпреЗ рддреАрди рдЯреБрдХрдбрд╝реЗ рд╣реИрдВ: рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдЬреЛрдбрд╝реЗ рдЧрдП рдЦрд╛рддреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА, рдЪрдпрдирд┐рдд рдореЗрд▓рдмреЙрдХреНрд╕ рдХреЗ рдЕрдВрджрд░ рдлрд╝реЛрд▓реНрдбрд░реЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА, рдФрд░ рдПрдХ рдлрд╝реЛрд▓реНрдбрд░ рдХреА рд╕рд╛рдордЧреНрд░реА рджрд┐рдЦрд╛рдиреЗ рд╡рд╛рд▓реЗ рдкрддреНрд░реЛрдВ рдХреА рдПрдХ рд╕реВрдЪреАред

рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рднрд╛рдЧ рдореЗрдВ рд▓рд┐рдЦрд╛ рд╣реИ, рдпрд╣ рд╕рдм рд╕реАрдЦрдиреЗ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рд╕реНрдереИрддрд┐рдХ рд╕реНрд▓рд╛рдЗрдб рдХреИрд╕реЗ рдХрд░реЗрдВ рдФрд░ рдЖрдХрд░реНрд╖рд┐рдд рдХрд░реЗрдВред рдЕрдЧрд▓рд╛ рдХрджрдо рдпрд╣ рд╣реИ рдХрд┐ рдЗрди рд╕реНрд▓рд╛рдЗрдбреЛрдВ рдХреЛ рдХреИрд╕реЗ рд╕реАрдЦрд╛ рдЬрд╛рдПред

рдореБрдЭреЗ рдпрдХреАрди рд╣реИ рдХрд┐ рдЕрдзрд┐рдХрд╛рдВрд╢ рдбреЗрд╡рд▓рдкрд░реНрд╕, рдЬрд┐рди рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдЙрдирдХреЗ рдлреНрд░реЗрдорд╡рд░реНрдХ рдореЗрдВ рдпрд╣ рдЖрдпрд╛ рд╣реИ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рдкрддрд╛ рд╣реИ рдХрд┐ Android рдлреНрд░реЗрдорд╡рд░реНрдХ рдореЗрдВ MotionEvents рдХреИрд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА, рдореИрдВ рд╢реБрд░реБрдЖрдд рд╕реЗ рд╣реА рд╢реБрд░реВ рдХрд░ рджреВрдВрдЧрд╛ред

рддреЛ, рдмреЗрд╕ рдХреНрд▓рд╛рд╕ рд╡реНрдпреВ рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ MotionEvents рдХреА рд╕рдВрднрд╛рд╡рд┐рдд рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧред рдФрд░ рдЗрд╕реА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЗ рдЬрд╡рд╛рдм рдореЗрдВ, рд╡рд┐рдЬреЗрдЯ рдЗрд╕ рдореЛрд╢рди рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдЯрдЪрд╕реНрдХреНрд░реАрди рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдЗрдВрдЯрд░реИрдХреНрдЯ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИред

рд╣рдорд╛рд░реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╣рдо рдХреЗрд╡рд▓ рдЙрди рдШрдЯрдирд╛рдУрдВ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ рдЬреЛ рд╕реНрд▓рд╛рдЗрдб рд╕реНрдЯреИрдХ рдХреЗ рдЕрдВрджрд░ рд╕реНрд▓рд╛рдЗрдб рдХреЛ рд╕реНрдХреНрд░реЙрд▓ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдВрдЧреЗред

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



рдЕрдВрддрд┐рдо рдкреИрд░рд╛рдЧреНрд░рд╛рдл рдХреЗ рд╕рд╛рде, рдпрд╣ рд╢рд╛рдпрдж рд╕рдмрд╕реЗ рдХрдард┐рди рд╣реЛрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдЕрдХреНрд╕рд░ рд╡рд╛рдВрдЫрд┐рдд рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рднреАрдбрд╝ рдореЗрдВ, рд╕рднреА рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рд╕рдордЭреМрддрд╛ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЕрдХреНрд╕рд░ рдЗрд╕реЗ "рдмрд╕ рдХрд╛рдо" рдмрдирд╛рддреЗ рд╣реИрдВ рдЕрдм рдиреЛрдЯ рдХреЗ рд╕рд╛рде "рдореИрдВ рдмрд╛рдж рдореЗрдВ рдмрджрд▓реВрдВрдЧрд╛, рдЬрдм рд╕рдордп рд╣реЛрдЧрд╛"ред рдореИрдВ рдпрд╣ рдирд╣реАрдВ рдХрд╣ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рдЧрд▓рдд рд╣реИ, рдореИрдВ рд╕рд┐рд░реНрдл рдЖрдкрдХреЛ рдЪреЗрддрд╛рд╡рдиреА рджреЗрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ рдХрд┐ рдЖрдк рдЗрд╕реЗ рдмрд╛рдж рдореЗрдВ рдпрд╛рдж рдХрд░реЗрдВрдЧреЗ, рдЬрдм рдХрд┐рд╕реА рдЪреАрдЬ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмрд╣реБрдд рджреЗрд░ рд╣реЛ рдЪреБрдХреА рд╣реИ рдпрд╛ рдЗрд╕рд╕реЗ рднреА рдмрджрддрд░, рдпрд╣ рдЕрд╕рдВрднрд╡ рд╣реИред

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

рддреЛ, рд╣рдорд╛рд░реЗ рдореЗрдврд╝реЗ рд╡рд╛рдкрд╕ред

рдкрд╣рд▓реА рдирдЬрд╝рд░ рдореЗрдВ, рд╕рдм рдХреБрдЫ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдХреЗрд╡рд▓ рдкрд╣рд▓реА рдирдЬрд╝рд░ рдореЗрдВ рд╣реИред рдпрджрд┐ рдЖрдкрдХреЛ рдкрд╣рд▓реЗ рд╕реНрдХреНрд░реЙрд▓рд┐рдВрдЧ рдХреЛ рд╕рдВрднрд╛рд▓рдирд╛ рдерд╛, рддреЛ рдЖрдк рд╢рд╛рдпрдж рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдореЛрд╢рдирдЗрд╡реЗрдиреНрдЯреНрд╕ рдореЗрдВ рд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдЕрд╕рд▓реА рдЗрд░рд╛рджреЗ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдирд╛ рдЗрддрдирд╛ рдЖрд╕рд╛рди рдирд╣реАрдВ рд╣реИред рдХреНрдпрд╛ рдЙрд╕рдиреЗ рд╕реНрд▓рд╛рдЗрдб рдХреЛ рд╕рд╛рдЗрдб рдореЗрдВ рд▓реЗ рдЬрд╛рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛, рдпрд╛ рдХреНрдпрд╛ рд╡рд╣ рдЙрд╕ рддрддреНрд╡ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рд╕реВрдЪреА рдХреЗ рдЕрдВрджрд░ рд╣реИ, рдЖрджрд┐ред рдЗрд╕ рд╕рднреА рддрд░реНрдХ рдХреЛ рд╕реНрд▓рд╛рдЗрдб рд╕реНрдЯреИрдХ рд╕реЗ рдЕрд▓рдЧ рд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╕рдВрдкреВрд░реНрдг рд╕реНрдХреНрд░реЙрд▓рд┐рдВрдЧ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЛ рдПрдХ рдЕрд▓рдЧ рд╕реНрд▓рд╛рдЗрдбрд╕реНрдЯреИрдХрдХреЙрд▓рд░ рдШрдЯрдХ рдореЗрдВ рдЕрд▓рдЧ рдХрд░рдирд╛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛрдЧрд╛ред

public static class SlideScroller extends Scroller implements OnTouchListener{ private final ScrollingListener mListener; private final GestureDetector mGestureDetector; public SlideScroller(Context context, ScrollingListener listener, OnGestureListener gestureListener) { super(context); this.mListener = listener; this.mGestureDetector = new GestureDetector(context, gestureListener); mGestureDetector.setIsLongpressEnabled(false); } } 


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

рдШреБрдордХреНрдХрдбрд╝ рдХреЛ рд╕реНтАНрд▓рд╛рдЗрдбрд╕реНтАНрдЯреИрдХ рдХреЛ рдПрдХ рдЗрдВрдЯрд░рдлреЗрд╕ рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдЬрд┐рд╕рдХреЗ рдорд╛рдзреНтАНрдпрдо рд╕реЗ рд╡рд╣ рд╕реНтАНрд▓рд╛рдЗрдбрд╕реНтАНрдЯреИрдХ, рдШрдЯрдирд╛рдУрдВ рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рдорд╣рддреНтАНрд╡рдкреВрд░реНрдг рдкрд░ рд░рд┐рдкреЛрд░реНрдЯ рдХрд░реЗрдЧрд╛:

  public interface ScrollingListener { void onScroll(int distance); void onStarted(); void onFinished(); void onJustify(); } 


рд╕реНрдХреНрд░реЙрд▓рд┐рдВрдЧ рд╢реБрд░реВ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ, рдЬрдм рд╕реНрд▓рд╛рдЗрдб рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдкрд┐рдХреНрд╕реЗрд▓ рд▓реЗ рдЬрд╛рддреА рд╣реИ, рддреЛ рд╕реНрдХреНрд░реЙрд▓рд┐рдВрдЧ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЬрд╛рддреА рд╣реИ рдФрд░ рд╣рдореЗрдВ рд╕реНрд▓рд╛рдЗрдб рдХреА рд╕реНрдерд┐рддрд┐ рд╕рдВрд░реЗрдЦрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдФрд░ рдпрд╣ рд╕реНрдХреНрд░реЙрд▓ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкреВрд░рд╛ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

рд╕реНрд▓рд╛рдЗрдб рд╕реНрдЯреИрдХ рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ, рдХреБрдЫ рднреА рд╕рд░рд▓ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рд╣рдо рдмрд╕ рд╕рднреА рд╕реНрдкрд░реНрд╢ рдШрдЯрдирд╛рдУрдВ рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рд╕реНрдХреЙрд▓рд░ рдХреЛ рд╕реМрдВрдкрддреЗ рд╣реИрдВ, рдФрд░ рд╡рд╣ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдПрдЧрд╛ рдХрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреНрдпрд╛ рд╣реБрдЖ рдФрд░ рдЖрд╡рд╢реНрдпрдХ рдХреЙрд▓рдмреИрдХ рдХрд╛ рдХрд╛рд░рдг рдмрдирддрд╛ рд╣реИред

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдкрдиреЗ рд╢рд╛рдпрдж рджреЗрдЦрд╛ рд╣реИ, рд╕рднреА рдкреНрд░рддрд┐рдирд┐рдзрд┐ android.view.View.OnTouchListener рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ onTouch (рджреЗрдЦреЗрдВ v, MotionEvent рдШрдЯрдирд╛) рд╡рд┐рдзрд┐ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╣реЛрддрд╛ рд╣реИред

  @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN:{ int pointerId = MotionEventCompat.findPointerIndex(event, mActivePointerId); if (pointerId == INVALID_POINTER_ID){ break; } mLastTouchX = MotionEventCompat.getX(event, pointerId); mJustifying = false; forceFinished(true); clearMessages(); break; } case MotionEvent.ACTION_MOVE:{ int pointerId = MotionEventCompat.findPointerIndex(event, mActivePointerId); if (pointerId == INVALID_POINTER_ID){ break; } // perform scrolling float x = MotionEventCompat.getX(event, pointerId); int distanceX = (int)(x - mLastTouchX); if (distanceX != 0) { mTouchScrolling = true; startScrolling(); mListener.onScroll(-distanceX); mLastTouchX = x; } break; } case MotionEvent.ACTION_UP: mTouchScrolling = false; mActivePointerId = INVALID_POINTER_ID; break; } if ((!mGestureDetector.onTouchEvent(event) || ((SlideStackView)v).isOverScrolled()) && (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL)){ justify(); } return true; } 


рдЖрдЗрдП рдЬрд╛рдиреЗ рдХреНрд░рдо рдореЗрдВ:



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

  if ((!mGestureDetector.onTouchEvent(event) || ((SlideStackView)v).isOverScrolled()) && (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL)){ justify(); } 


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

рдирддреАрдЬрддрди, рдЕрдЧрд░ рдлрд╝реНрд▓рд┐рдВрдЧ рдкреВрд░реА рд╣реЛ рдЬрд╛рддреА рд╣реИ, рддреЛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд╕рдм рдХреБрдЫ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЬрд╛рдПрдЧрд╛ (рдпрд╛ рд╢реБрд░реВ рдХрд░реЗрдВ, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдкрд╕рдВрдж рдХрд░рддреЗ рд╣реИрдВ) рдСрдирдлреНрд▓рд┐рдВрдЧ рд╡рд┐рдзрд┐ (MotionEvent e1, MotionEvent e2, рдлреНрд▓реЛрдЯ рд╡реЗрд▓реЛрд╕рд┐рдЯреАрдПрдХреНрд╕, рдлреНрд▓реЛрдЯ рд╡реЗрд▓реЛрд╕рд┐рдЯреА) рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ:

  @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (mScroller.isTouchScrolling()){ LOG.w("mTouchScrolling in fling"); } SlideInfo slide = getSlideInfo(mSelected); int dx = getAdjustedTargetX(velocityX) - slide.mOffset; mScroller.fling(-(int)getVelocity(dx)); return true; } 


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

рдЕрдЧрд░ рд╣рдореЗрдВ рдкрд╣рд▓реЗ рд╣реА рджрд┐рдпрд╛ рдЬрд╛ рдЪреБрдХрд╛ рд╣реИ рддреЛ рдЧрддрд┐ рдХреНрдпреЛрдВ рд▓реЗрдВ? рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдЧрддрд┐ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╣реЛ рд╕рдХрддреА рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдпрд╣ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдХрд┐рд╕реА рднреА рдмрд┐рдВрджреБ рдкрд░ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдмрд┐рдВрджреБ рдкрд░ рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдЗрд╕ рдмрд┐рдВрджреБ рдХреА рдЧрдгрдирд╛ getAdjustedTargetX () рд╡рд┐рдзрд┐ рдореЗрдВ рдХреА рдЬрд╛рддреА рд╣реИ:

  /** * Defines target x coordinate of the slide. * It depends on fling direction * <p> * In case right fling it is calculated like this * <pre> * * getLeftEdge() getRightEdge() targetX * _|___________________________|______________________|__ * | | |rightOverScrollInFling| | * | _ _ _ _ _ _ _ _ _ _ _ _ _ _ <--------------------> | * | | | | | * | | * | | | | | * | mSelectedSlide | * | | | | | * | | * | |_ _ _ _ _ _ _ _ _ _ _ _ _ _| | | * | SlideStackView | * |_|___________________________|______________________|__| * </pre> * <p> * In case left fling it is calculated like this * <pre> * 0 * ________________________|_____________________________ * | |leftOverScrollInFling | | * | <--------------------> _ _ _ _ _ _ _ _ _ _ _ _ _ _ | * | | | | | * | | * | | | | | * | mSelectedSlide | * | | | | | * | | * | | |_ _ _ _ _ _ _ _ _ _ _ _ _ _| | * | SlideStackView | * |_|______________________|_____________________________| * </pre> * * @param velocityX velocity that defines direction of the fling * @return delta x in pixels that slide needs to scolled by * @see SlideStackView#getLeftEdge(int) * @see SlideStackView#getRightEdge(int) * @see SlideStackView#mRightOverScrollInFling * @see SlideStackView#mLeftOverScrollInFling */ private int getAdjustedTargetX(float velocityX) { int result = 0; if (velocityX > 0){ result = getRightEdge(mSelected) - getLeftEdge(mSelected) + mRightOverScrollInFling; // LOG.v("onFling " + targetX); } else { // relative to layout position of the slide result = 0 - mLeftOverScrollInFling; } return result; } 


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

рдПрдВрдбреНрд░реЙрдЗрдб рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдкрд░, рдПрдХ рд╕реНрдХреЙрд▓рд░ рдШреБрдордиреЗ рдХреЗ рджреМрд░рд╛рди рдХрд┐рд╕реА рддрддреНрд╡ рдХреЗ рдХреАрдиреЗрдореЗрдЯрд┐рдХреНрд╕ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрддрд╛ рд╣реИред рдПрдХ рдореЙрдбрд▓ рдХреЗ рд░реВрдк рдореЗрдВ, Google рдХреЗ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдиреЗ рд╕реНрдХреВрд▓ рд╕реЗ рдЬреНрдЮрд╛рдд рд╕рдорд╛рди рд░реВрдк рд╕реЗ рддреНрд╡рд░рд┐рдд рдЧрддрд┐ рдХрд╛ рд╕реВрддреНрд░ рд▓рд┐рдпрд╛: S = V 0 * t- (g * t 2 ) / 2ред рд╣рдо рдЖрдВрджреЛрд▓рди рдХреА рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЧрддрд┐ рдЬрд╛рдирддреЗ рд╣реИрдВ, рд╣рдо рдЖрдВрджреЛрд▓рди рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ рд╕рдордп рдХреЛ рдорд╛рдк рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╣ рдХреЗрд╡рд▓ рдЙрд╕ рддреНрд╡рд░рдг рдХреЛ рдЪреБрдирдиреЗ рдХреЗ рд▓рд┐рдП рд░рд╣рддрд╛ рд╣реИ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рд╕реНрд▓рд╛рдЗрдб рдмрдВрдж рд╣реЛ рдЬрд╛рдПрдЧреАред

рдбреЗрд╡рд▓рдкрд░реНрд╕ рдиреЗ рдЕрдиреБрдорд╛рди рдирд╣реАрдВ рд▓рдЧрд╛рдпрд╛ рдФрд░ рдПрдХ рдЖрдзрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдореБрдХреНрдд рдЧрд┐рд░рд╛рд╡рдЯ рдХреЗ рддреНрд╡рд░рдг рдХреЛ рд▓рд┐рдпрд╛:

  mDefaultDeceleration = SensorManager.GRAVITY_EARTH // g (m/s^2) * 39.37f // inch/meter * ppi // pixels per inch * ViewConfiguration.getScrollFriction() * 10.0f; 


рдпрджрд┐ рд╣рдо рдЙрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕реЗ рд╡рд┐рдЪрд▓рд┐рдд рд╣реЛрддреЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ рд╣рдордиреЗ рд░реЛрдХ рджрд┐рдпрд╛ рдерд╛, рддреЛ рд╣рдо 4 рд╕рдВрднрд╛рд╡рд┐рдд рдкрд░рд┐рджреГрд╢реНрдпреЛрдВ рдХреЛ рдЕрд▓рдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЧрддрд┐ рдХреЗ рд╕рд╛рде рдмрд╣рдиреЗ рдХреЗ рджреМрд░рд╛рди рд╣реЛрдВрдЧреЗред

рдЦреБрд▓реЗ рдФрд░ рдмрдВрдж рд╕реНрд▓рд╛рдЗрдб рдХреА рд╕реНрдерд┐рддрд┐ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ:





рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдо рд╢реБрд░реБрдЖрддреА рд╕реНрдерд┐рддрд┐ рд╕реЗ рдПрдХ рдлреНрд▓рд┐рдВрдЧ рдХрд░рддреЗ рд╣реИрдВред рдЙрд▓реНрд▓рд┐рдЦрд┐рдд 4 рд╕рдВрднрд╛рд╡рд┐рдд рд╡рд┐рдХрд▓реНрдк рдмрд╛рдИрдВ рдУрд░ (1 рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ) рдФрд░ рджрд╛рдпреАрдВ рдУрд░ (2 рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ) рд╕реНрд▓рд╛рдЗрдб рдкрджреЛрдВ рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рджреВрд░реА рддрдп рдХрд░рдХреЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рдорд╛рди рд▓реЗрдВ рдХрд┐ рдЗрди рдкрджреЛрдВ рдХреЗ рдмреАрдЪ рдХреА рджреВрд░реА рдПрд╕ рдПрди



рдПрд╕ <рдПрд╕ рдПрди / 2

рдпрд╣ рд╕реНрдерд┐рддрд┐ рдЗрдВрдЧрд┐рдд рдХрд░рддреА рд╣реИ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдлрд╝реНрд▓рд┐рдВрдЧ, рддрддреНрд╡ рдХреЛ рдПрдХ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЧрддрд┐ рджреЗрддрд╛ рд╣реИ, рдЬреЛ рддрддреНрд╡ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╡рд╣ рдЖрдзреА рджреВрд░реА рдХреЛ рдЕрдВрддрд┐рдо рд╕реНрдерд┐рддрд┐ рддрдХ рдкрд╛рд░ рдХрд░ рд╕рдХреЗред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдкреНрд░рд╛рдХреГрддрд┐рдХ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдЙрд╕ рдЧрддрд┐ рд╕реЗ рдкреНрд░рд╡рд╛рд╣ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдиреЗ рддрддреНрд╡ рджрд┐рдпрд╛ рдерд╛, рдФрд░, рддрддреНрд╡ рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдЗрдВрддрдЬрд╛рд░ рдХрд░ рд░рд╣рд╛ рд╣реИ, рдЗрд╕реЗ рдЕрдкрдиреА рдореВрд▓ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд▓реМрдЯрд╛рдПрдВ, рдЕрд░реНрдерд╛рддред рд╕рдмрд╕реЗ рдмрд╛рдИрдВ рд╕реНрдерд┐рддрд┐ред



рдПрд╕ рдПрди / 2 <рдПрд╕ <рдПрд╕ рдПрди

рдпрд╣рд╛рдВ, рддрддреНрд╡ рдХрд╛ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╡реЗрдЧ рд▓рдХреНрд╖реНрдп рдХреА рдЖрдзреА рджреВрд░реА рдкрд░ рдХрд╛рдмреВ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдерд╛, рд▓реЗрдХрд┐рди рдЕрдВрддрд┐рдо рдмрд┐рдВрджреБ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрд░реНрдпрд╛рдкреНрдд рдерд╛ред рдЗрд╕рд▓рд┐рдП, рдЗрд╕ рдкрд░рд┐рджреГрд╢реНрдп рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реБрдП, рдЖрдк рддрддреНрд╡ рдХреЛ рдереЛрдбрд╝реА рдЕрдзрд┐рдХ рдЧрддрд┐ рджреЗ рд╕рдХрддреЗ рд╣реИрдВ - рдЬреИрд╕реЗ рдХрд┐ рдпрд╣ рдЧрдВрддрд╡реНрдп рдкрд░ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред рдЗрд╕рдХреЗ рд▓рд┐рдП, рд╕рдорд╛рди рд░реВрдк рд╕реЗ рддреНрд╡рд░рд┐рдд рдЧрддрд┐ рдХреЗ рднреМрддрд┐рдХреА рдХреЛ рдпрд╛рдж рдХрд░рдиреЗ рдХреЗ рд▓рд╛рдпрдХ рд╣реИ, рдФрд░, рддреНрд╡рд░рдг рдФрд░ рдкрд░рд┐рдгрд╛рдореА рджреВрд░реА рдХреЛ рдЬрд╛рдирдиреЗ рдХреЗ рд╕рд╛рде, рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЧрддрд┐ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдлреНрд▓рд┐рдВрдЧ рдХрд░реЗрдВред

S n <S <S n + рдУрд╡рд░рдХреНрд░реЛрд▓

рдЗрд╕ рдкрд░рд┐рдгрд╛рдо рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдиреЗ рддрддреНрд╡ рдХреЛ рдкрд░реНрдпрд╛рдкреНрдд рдЙрдЪреНрдЪ рдЧрддрд┐ рджреА рд╣реИ, рдЬрд┐рд╕ рдкрд░ рд╡рд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рд╣реА рдмрд┐рдВрджреБ рд╕реЗ рдкрд░реЗ рдЖрдВрджреЛрд▓рди рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░ рджреЗрдЧрд╛, рд▓реЗрдХрд┐рди рдЕрдзрд┐рдХрддрдо рд╕реНрд╡реАрдХрд╛рд░реНрдп рд╕реНрдХрд┐рдб рддрдХ рдирд╣реАрдВ рдкрд╣реБрдВрдЪреЗрдЧрд╛ред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕рдм рдХреБрдЫ рдареАрдХ рдЙрд╕реА рддрд░рд╣ рд╣реЛрдЧрд╛ рдЬреИрд╕реЗ рд╣рдо рдЗрд╕реЗ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЕрд░реНрдерд╛рддреН: рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдпрд╣ рджреЗрдЦреЗрдЧрд╛ рдХрд┐ рддрддреНрд╡ рдЬреИрд╕реЗ рдХрд┐ рд╡рд┐рджреЗрд╢ рдореЗрдВ рдЪрд▓рд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рдпрд╣ рд╕рдВрд░реЗрдЦрд┐рдд рд╣реЛрдЧрд╛ рдФрд░ рдЪрд░рдо рд╕рд╣реА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧрд╛ред

рдПрд╕> рдПрд╕ рдПрди + рдУрд╡рд░рдХреНрд░реЛрд▓

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

рдпрджрд┐ рд╣рдо рджреВрд╕рд░реА рджрд┐рд╢рд╛ рдореЗрдВ рдлрд┐рдВрдЧрд░реНрд╕ рдХреЛ рдбрд┐рд╕рд╛рдЗрдб рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рд╕рднреА рд╕рдорд╛рди рдорд╛рдорд▓реЛрдВ рдХреЛ рджреЗрдЦреЗрдВрдЧреЗ, рд╕рд┐рд╡рд╛рдп рдЗрд╕рдХреЗ рдХрд┐ рд░реЗрдлрд░реЗрдВрд╕ рдбрд┐рд╕реНрдЯреЗрдВрд╕ рдХреЛ рдереЛрдбрд╝рд╛ рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рдХреИрд▓рдХреБрд▓реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рддреЛ, рдХреИрд╕реЗ рд╕рдВрднрд╛рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдо рдкрддрд╛ рд▓рдЧрд╛рдпрд╛ рд╣реИред рдЕрдм рд╣рдореЗрдВ рдпрд╣ рддрдп рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рддрд░рд╣ рдХреЗ рдЖрдВрджреЛрд▓рди рдХреЗ рджреМрд░рд╛рди рдПрдиреАрдореЗрд╢рди рдХреИрд╕реЗ рдмрдирд╛рдпрд╛ рдЬрд╛рдПред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрд╕ рд╡рд┐рдзрд┐ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:

  public void fling(int velocity){ mLastX = 0; final int maxX = 0x7FFFFFFF; final int minX = -maxX; fling(mLastX, 0, velocity, 0, minX, maxX, 0, 0); setNextMessage(MSG_SCROLL); } 


рдпрд╣ рд╡рд┐рдзрд┐ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдХреНрд╖реИрддрд┐рдЬ рдлрд╝реНрд▓рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдФрд░ рд╢реБрд░реВ рдФрд░ рдЕрдВрдд рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рдирд╣реАрдВ рд░рдЦрддреА рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдХреЗрд╡рд▓ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕реНрдерд┐рддрд┐ рдХреЛ рдпрд╛рдж рдХрд░рддреЗ рд╣реИрдВ, рдЕрдзрд┐рдХрддрдо рд╕рдВрднрд╡ рд╕реАрдорд╛рдПрдВ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рд╡рд╛рд░рд┐рд╕ рд╡рд░реНрдЧ рдореЗрдВ рдЦреБрдж рдХреЛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЦреБрдж рдХреЛ рдПрдХ рд╕рдВрджреЗрд╢ рднреЗрдЬрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдореЗрдВ рд╕реНрдХреНрд░реЙрд▓ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

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

  private final Handler mAnimationHandler = new AnimationHandler(); private void setNextMessage(int message) { clearMessages(); mAnimationHandler.sendEmptyMessage(message); } private void clearMessages() { mAnimationHandler.removeMessages(MSG_SCROLL); mAnimationHandler.removeMessages(MSG_JUSTIFY); } 


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

  private final class AnimationHandler extends Handler { @Override public void handleMessage(Message msg) { computeScrollOffset(); int currX = getCurrX(); int delta = mLastX - currX; mLastX = currX; if (delta != 0) { mListener.onScroll(-delta); } тАж } } 


рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ: рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдЗрд╕ рд╕рдВрджреЗрд╢ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреНрд╖рдг рдореЗрдВ рдПрдиреАрдореЗрд╢рди рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдХреЛрд░рд░ рд╕реЗ рдкреВрдЫрддреЗ рд╣реИрдВред рдлрд┐рд░ рд╣рдо рдирдИ рд╕реНрдерд┐рддрд┐ рдФрд░ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЬреНрдЮрд╛рдд рдЕрдВрддрд┐рдо рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВред рдЕрдВрдд рдореЗрдВ, рд╣рдо рд╕реНрд▓рд╛рдЗрдбрд╢реИрдХ рдХреЛ рд╕реВрдЪрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╕реНрдХреНрд░реЙрд▓ рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИред рдареАрдХ рд╡реИрд╕реЗ рд╣реА рдЬреИрд╕реЗ рд╣рдордиреЗ onTouchEvent () рдореЗрдердб рдХреА рдмреЙрдбреА рд╕реЗ рдХрд┐рдпрд╛ рдерд╛ред

рдЕрдм рдпрд╣ рдЫреЛрдЯреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИ - рдЗрди рд╕рдВрджреЗрд╢реЛрдВ рдХреЗ рдЬрд╡рд╛рдм рдореЗрдВ рдЖрдкрдХреЛ рд╕реНрдХреНрд░реАрди рдкрд░ рд╕реНрд▓рд╛рдЗрдб рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛ред рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдмрд┐рдВрджреБ onScroll () рд╡рд┐рдзрд┐ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реЛрдЧрд╛:

  @Override public void onScroll(int distance) { if (distance == 0){ return; } // LOG.d("onScroll " + distance); doScroll(distance); } 


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

  /** * Performs actual scrolling. Moves the views according * to the current selected slide number and distance * passed to the method. After the scrolling has been * performed method {@link #onScrollPerformed()} will be * called where you can apply some visual effects. * @param distance scroll distance */ private void doScroll(int distance) { adjustScrollDistance(distance); // LOG.d("scroll delta " + mScrollDelta); View selected = getChild(getSelectedViewIndex()); scrollChildBy(selected, mScrollDelta); notifyScrollPerformed(); onScrollPerformed(); fillViewsIn(); if (!mDirty.isEmpty()){ invalidate(mDirty.left, mDirty.top, mDirty.right, mDirty.bottom); mDirty.setEmpty(); } } 


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

рдЕрдм рд╕реВрдЪреАрдмрджреНрдз рддрд░реАрдХреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛ рдФрд░ рдЕрдзрд┐рдХ:

  /** * Moves the specified child by some amount of pixels * @param child child to move * @param scrollDelta scrolling delta */ private void scrollChildBy(View child, int scrollDelta) { SlideInfo info = getSlideInfo(child); // LOG.d("apply scroll " + info.mPosition + " delta " + scrollDelta); Rect childDirty = getChildRectWithShadow(child); info.mOffset -= scrollDelta; child.offsetLeftAndRight(-scrollDelta); childDirty.union(getChildRectWithShadow(child)); mDirty.union(childDirty); // LOG.d("apply scroll " + info.mPosition + " newoff " + info.mOffset); } 


рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рд╣реА рд▓реЗрдЦ рдХреЗ рдкрд╣рд▓реЗ рднрд╛рдЧ рдореЗрдВ рдХрд╣рд╛ рдерд╛, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ mDirty рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдХрдИ рдЕрд╕реНрдерд╛рдпреА рдСрдмреНрдЬреЗрдХреНрдЯ рдирд╣реАрдВ рдмрдирд╛рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдПрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рдореЗрдореЛрд░реА рдХреЗ рддрд░реНрдХрд╕рдВрдЧрдд рдЙрдкрдпреЛрдЧ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рдбреАрдмрдЧрд┐рдВрдЧ рдХреЛ рд╕рд░рд▓ рдХрд░рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдХреЗрд╡рд▓ рдПрдХ рд╡рд╕реНрддреБ рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ, рдЗрд╕рдХреЗ рдкрд░рд┐рд╡рд░реНрддрди рдФрд░ рдЙрд╕ рддрдХ рдкрд╣реБрдВрдЪред рдпрд╣ рдЗрд╕ рд╕рдВрднрд╛рд╡рдирд╛ рдХреЛ рдмрд╣реБрдд рдХрдо рдХрд░ рджреЗрддрд╛ рд╣реИ рдХрд┐ рддреНрд░реБрдЯрд┐ рдХрд┐рд╕реА рдХрд╛ рдзреНрдпрд╛рди рдирд╣реАрдВ рдЬрд╛рдПрдЧреАред

  /** * Notifies scroll listeners about selected slide has been scrolled. * Do nothing if there is no scroll listener was set earlier. */ private void notifyScrollPerformed() { if (mScrollListener != null){ final float p = getSlidePositionInBounds(mSelected); // LOG.v("notifyScrollPerformed " + mSelected + ", " + p); mScrollListener.onSlideScrolled(mSelected, p); } } /** * Calculates position for the specified slide relative to it's * scrollable bounds. * <p> * <b>Note:</b> Slide position coulld be <code>< 0.0f</code> and * <code> > 1.0f * @param slidePosition * @return */ private float getSlidePositionInBounds(int slidePosition) { SlideInfo info = getSlideInfo(slidePosition); int offset = info.mOffset; int scrollBounds = getWidth() - getRightEdgeDelta(info.mPosition) - getLeftEdge(info.mPosition); float p = ((float) offset) / scrollBounds; return p; } 


рдЕрдХреНрд╕рд░, рдЬрдм рдЖрдк рдПрдХ рдШрдЯрдХ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдпрд╣ рд╕реЛрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдХреБрдЫ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЖрдкрдХреЗ рдШрдЯрдХ рдХреЗ рдЕрдВрджрд░ рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдШрдЯрдирд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рдХреИрд╕реЗ рдЙрдкрдпреЛрдЧреА рдкрд╛рдПрдВрдЧреЗред рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдордд рднреВрд▓рдирд╛ рдФрд░, рдпрджрд┐ рд╕рдВрднрд╡ рд╣реЛ рддреЛ, рдЕрдкрдиреЗ рд╡рд░реНрдЧ рдХреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд╕рд╛рде рдкреНрд░рджрд╛рди рдХрд░реЗрдВ, рдЬрд┐рд╕рдХреЗ рдЙрдкрдпреЛрдЧ рд╕реЗ рд╡реЗ рдЕрдВрджрд░ рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИ, рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЙрдЪреНрдЪ-рд╕реНрддрд░реАрдп рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпреЗ рд╕реНрд▓рд╛рдЗрдб рд╕реНрдЯреИрдХ рд╕реНрдХреНрд░реЙрд▓ рдХрд░рдиреЗ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рджреЛ рдореБрдЦреНрдп рдШрдЯрдирд╛рдПрдВ рд╣реИрдВред рдШрдЯрдирд╛рдПрдВ рдХрд╛рдлреА рд╕реНрдкрд╖реНрдЯ рд╣реИрдВ, рдЕрд░реНрдерд╛рддреН:
рдПрдХ рдШрдЯрдирд╛ рдЬреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд╕реВрдЪрд┐рдд рдХрд░рддреА рд╣реИ рдХрд┐ рд╡рд░реНрддрдорд╛рди рд╕реНрд▓рд╛рдЗрдб рд╕реНрд▓рд╛рдЗрдб рд╕реНрдЯреИрдХ рдХреЗ рдЕрдВрджрд░ рдмрджрд▓ рдЧрдИ рд╣реИ, рдФрд░ рдпрд╣ рдзреНрдпрд╛рди рд░рдЦрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдпрд╣ рдШрдЯрдирд╛ рдЙрд╕ рд╕рдордп рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ рдЬрдм рд╕реНрд▓рд╛рдЗрдб рдиреЗрддреНрд░рд╣реАрди рд░реВрдк рд╕реЗ рд╕рдХреНрд░рд┐рдп рд╣реЛ рдЧрдИ рд╣реИ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдЙрд╕ рд╕рдордп рдЬрдм рд╕реНрдХреНрд░реЙрд▓ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИред
рдПрдХ рдШрдЯрдирд╛ рдЬреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд╕реВрдЪрд┐рдд рдХрд░рддреА рд╣реИ рдХрд┐ рд╕реНрд▓рд╛рдЗрдб рдХреА рд╕реНрдерд┐рддрд┐ рдЗрд╕рдХреА рдореВрд▓ рд╕реАрдорд╛рдУрдВ рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рдмрджрд▓ рдЧрдИ рд╣реИред рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕рд╛рдкреЗрдХреНрд╖ рд╕реНрдерд┐рддрд┐ рд╕реАрдорд╛рдУрдВ рд╕реЗ рдкрд░реЗ рдЬрд╛ рд╕рдХрддреА рд╣реИ [0, 1], рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рдмрд╣реБрдд "рдмрд╣рд╛рд╡" рд╣реЛрдЧрд╛, рдЬрд┐рд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдореИрдВ рдФрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдмрд╛рдд рдХрд░реВрдВрдЧрд╛ред

  /** * Listener interface that informs about slide scrolling * related events such as current selected slide has changed, * or current selected slide scroll position has changed. * @author k.kharkov */ public interface OnSlideScrollListener{ /** * Called when the current selected position for slide * has changed. Usually it happen after scrolling finished. * @param selectedSlide */ void onSlideChanged(int selectedSlide); /** * Informs about changing scroll position of the slide. * @param position current selected slide position * @param p position of the slide inside it's scroll * bounds. 0.0f at left edge, 1.0f at right edge. If * <code>p < 0.0f || p > 1.0f</code> the slide is over * scrolled to left or to the right. */ void onSlideScrolled(int position, float p); } 


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

  /** * Retrieves slide's left edge coordinate in opened state * relative to parent. * @param position slide number in adapter's data set * @return coordinate of the slide's left in opened state */ private int getLeftEdge(int position){ return mAdapter == null ? 0 :mAdapter.getSlideOffset(position); } 


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

@Mail.Ru , , . - , , - :

  /** * Retrieves coordinate of the slide's left edge in closed state * relative to parent. * @param position slide number in adapter's data set * @return coordinate of slide's left in closed state. */ private int getRightEdge(int position) { int rightEdge = getRight() - getRightEdgeDelta(position); return rightEdge; } /** * Just calculates delta between child's right edge and * parent's right edge * @param position position of the child (in adapter's * data set indexes) * @return delta in pixels */ private int getRightEdgeDelta(int position){ if (position < 0){ return 0; } int delta = mSlideInvisibleOffsetFirst + mSlideInvisibleOffset * position; return delta; } 


, , . , . . , - , , .

2 : onScrollPerformed(), adjustScrollDistance().

, - . , , , - . , -, . , , , . , . , - .

bouncing effect. , -, . , , Android- , iOS. , . look&feel. , , , iOS , . , . , , ,
, , - , .

, : , . -. adjustScrollDistance():

  /** * Processes scroll distance according to the current scroll * state of the slide stack view. Takes into account * over scrolling, justifying. * @param distance desired distance to scroll. */ private void adjustScrollDistance(int distance) { mScrollDelta = distance; if (mScroller.isJustifying()){ processNonOverScroll(distance); } else if (mScrollDelta < 0 && isRightOverScrolled()){ processOverScroll(distance); } else if (mScrollDelta > 0 && isLeftOverScrolled()){ processOverScroll(distance); } else { processNonOverScroll(distance); } } 


SlideStackView, , , , , , . , , .

. , :

  /** * @return <code>true</code> if slide stack over scrolled * to the right. <code>false</code> otherwise */ private boolean isRightOverScrolled(){ /** * info.mOffset - it is * the latest position of the slide's left side * so if it is over scrolled - return true * _________________ * | _____________|_ * | |lastSlide | | * |<->| | | * | | | | * | |_____________|_| * |_________________| * SlideStack */ SlideInfo info = getSlideInfo(getSelectedViewIndex()); if (mSelected == mFirst + getChildCount() - 1){ if (info.mOffset > getLeftEdge(info.mPosition)){ return true; } } /** * getRightEdge() - it is left bound of the slide * when it is hidden * ___________|______ * | | __|____________ * | | | |anySlide | * | |<->| | | * | | | | | * | | |__|____________| * |___________|______| * SlideStack */ int left = info.mOffset + getLeftEdge(mSelected); if (left > getRightEdge(mSelected)){ return true; } return false; } 


, , :



  /** * @return <code>true</code> if the slide stack view is * over scrolled to the left. <code>false</code> otherwise. */ private boolean isLeftOverScrolled(){ View selected = getChild(getSelectedViewIndex()); SlideInfo info = getSlideInfo(selected); return selected.getRight() + info.mOffset < getRightEdge(mSelected - 1); } 


, . , , , () . , , (. getRightEdge()).

, , :

  /** * Changes actual scroll delta in case over scroll. * Depends on whether we in fling mode or not. * @param distance */ private void processOverScroll(int distance) { // LOG.d("process overscroll " + distance); //process over scroll while in fling mode; if (!mScroller.isTouchScrolling()){ mScroller.setDecelerationFactor(mDecelerationFactor); } else{ // or just slow down while touch scrolling mOverScrollOffset += distance; int nOffsetAbsolute = (int) (mOverScrollOffset / mOverScrollFactor); int oldOffsetAbsolute = mLastOverScrollOffset; int scrollDelta = nOffsetAbsolute - oldOffsetAbsolute; mLastOverScrollOffset += scrollDelta; mScrollDelta = scrollDelta; } } 


, touchScrolling, , - . , : - , . , . , mOverscrollFactor . . , , . , overscroll factor = 5, , distance = 1. . . , , . , . , 5 , , , 1 . , , .
mOverScrollOffset тАФ , . mLastOverScrollOffset тАФ , . , , .

: , , mOverScrollOffset mLastOverScrollOffset. , ( ), . , . :

  /** * We need assume that actual scroll delta is distance parameter, * we need adjust {@link #mLastOverScroll} if we will not go out * from over scroll mode and over scroll again. * @param distance raw distance passed from the scroller. */ private void processNonOverScroll(int distance) { mScrollDelta = distance; if (isOverScrolled()){ mLastOverScrollOffset += distance; mOverScrollOffset = (int) (mLastOverScrollOffset * mOverScrollFactor); } else { mLastOverScrollOffset = 0; mOverScrollOffset = 0; } } 


: mOverScrollOffset mLastOverScrollOffset , , , , . тАФ .

: , .

, . , ( ) . , , , , Scroller. , :

S=V 0 *t-(g*t 2 )/2 ( )

, , . 3 :

S=V 0 *t-(g*t 2 )/2

,

S2=V k *t2- ((g*p)*уАЦt2уАЧ 2 )/2

, , p .

S3=V k2 *t3- ((g*p*p)*уАЦt3уАЧ 2 )/2

: , .
, .

mScroller.setDecelerationFactor(mDecelerationFactor);

, . , , :

  /** * Adjusts the current deceleration to slow down more or less. * @param factor if > 1.0 the scroller will slow down more. * if factor < 1.0 the scroller will slow down less. */ public void setDecelerationFactor(float factor){ mVelocity = mVelocity - mDeceleration * mPassed / 1000.0f; float velocity = mVelocity; mDeceleration *= factor; mDuration = (int) (1000.0f * mVelocity / mDeceleration); int startX = mStartX = mCurrX; int startY = mStartY = mCurrY; int totalDistance = (int) ((velocity * velocity) / (2.0f * mDeceleration)); mFinalX = startX + Math.round(totalDistance * mCoeffX); // Pin to mMinX <= mFinalX <= mMaxX mFinalX = Math.min(mFinalX, mMaxX); mFinalX = Math.max(mFinalX, mMinX); mFinalY = startY + Math.round(totalDistance * mCoeffY); // Pin to mMinY <= mFinalY <= mMaxY mFinalY = Math.min(mFinalY, mMaxY); mFinalY = Math.max(mFinalY, mMinY); mStartTime += mPassed; } 


, , , , hide :

  /** * @hide * Returns the current velocity. * * @return The original velocity less the deceleration. Result may be * negative. */ public float getCurrVelocity() { return mVelocity - mDeceleration * timePassed() / 2000.0f; } 


, v(t)=v 0 +at (1000 тАФ ). - , , .

, event' , . , . , , , . Android Framework , . , . , ViewGroup.dispatchTouchEvent().

. , , . , , :



, , View .

, , . , . , event' , : .

. :

  /** * Determines whether the user tries to scroll the slide stack view * or just tries to scroll some scrollable content inside the slide. * <p> * {@inheritDoc} */ @Override public boolean onInterceptTouchEvent(MotionEvent ev) { 


, , , \\ .
, :

  final int action = MotionEventCompat.getActionMasked(ev); if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP){ /* * That means we need to abort all scrolling and return to nearest * stable position in the slide stack. So justify position. */ mBeingDrag = false; mUnableToDrag = false; mScroller.justify(); // LOG.v("OnInterceptTouchEvent: action cancel | up"); return false; } /* * In case we have already determined whether we need this * touch event or not - just return immediately */ if (action != MotionEvent.ACTION_DOWN){ if (mBeingDrag){ // LOG.v("OnInterceptTouchEvent: already dragging"); return true; } if (mUnableToDrag){ // LOG.v("OnInterceptTouchEvent: already unable to drag"); return false; } } 


(, MotionEvent), event' , .

, , , event .

  switch (action){ case MotionEvent.ACTION_DOWN:{ /* * remember the start coordinates for the motion event * in order to determine drag event length */ mInitialX = ev.getX(); mInitialY = ev.getY(); mActivePointerId = MotionEventCompat.getPointerId(ev, 0); /* * pass down event to the scroller after we have decided to intercept, * not here. It helps to start calculation motion event in case we * decide to intercept it. */ mScroller.setActivePointer(mActivePointerId); if (mScroller.isScrolling() || isHiddenSlideMove(false)){ /* * in case the user start the touch while we didn't * accomplish scrolling - intercept touch event. * */ mBeingDrag = true; mUnableToDrag = false; } else { /* * Otherwise let's start the process of detecting * who the touch event belongs to. */ mBeingDrag = false; mUnableToDrag = false; } // LOG.v("OnInterceptTouchEvent: DOWN being drag " + mBeingDrag + // ", unable to drag " + mUnableToDrag); return mBeingDrag; } 


event , . . , MotionEvent.ACTION_DOWN. event' , . , , event' child' . , isHiddenSlideMove(). , event' ┬л┬╗, , , . , .

, :

  /** * Defines whether motion events has been started on the closed slide or not * * @param extend * if <code>true</code> it will take into account * {@link #mTouchExtension}. Otherwise this method will only take * into account {@link #mInitialX} and {@link #mInitialY} * @return <code>true</code> in case the motion event has been started to * the right of the last closed slide, <code>false</code> otherwise. */ private boolean isHiddenSlideMove(boolean extend) { int x = (int) mInitialX; int y = (int) mInitialY; Rect rightSide = new Rect(); boolean right = false; for (int i = getLastHiddenSlideIndex(); i >= 0 && !right; i--) { View view = getChild(i); Rect rect = new Rect(); view.getHitRect(rect); rightSide.union(rect); if (rightSide.contains(x, y) || (extend && rightSide.contains(x + mTouchExtension, y))) { right = true; } } return right; } 


тАФ :

  case MotionEvent.ACTION_MOVE:{ final int activePointerId = mActivePointerId; if (activePointerId == INVALID_POINTER_ID) { // If we don't have a valid id, the touch down wasn't on content. break; } final int pointerIndex = MotionEventCompat.findPointerIndex(ev, activePointerId); final float x = MotionEventCompat.getX(ev, pointerIndex); final float dx = x - mInitialX; final float xDiff = Math.abs(dx); final float y = MotionEventCompat.getY(ev, pointerIndex); final float dy = y - mInitialY; final float yDiff = Math.abs(dy); if (dx != 0 && canScroll(this, false, (int) dx, (int) x, (int) y)) { // Nested view has scrollable area under this point. Let it be handled there. if(!isHiddenSlideMove(false)) { mUnableToDrag = true; return false; } } // if it seems to be horizontal scroll if (xDiff > mTouchSlop && xDiff * 0.5f > yDiff){ // LOG.v("OnInterceptTouchEvent: MOVE start drag"); ev.setAction(MotionEvent.ACTION_DOWN); adjustSelectedSlide(); mScroller.onTouch(this, ev); mBeingDrag = true; } else if (yDiff > mTouchSlop){ // LOG.v("OnInterceptTouchEvent: MOVE unable to drag"); mUnableToDrag = true; } break; } 


. . -, , , , , ( ). , , . ,
. , . . , , 22,5 , .



, , тАФ . . , .

. , , , ( ), , . , Google (. ViewPager):

  if (dx != 0 && canScroll(this, false, (int) dx, (int) x, (int) y)) { // Nested view has scrollable area under this point. Let it be handled there. if(!isHiddenSlideMove(false)) { mUnableToDrag = true; return false; } } 

  /** * Tests scrollability within child views of v given a delta of dx. * * @param v View to test for horizontal scrollability * @param checkV Whether the view v passed should itself be checked for scrollability (true), * or just its children (false). * @param dx Delta scrolled in pixels * @param x X coordinate of the active touch point * @param y Y coordinate of the active touch point * @return true if child views of v can be scrolled by delta of dx. */ protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) { if (v instanceof ViewGroup) { final ViewGroup group = (ViewGroup) v; final int scrollX = v.getScrollX(); final int scrollY = v.getScrollY(); final int count = group.getChildCount(); // Count backwards - let topmost views consume scroll distance first. for (int i = count - 1; i >= 0; i--) { final View child = group.getChildAt(i); if (x + scrollX >= child.getLeft() && x + scrollX < child.getRight() && y + scrollY >= child.getTop() && y + scrollY < child.getBottom() && canScroll(child, true, dx, x + scrollX - child.getLeft(), y + scrollY - child.getTop())) { return true; } } } return (checkV && ViewCompat.canScrollHorizontally(v, -dx)); } 


View, ┬л┬╗, , , ViewCompat.canScrollHorizontally(). , , . ViewCompat, .

 public class ViewCompat { public static boolean canScrollHorizontally(View v, int direction){ if (v instanceof QuickActionView){ return ((QuickActionView)v).canScrollHorizontally(direction); } else { return android.support.v4.view.ViewCompat.canScrollHorizontally(v, direction); } } } } 


. .

  /** * {@inheritDoc} */ @Override public boolean onTouchEvent(MotionEvent event) { LOG.i("onTouchEvent: " + event); if (event.getAction() == MotionEvent.ACTION_DOWN && event.getEdgeFlags() != 0) { // Don't handle edge touches immediately -- they may actually belong to one of our // descendants. return false; } if ((event.getAction() & MotionEventCompat.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP){ continueWithSecondPointer(event); return true; } // adjust selected slide in case we didn't it in #onInterceptTouchEvent() method // if we have no touchable child under the touch event for instance if (!mScroller.isScrolling() && event.getAction() == MotionEvent.ACTION_DOWN){ adjustSelectedSlide(); } return mScroller.onTouch(this, event); } 


event' , . , , , View.

  @Override public boolean dispatchTouchEvent(MotionEvent ev) { // LOG.v("dispatchTouchEvent: " + ev); if (getChildCount() == 0){ return false; } return super.dispatchTouchEvent(ev); } 


. - , .

, , , MotionEvent'.

тАФ . dispatchTouchEvent(), onInterceptTouchEvent() onTouchEvent(), , event. , , . developer.android.com , event'.

, . , , .

:)

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


All Articles