Android рдкрд╛рда рдкреНрд░рджрд░реНрд╢рди


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


рдореИрдВ TextView рдбрд┐рд╡рд╛рдЗрд╕ рдФрд░ рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдХреБрдЫ рд╕реВрдХреНрд╖реНрдорддрд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реВрдВрдЧрд╛ред рдкрд┐рдЫрд▓реЗ Google I / O рдХреА рд░рд┐рдкреЛрд░реНрдЯреЛрдВ рд╕реЗ рдореБрдЦреНрдп рд╕реБрдЭрд╛рд╡ рд▓рд┐рдП рдЧрдП рдереЗред


рд╣реБрдб рдХреЗ рдиреАрдЪреЗ TextView


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



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


TextView рдХреЛрд░ рд╕реНрд╡рдпрдВ C ++ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рдЬреЛ рдкреЛрд░реНрдЯрд┐рдВрдЧ рдХреЛ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдирдП рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рд╕реЗ рд╡рд╣рд╛рдВ рд▓рд╛рдЧреВ рдирдИ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЗ рд╕рдорд░реНрдерди рдкреБрд╕реНрддрдХрд╛рд▓рдп рддрдХ рд╕реАрдорд┐рдд рдХрд░рддрд╛ рд╣реИред рдореБрдЦреНрдп рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИ:


  • рдорд┐рдирд┐рдХрд┐рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдкрд╛рда рдХреА рд▓рдВрдмрд╛рдИ, рд░реЗрдЦрд╛ рдХреЛ рддреЛрдбрд╝рдиреЗ рдФрд░ рд╢рдмреНрджрд╛рдВрд╢ рджреНрд╡рд╛рд░рд╛ рд╢рдмреНрджреЛрдВ рдХреЛ рдорд╛рдкрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
  • ICU рдпреВрдирд┐рдХреЛрдб рд╕рд╣рд╛рдпрддрд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред
  • рд╣рд╛рд░реНрдлрдмрдЬ рдпреВрдирд┐рдХреЛрдб рд╡рд░реНрдгреЛрдВ рдХреЗ рд▓рд┐рдП рдлреЛрдВрдЯ рдореЗрдВ рд╕рдВрдмрдВрдзрд┐рдд рдЧреНрд░рд╛рдлрд┐рдХ рддрддреНрд╡реЛрдВ (рдЧреНрд▓рд┐рдлрд╝) рдХреЛ рдвреВрдВрдврддрд╛ рд╣реИред
  • FreeType рдЧреНрд▓рд┐рдлрд╝ рдХреЗ рдмрд┐рдЯрдореИрдк рдмрдирд╛рддрд╛ рд╣реИред
  • Skia 2D рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдЦреАрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЗрдВрдЬрди рд╣реИред

рдкрд╛рда рдХреА рд▓рдВрдмрд╛рдИ рдФрд░ рд░реЗрдЦрд╛ рдХреЛ рдорд╛рдкрдирд╛


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



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


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


 textView.typeface = TypeFace.CustomFallbackBuilder( FontFamily.Builder( Font.Builder(assets, тАЬlato.ttfтАЭ).build() ).build() ).addCustomFallback( FontFamily.Builder( Font.Builder(assets, тАЬkosugi.ttfтАЭ).build() ).build() ).build() 

рдЕрдм, CustomFallbackBuilder рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ CustomFallbackBuilder рдЬрдм рдЧреНрд▓рд┐рдлрд╝ рдХреЗ рд╕рд╛рде рд╡рд░реНрдг рдорд┐рд▓рд╛рди рдХрд░рддреЗ рд╣реИрдВ, рддреЛ SDK рдХреНрд░рдо рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдлрд╝реЙрдиреНрдЯ рдкрд░рд┐рд╡рд╛рд░ рдкрд░ CustomFallbackBuilder рдХрд░реЗрдЧрд╛, рдФрд░ рдпрджрд┐ рдпрд╣ рдирд╣реАрдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рддреЛ рд╕рд┐рд╕реНрдЯрдо рдлреЛрдВрдЯ рдореЗрдВ рдЦреЛрдЬ рдЬрд╛рд░реА рд░рд╣реЗрдЧреА (рдФрд░ setSystemFallback() рд╡рд┐рдзрд┐ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЖрдк рдкрд╕рдВрджреАрджрд╛ рд╕рд┐рд╕реНрдЯрдо рдлрд╝реЙрдиреНрдЯ рдкрд░рд┐рд╡рд╛рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ)ред CustomFallbackBuilder рдлрд╝реЙрдиреНрдЯ рдкрд░рд┐рд╡рд╛рд░ рдХреА рд╕рдВрдЦреНрдпрд╛ рдкрд░ рдПрдХ рд╕реАрдорд╛ рд╣реИ - рдЖрдк 64 рд╕реЗ рдЕрдзрд┐рдХ рдлрд╝реЙрдиреНрдЯ рдирд╣реАрдВ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред


рдорд┐рдирд┐рдХрд┐рди рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╢рдмреНрджреЛрдВ рдореЗрдВ рддрд╛рд░реЛрдВ рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд╢рдмреНрджреЛрдВ рдХреЛ рдорд╛рдкрддрд╛ рд╣реИред рд▓реЙрд▓реАрдкреЙрдк (21) рд╕реЗ рдХрд╛рдо рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╢рдмреНрджреЛрдВ рдХреЗ рдПрдХ рд╕рд┐рд╕реНрдЯрдо LRU рдХреИрд╢ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рддрд░рд╣ рдХрд╛ рдХреИрд╢ рдПрдХ рдмрд╣реБрдд рдмрдбрд╝рд╛ рдкреНрд░рджрд░реНрд╢рди рджреЗрддрд╛ рд╣реИ: рдХреИрд╢реНрдб рд╢рдмреНрдж рдХреЗ рд▓рд┐рдП Paint.measureText() рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдкрд░ рдФрд╕рддрди 3% рд╕рдордп рд▓рдЧреЗрдЧрд╛ рдЬрдм рд╡рд╣ рдкрд╣рд▓реА рдмрд╛рд░ рдЕрдкрдиреЗ рдЖрдХрд╛рд░ рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИред



рдпрджрд┐ рдкрд╛рда рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЪреМрдбрд╝рд╛рдИ рдореЗрдВ рдлрд┐рдЯ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдорд┐рдирд┐рдХрд┐рди рдкрд╛рда рдореЗрдВ рд▓рд╛рдЗрди рдмреНрд░реЗрдХ рдФрд░ рд╢рдмреНрджреЛрдВ рдХреА рд╡реНрдпрд╡рд╕реНрдерд╛ рдХрд░рддрд╛ рд╣реИред breakStrategy (23) рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рдХреЗ , рдЖрдк breakStrategy рд▓рд┐рдП breakStrategy рдФрд░ breakStrategy рд╡рд┐рд╢реЗрд╖ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдХреЗ рдЗрд╕рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рдореВрд▓реНрдп рдХреЗ рд╕рд╛рде breakStrategy=simple рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗрд╡рд▓ рдкрд╛рда рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЧреБрдЬрд░рддреЗ рд╣реБрдП, рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ рд╣рд╛рдЗрдлрд╝рди рдХреА рд╡реНрдпрд╡рд╕реНрдерд╛ рдХрд░реЗрдЧрд╛: рдЬреИрд╕реЗ рд╣реА рд▓рд╛рдЗрди рдлрд┐рдЯ рд╣реЛрдирд╛ рдмрдВрдж рд╣реЛ рдЬрд╛рддреА рд╣реИ, рд╣рд╛рдЗрдлрд╝рдиреЗрд╢рди рдХреЛ рдЕрдВрддрд┐рдо рд╢рдмреНрдж рд╕реЗ рдкрд╣рд▓реЗ рд░рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИред



balanced рдореВрд▓реНрдп рдореЗрдВ balanced рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд▓рд╛рдЗрди рдмреНрд░реЗрдХ рдмрдирд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдЧреА рддрд╛рдХрд┐ рд▓рд╛рдЗрдиреЛрдВ рдХреЛ рдЪреМрдбрд╝рд╛рдИ рдореЗрдВ рдЧрдардмрдВрдзрди рдХрд┐рдпрд╛ рдЬрд╛рдПред



high_quality рдореЗрдВ рд▓рдЧрднрдЧ рд╕рдорд╛рди рд╡реНрдпрд╡рд╣рд╛рд░ рд╣реЛрддрд╛ рд╣реИ, рдХреБрдЫ рдЕрдВрддрд░реЛрдВ рдХреЗ рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рде (рдЙрдирдореЗрдВ рд╕реЗ рдПрдХ: рджрдВрдбрд╛рддреНрдордХ рд░реЗрдЦрд╛ рдкрд░, рд╣рд╛рдЗрдлрд╝рдиреЗрд╢рди рди рдХреЗрд╡рд▓ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╢рдмреНрдж рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рдмрд▓реНрдХрд┐ рд╢рдмреНрджрд╛рдВрд╢ рджреНрд╡рд╛рд░рд╛ рд╢рдмреНрдж рднреА рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ)ред


hyphenationFrequency рд╡рд┐рд╢реЗрд╖рддрд╛ hyphenationFrequency рд╕рд┐рд▓реЗрдмрд▓реНрд╕ рджреНрд╡рд╛рд░рд╛ рд╢рдмреНрдж рд░реИрдкрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рд░рдгрдиреАрддрд┐ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИред none рдореВрд▓реНрдп рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд╣рд╛рдЗрдлрд╝рдиреЗрд╢рди рдирд╣реАрдВ рдХрд░реЗрдЧрд╛, normal рд╣рд╛рдЗрдлрд╝рдиреЗрд╢рди рдХреА рдПрдХ рдЫреЛрдЯреА рдЖрд╡реГрддреНрддрд┐ рдХрд░реЗрдЧрд╛, рдФрд░ full , рдЕрдзрд┐рдХрддрдо рд╢рдмреНрджреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдЧрд╛ред



рдЪрдпрдирд┐рдд рдЭрдВрдбреЗ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдкрд╛рда рд░реЗрдВрдбрд░рд┐рдВрдЧ рдкреНрд░рджрд░реНрд╢рди ( Android P (28) рдкрд░ рдорд╛рдкрд╛ рдЬрд╛рддрд╛ рд╣реИ):



рдХрд╛рдлреА рдордЬрдмреВрдд рдкреНрд░рджрд░реНрд╢рди рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, Google рдбреЗрд╡рд▓рдкрд░реНрд╕, рд╕рдВрд╕реНрдХрд░рдг Q (29) рдФрд░ AppCompat 1.1.0 рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рддреЗ рд╣реБрдП, рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╣рд╛рдЗрдлрд╝рдиреЗрд╢рди рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рдпрджрд┐ рд╢рдмреНрдж рд░реИрдкрд┐рдВрдЧ рдЖрд╡реЗрджрди рдореЗрдВ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ, рддреЛ рдЕрдм рдЖрдкрдХреЛ рдЗрд╕реЗ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред


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


рдкрд╛рда рд╢реИрд▓реА


рдПрдВрдбреНрд░реЙрдЗрдб рдореЗрдВ рдЯреЗрдХреНрд╕реНрдЯ рдХреЛ рд╕реНрдЯрд╛рдЗрд▓ рдХрд░рдиреЗ рдХреЗ рдХрдИ рддрд░реАрдХреЗ рд╣реИрдВ:


  • рдПрдХ рдПрдХрд▓ рд╢реИрд▓реА рдЬреЛ рд╕рдВрдкреВрд░реНрдг TextView рддрддреНрд╡ рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддреА рд╣реИред
  • рдмрд╣реБ-рд╢реИрд▓реА (рдорд▓реНрдЯреА рд╕реНрдЯрд╛рдЗрд▓) - рдПрдХ рдмрд╛рд░ рдореЗрдВ рдХрдИ рд╢реИрд▓рд┐рдпрд╛рдБ, рдЬреЛ рдкреИрд░рд╛рдЧреНрд░рд╛рдл рдпрд╛ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдкрд╛рддреНрд░реЛрдВ рдХреЗ рд╕реНрддрд░ рдкрд░ рдкрд╛рда рдкрд░ рд▓рд╛рдЧреВ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рдХрдИ рддрд░реАрдХреЗ рд╣реИрдВ:
    • рдХреИрдирд╡рд╛рд╕ рдкрд░ рдкрд╛рда рдЦреАрдВрдЪрдирд╛
    • html рдЯреИрдЧ
    • рд╡рд┐рд╢реЗрд╖ рдорд╛рд░реНрдХрдЕрдк рддрддреНрд╡ - рд╕реНрдкреИрди

рдПрдХ рдПрдХрд▓ рд╢реИрд▓реА рдХрд╛ рдЕрд░реНрде рд╣реИ рдЯреЗрдХреНрд╕реНрдЯ рд╡реНрдпреВ рдорд╛рд░реНрдХрдЕрдк рдореЗрдВ XML рд╢реИрд▓рд┐рдпреЛрдВ рдпрд╛ XML рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕рд┐рд╕реНрдЯрдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреНрд░рдо рдореЗрдВ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рд╕реЗ рдореВрд▓реНрдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░реЗрдЧрд╛: рдЯреЗрдХреНрд╕реНрдЯрдПрдкреИрд░реЗрдВрд╕, рдереАрдо (рдереАрдо), рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╢реИрд▓реА (рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╢реИрд▓реА), рдЖрд╡реЗрджрди рд╕реЗ рд╢реИрд▓реА, рдФрд░ рд╕рд░реНрд╡реЛрдЪреНрдЪ рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рд╡реНрдпреВ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХрд╛ рдорд╛рди рд╣реИред


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


HTML рдЯреИрдЧ рдПрдХ рдФрд░ рд╕рд░рд▓ рд╕рдорд╛рдзрд╛рди рд╣реИ рдЬреЛ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд╢рдмреНрджреЛрдВ рдХреЛ рдмреЛрд▓реНрдб, рдЗрдЯреИрд▓рд┐рдХ рдмрдирд╛рдиреЗ рдпрд╛ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдкрд╛рда рдореЗрдВ рдбреЙрдЯреНрд╕ рдХреЗ рд╕рд╛рде рд╕реВрдЪрд┐рдпреЛрдВ рдХреЛ рд╣рд╛рдЗрд▓рд╛рдЗрдЯ рдХрд░рдиреЗ рдЬреИрд╕реА рд╕реБрд╡рд┐рдзрд╛рдПрдБ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рд╕рднреА рдбреЗрд╡рд▓рдкрд░ рдХреЛ Html.fromHtml() рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреЙрд▓ рдХрд░рдирд╛ рд╣реИ, рдЬреЛ рдХрд┐ рдкрд╛рда рдХреЛ рдЯреИрдЧ рдХрд┐рдП рдЧрдП рдкрд╛рда рдХреЛ рд╕реНрдкреИрди рджреНрд╡рд╛рд░рд╛ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░ рджреЗрдЧрд╛ред рд▓реЗрдХрд┐рди рдЗрд╕ рд╕рдорд╛рдзрд╛рди рдореЗрдВ рд╕реАрдорд┐рдд рдХреНрд╖рдорддрд╛рдПрдВ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ HTML рдЯреИрдЧреНрд╕ рдХреЗ рдХреЗрд╡рд▓ рдПрдХ рд╣рд┐рд╕реНрд╕реЗ рдХреЛ рдкрд╣рдЪрд╛рдирддрд╛ рд╣реИ рдФрд░ рд╕реАрдПрд╕рдПрд╕ рд╢реИрд▓рд┐рдпреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред


 val text = "My text <ul><li>bullet one</li><li>bullet two</li></ul>" myTextView.text = Html.fromHtml(text) 

TextView рдХреЛ рд╕реНрдЯрд╛рдЗрд▓ рдХрд░рдиреЗ рдХреЗ рд╡рд┐рднрд┐рдиреНрди рддрд░реАрдХреЛрдВ рдХреЛ рдЬреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рд╡рд┐рдзрд┐ рдХреА рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рдХреЛ рдпрд╛рдж рд░рдЦрдиреЗ рдпреЛрдЧреНрдп рд╣реИ, рдЬреЛ рдЕрдВрддрд┐рдо рдкрд░рд┐рдгрд╛рдо рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░реЗрдЧрд╛:



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


spans


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


рд╕реНрдкреИрди рдХреА рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╢реНрд░реЗрдгрд┐рдпрд╛рдВ рдкреНрд░рддрд┐рд╖реНрдард┐рдд рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИрдВ:


  • рдЪрд░рд┐рддреНрд░ рд╕реНрдкреИрди - рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рдЪрд░рд┐рддреНрд░ рд╕реНрддрд░ рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддреЗ рд╣реИрдВред
    • рджрд┐рдЦрд╛рд╡рдЯ рдкреНрд░рднрд╛рд╡рд┐рдд - рдкрд╛рда рдХрд╛ рдЖрдХрд╛рд░ рди рдмрджрд▓реЗрдВред
    • рдореИрдЯреНрд░рд┐рдХ рдкреНрд░рднрд╛рд╡рд┐рдд - рдкрд╛рда рдХрд╛ рдЖрдХрд╛рд░ рдмрджрд▓реЗрдВред
  • рдкреИрд░рд╛рдЧреНрд░рд╛рдл рд╕реНрдкреИрди - рдкреИрд░рд╛рдЧреНрд░рд╛рдл рд╕реНрддрд░ рдкрд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


рдПрдВрдбреНрд░реЙрдЗрдб рдлреНрд░реЗрдорд╡рд░реНрдХ рдореЗрдВ рдЗрдВрдЯрд░рдлреЗрд╕ рдФрд░ рдПрдмреНрд╕реНрдЯреНрд░реИрдХреНрдЯ рдХреНрд▓рд╛рд╕реЗрд╕ рд╣реИрдВ, рдЬрд┐рдиреНрд╣реЗрдВ onMeasure() рдФрд░ onMeasure() рд░реЗрдВрдбрд░рд┐рдВрдЧ рдХреЗ рджреМрд░рд╛рди рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпреЗ рддрд░реАрдХреЗ TextPaint рдФрд░ Canvas рдЬреИрд╕реА TextPaint -рд▓реЗрд╡рд▓ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рддрдХ рдкрд╣реБрдБрдЪ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВред рд╕реНрдкреИрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдПрдВрдбреНрд░реЙрдЗрдб рдлреНрд░реЗрдорд╡рд░реНрдХ рдпрд╣ рдЬрд╛рдВрдЪрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рддрд░реАрдХреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреМрди-рд╕рд╛ рдЗрдВрдЯрд░рдлреЗрд╕ рд╣реИред



рдПрдВрдбреНрд░реЙрдЗрдб рдлреНрд░реЗрдорд╡рд░реНрдХ рд▓рдЧрднрдЧ 20+ рд╕реНрдкреИрди рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдЖрдк рдЕрдкрдирд╛ рдмрдирд╛ рд▓реЗрдВ, рдпрд╣ рдЬрд╛рдВрдЪрдирд╛ рдмреЗрд╣рддрд░ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдПрд╕рдбреАрдХреЗ рдЙрдкрдпреБрдХреНрдд рд╣реИред


рд╕реНрдкреИрди рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдореЗрдЯреНрд░рд┐рдХ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐


рд╕реНрдкреИрди рдХреА рдкрд╣рд▓реА рд╢реНрд░реЗрдгреА рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддреА рд╣реИ рдХрд┐ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рд╡рд░реНрдг рдХреИрд╕реЗ рджрд┐рдЦреЗрдВрдЧреЗ: рдЪрд░рд┐рддреНрд░ рдХрд╛ рд░рдВрдЧ, рдкреГрд╖реНрдарднреВрдорд┐ рдХрд╛ рд░рдВрдЧ, рд░реЗрдЦрд╛рдВрдХрд┐рдд рдпрд╛ рдкрд╛рд░ рдХрд┐рдП рдЧрдП рд╡рд░реНрдг, рдЖрджрд┐ред рдпреЗ рд╕реНрдкреИрди UpdateAppearance рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ CharacterStyle рдХреНрд▓рд╛рд╕ рд╕реЗ рдЗрдирд╣реЗрд░рд┐рдЯ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ TextPaint рдСрдмреНрдЬреЗрдХреНрдЯ рддрдХ рдкрд╣реБрдВрдЪ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред



рдореИрдЯреНрд░рд┐рдХ рдкреНрд░рднрд╛рд╡рд┐рдд рд╕реНрдкреИрди рдЯреЗрдХреНрд╕реНрдЯ рдФрд░ рд▓реЗрдЖрдЙрдЯ рдХреЗ рдЖрдХрд╛рд░ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП, рдЗрд╕ рддрд░рд╣ рдХреЗ рд╕реНрдкреИрди рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рди рдХреЗрд╡рд▓ onMeasure() , рдмрд▓реНрдХрд┐ рдХреЙрд▓ onMeasure() / onLayout() ред рдпреЗ MetricAffectingSpan рдЖрдорддреМрд░ рдкрд░ MetricAffectingSpan рд╡рд░реНрдЧ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рд╣реЛрддреЗ рд╣реИрдВ, рдЬреЛ рдКрдкрд░ рдмрддрд╛рдП рдЧрдП MetricAffectingSpan рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓реЗ рд╣реИрдВред



рд╡рд░реНрдг рдмрдирд╛рдо рдкреИрд░рд╛рдЧреНрд░рд╛рдл рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╕реНрдкреИрди


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



Android рдкрд░, рдкреИрд░рд╛рдЧреНрд░рд╛рдл рдХреЛ newlines ( \n ) рджреНрд╡рд╛рд░рд╛ рдЕрд▓рдЧ рдХрд┐рдП рдЧрдП рдкрд╛рда рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред



рдЖрдкрдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рд▓реЗрдЦрди


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


  • рдЪрд░рд┐рддреНрд░ рд╕реНрддрд░ рдкрд░ рдкрд╛рда рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддрд╛ рд╣реИ -> CharacterStyle
  • рдкреИрд░рд╛рдЧреНрд░рд╛рдл рд╕реНрддрд░ рдкрд░ рдкрд╛рда рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддрд╛ рд╣реИ -> ParagraphStyle
  • рдкрд╛рда рджреГрд╢реНрдп рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддрд╛ рд╣реИ тЖТ UpdateAppearance
  • рдкрд╛рда рдХрд╛ рдЖрдХрд╛рд░ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддрд╛ рд╣реИ - UpdateLayout

рдпрд╣рд╛рдБ рдлрд╝реЙрдиреНрдЯ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд╡рдзрд┐ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ:


 class CustomTypefaceSpan(private val font: Typeface?) : MetricAffectingSpan() { override fun updateMeasureState(textPaint: TextPaint) = update(textPaint) override fun updateDrawState(textPaint: TextPaint) = update(textPaint) fun update(textPaint: TextPaint) { textPaint.apply { val old = typeface val oldStyle = old?.style ?: 0 val font = Typeface.create(font, oldStyle) typeface = font //    } } } 

рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рд╣рдо рдХреЛрдб рдХреЗ рд╣рд╛рдЗрд▓рд╛рдЗрдЯрд┐рдВрдЧ рдмреНрд▓реЙрдХ рдХреЗ рд▓рд┐рдП рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛ рд╕реНрдкреИрди рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣рдо рдЕрдкрдиреЗ рдкрд┐рдЫрд▓реЗ рд╕реНрдкреИрди рдХреЛ рдПрдбрд┐рдЯ рдХрд░реЗрдВрдЧреЗ - рдлреЙрдиреНрдЯ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдЯреЗрдХреНрд╕реНрдЯ рдХреЗ рдмреИрдХрдЧреНрд░рд╛рдЙрдВрдб рдХрд▓рд░ рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХрд░реЗрдВрдЧреЗ:


 class CodeBlockSpan(private val font: Typeface?) : MetricAffectingSpan() { тАж fun update(textPaint: TextPaint) { textPaint.apply { //    тАж bgColor = lightGray //    } } } 

рдкрд╛рда рдкрд░ рдЕрд╡рдзрд┐ рд▓рд╛рдЧреВ рдХрд░реЗрдВ:


 //    span spannable.setSpan(CodeBlockSpan(typeface), ...) 

рд▓реЗрдХрд┐рди рдЖрдк рджреЛ рд╕реНрдкреИрди рдХреЗ рд╕рдВрдпреЛрдЬрди рд╕реЗ рдареАрдХ рд╡реИрд╕рд╛ рд╣реА рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: Android рдлреНрд░реЗрдорд╡рд░реНрдХ рд╕реЗ рд╣рдорд╛рд░реЗ рдкрд┐рдЫрд▓реЗ CustomTypefaceSpan рдФрд░ BackgroundColorSpan рдХреЛ рд▓реЗрдВ:


 //    spannable.setSpan(BackgroundColorSpan(lightGray), ...) //   spannable.setSpan(CustomTypefaceSpan(typeface), ...) 

рдЗрди рджреЛрдиреЛрдВ рд╕рдорд╛рдзрд╛рдиреЛрдВ рдореЗрдВ рдЕрдВрддрд░ рд╣реЛрдЧрд╛ред рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рд╕реНрд╡-рд▓рд┐рдЦрд┐рдд рд╕реНрдкреИрди рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд╡рд┐рдкрд░реАрдд Parcelable рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рдЬрдм рд╕реНрд╡-рд▓рд┐рдЦрд┐рдд рдорд╛рд░реНрдХрдЕрдк рдХреА рдЕрд╡рдзрд┐ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдЗрдВрдЯреЗрдВрдЯ рдпрд╛ рдХреНрд▓рд┐рдкрдмреЛрд░реНрдб рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рд╕реНрдЯрд╛рдЗрд▓ рд▓рд╛рдЗрди рдХреЛ рдкреНрд░реЗрд╖рд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдлреНрд░реЗрдорд╡рд░реНрдХ рд╕реЗ рд╕реНрдкреИрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдорд╛рд░реНрдХрдЕрдк рд░рд╣реЗрдЧрд╛ред



рдкрд╛рда рдореЗрдВ рд╕реНрдкреИрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛


рдлреНрд░реЗрдорд╡рд░реНрдХ рдореЗрдВ рд╕реНрдЯрд╛рдЗрд▓ рдХрд┐рдП рдЧрдП рдЯреЗрдХреНрд╕реНрдЯ рдХреЗ рд▓рд┐рдП рджреЛ рдЗрдВрдЯрд░рдлреЗрд╕ рд╣реИрдВ: Spannable рдФрд░ Spannable (рдХреНрд░рдорд╢рдГ рдЕрдкрд░рд┐рд╡рд░реНрддрд┐рдд рдФрд░ рдкрд░рд┐рд╡рд░реНрддрдирд╢реАрд▓ рдорд╛рд░реНрдХрдЕрдк рдХреЗ рд╕рд╛рде) рдФрд░ рддреАрди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди: SpannedString (рдЕрдкрд░рд┐рд╡рд░реНрддрд┐рдд рдЯреЗрдХреНрд╕реНрдЯ), SpannableString (рдЕрдкрд░рд┐рд╡рд░реНрддрд┐рдд рдЯреЗрдХреНрд╕реНрдЯ) рдФрд░ SpannableStringBuilder ( SpannableStringBuilder рдкрд╛рда)ред


рдкрд░рд╕реНрдкрд░ рдкрд╛рдардкрд░рд┐рд╡рд░реНрддрдирд╢реАрд▓ рдорд╛рд░реНрдХрдЕрдк
рдлреИрд▓рд╛ рд╣реБрдЖ рддрд╛рд░рдирд╣реАрдВрдирд╣реАрдВ
рд╕реНрдкреИрди рдХрд░рдиреЗ рдпреЛрдЧреНрдп рддрд╛рд░рдирд╣реАрдВрд╣рд╛рдВ
Spannablestring рдмрд┐рд▓реНрдбрд░рд╣рд╛рдВрд╣рд╛рдВ

SpannableStringBuilder , рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ EditText рдЕрдВрджрд░ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдкрд╛рда рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред


рдЖрдк рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдирдИ рдЕрд╡рдзрд┐ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ:


setSpan(Object what, int start, int end, int flags)


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


рдКрдкрд░ рд╕реВрдЪреАрдмрджреНрдз рдХрдХреНрд╖рд╛рдПрдВ рди рдХреЗрд╡рд▓ рд╢рдмреНрджрд╛рд░реНрде рд░реВрдк рд╕реЗ рднрд┐рдиреНрди рд╣реЛрддреА рд╣реИрдВ, рдмрд▓реНрдХрд┐ рдпрд╣ рднреА рдХрд┐ рд╡реЗ рдЖрдВрддрд░рд┐рдХ рд░реВрдк рд╕реЗ рдХреИрд╕реЗ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХреА рдЬрд╛рддреА рд╣реИрдВ: SpannedString рдФрд░ SpannableString рд╕реНрдкреИрди рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд░рдгрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ SpannableStringBuilder рдПрдХ рдЕрдВрддрд░рд╛рд▓ рдкреЗрдбрд╝ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ ред


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


рдкрд╛рда рдореЗрдВ рдЕрд╡рдзрд┐ рдХреЗ рд▓рд┐рдП рдЬрд╛рдБрдЪ рдХрд░реЗрдВ


рдХрд╛рд░реНрдп рд╕рдордп-рд╕рдордп рдкрд░ рдпрд╣ рдЬрд╛рдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдарддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдПрдХ рд╕реНрдкреИрди рд▓рд╛рдЗрди рдХреА рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЕрд╡рдзрд┐ рд╣реИред рдФрд░ Stackoverflow рдкрд░ рдЖрдк рдпрд╣ рдХреЛрдб рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ:


 fun <T> hasSpan(spanned: Spanned, clazz: Class<T>): Boolean { val spans: Array<out T> = spanned.getSpans(0, spanned.length, clazz) return spans.isNotEmpty() } 

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


рдПрдХ рдФрд░ рдЕрдзрд┐рдХ рдкреНрд░рднрд╛рд╡реА рд╕рдорд╛рдзрд╛рди рд╣реЛрдЧрд╛ nextSpanTransition() рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП:


 fun <T> hasSpan(spanned: Spanned, clazz: Class<T>): Boolean { val limit = spanned.length return spanned.nextSpanTransition(0, limit, clazz) < limit } 

рд╡рд┐рднрд┐рдиреНрди рднрд╛рд╖рд╛ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдореЗрдВ рдкрд╛рда рдорд╛рд░реНрдХрдЕрдк


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


 <!-- values-en/strings.xml --> <string name="title">Best practices for text in Android</string> <!-- values-es/strings.xml --> <string name=тАЭtitleтАЭ>Texto en Android: mejores pr├бcticas</string> 

рдпрджрд┐ рдЖрдкрдХреЛ рдХреБрдЫ рд╕рд░рд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╢рдмреНрдж рдХреЛ рдмреЛрд▓реНрдб рдореЗрдВ рдЙрдЬрд╛рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рддреЛ рдЖрдк рд╕рд╛рдорд╛рдиреНрдп HTML рдЯреИрдЧ ( <b> ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред UI рдореЗрдВ, рдЖрдкрдХреЛ рдмрд╕ TextView рдореЗрдВ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕рдВрд╕рд╛рдзрди рд╕реЗрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:


 textView.setText(R.string.title) 

рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдкрдХреЛ рдХреБрдЫ рдФрд░ рдЬрдЯрд┐рд▓ рдЪрд╛рд╣рд┐рдП, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдлрд╝реЙрдиреНрдЯ рдмрджрд▓рдирд╛, рддреЛ html рдХрд╛ рдЕрдм рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╕рдорд╛рдзрд╛рди рд╡рд┐рд╢реЗрд╖ <annotation> рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИред рдпрд╣ рдЯреИрдЧ рдЖрдкрдХреЛ xml рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдХрд┐рд╕реА рднреА рдХреБрдВрдЬреА-рдорд╛рди рдпреБрдЧреНрдо рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЬрдм рд╣рдо рд╕рдВрд╕рд╛рдзрдиреЛрдВ рд╕реЗ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдЦреАрдВрдЪрддреЗ рд╣реИрдВ, рддреЛ рдпреЗ рдЯреИрдЧ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ Annotation рд╕реНрдкреИрди рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВ, рдкрд╛рда рдореЗрдВ рд╕рдВрдмрдВрдзрд┐рдд рдХреБрдВрдЬрд┐рдпреЛрдВ рдФрд░ рдореВрд▓реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рд╡реНрдпрд╡рд╕реНрдерд┐рдд рд╣реЛрддреЗ рд╣реИрдВред рдЙрд╕рдХреЗ рдмрд╛рдж, рдЖрдк рдкрд╛рда рдореЗрдВ рдПрдиреЛрдЯреЗрд╢рди рдХреА рд╕реВрдЪреА рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЖрд╡рд╢реНрдпрдХ рд╕реНрдкреИрди рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдореЗрдВ CustomTypefaceSpan рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдлрд╝реЙрдиреНрдЯ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред


рдПрдХ рдЯреИрдЧ рдЬреЛрдбрд╝реЗрдВ рдФрд░ рдЗрд╕реЗ "рдлрд╝реЙрдиреНрдЯ" рдХреБрдВрдЬреА рдФрд░ рдорд╛рди рдХреЗ рд▓рд┐рдП рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ - рдЬрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдлрд╝реЙрдиреНрдЯ рд╣рдо рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рд╡рд╣ рд╣реИ "title_emphasha" :

 <!-- values-en/strings.xml --> <string name="title">Best practices for <annotation font=тАЭtitle_emphasisтАЭ>text</annotation> in Android</string> <!-- values-es/strings.xml --> <string name=тАЭtitleтАЭ><annotation font=тАЭtitle_emphasisтАЭ>Texto</annotation> en Android: mejores pr├бcticas</string> 

рд╕рдВрд╕рд╛рдзрдиреЛрдВ рд╕реЗ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдЦреАрдВрдЪреЛ, рдПрдиреЛрдЯреЗрд╢рди рдХреЛ "рдлрд╝реЙрдиреНрдЯ" рдХреБрдВрдЬреА рдХреЗ рд╕рд╛рде рдЦреЛрдЬреЗрдВ рдФрд░ рд╕реНрдкреИрди рдХреА рд╡реНрдпрд╡рд╕реНрдерд╛ рдХрд░реЗрдВ:


 //      SpannedString,     span' val titleText = getText(R.string.title) as SpannedString //    val annotations = titleText.getSpans(0, titleText.length, Annotation::class.java) //     SpannableString //      val spannableString = SpannableString(titleText) //     for (annotation in annotations) { //     "font" if (annotation.key == "font") { val fontName = annotation.value //   ,     if (fontName == "title_emphasis") { val typeface = getFontCompat(R.font.permanent_marker) //  span    ,    spannableString.setSpan( CustomTypefaceSpan(typeface), titleText.getSpanStart(annotation), titleText.getSpanEnd(annotation), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE ) } } } styledText.text = spannableString 


рдпрд╣ рдКрдкрд░ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдХрд┐ рдПрдВрдбреНрд░реЙрдЗрдб рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рдмрд╛рд╣рд░ рдХреЗ рд╕реНрдкреИрди Parcelable рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрдВрдЯреЗрдВрдЯ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреНрд░реЗрд╖рд┐рдд рд╣реЛрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдпрд╣ рдЙрди рдПрдиреЛрдЯреЗрд╢рди рдкрд░ рд▓рд╛рдЧреВ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ рдЬреЛ Parcelable рд▓рд╛рдЧреВ Parcelable ред рддреЛ рдЖрдк рдПрдиреЛрдЯреЗрдВрдЯ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рдЗрдВрдЯреНрд░реЗрдВрдЯ рдФрд░ рдкрд╛рд░реНрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдареАрдХ рдЙрд╕реА рддрд░рд╣ рд╕реЗ рдкрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреИрд╕реЗ рдЕрдкрдиреЗ рд╕реНрдкреИрди рдХреА рд╡реНрдпрд╡рд╕реНрдерд╛ рдХрд░рдХреЗред


рдЯреЗрдХреНрд╕реНрдЯ рдЯреЗрдХреНрд╕реНрдЯ рдореЗрдВ рдХреИрд╕реЗ рдЯреЗрдХреНрд╕реНрдЯ рд░рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ


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


  • рдмреЛрд░рд┐рдВрдЧрд▓реИрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕рд░рд▓ рдЧреНрд░рдВрдереЛрдВ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ , рд▓рд╛рдЗрди рдмреНрд░реЗрдХ , рдЖрд░рдЯреАрдПрд▓ рдФрд░ рдЕрдиреНрдп рдЪреАрдЬреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдмрд╕реЗ рд╣рд▓реНрдХрд╛ рд╣реИред рдпрджрд┐ рдкрд╛рда рд╕рднреА рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХреЛ рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИ, рддреЛ TextView рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред
  • StaticLayout рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрдиреНрдп рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП TextView рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
  • рдПрдХ рдПрдбрд┐рдЯрдЯреЗрдХреНрд╕реНрдЯ рдореЗрдВ рдореНрдпреВрдЯреЗрдмрд▓ рдЯреЗрдХреНрд╕реНрдЯ рдХреЗ рд▓рд┐рдП рдбрд╛рдпрдиреЗрдорд┐рдХрд▓рд╛рдИрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

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


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



рд▓реЗрдХрд┐рди рд▓реЗрдЖрдЙрдЯ рд╡рд░реНрдЧ рдХреЗ рддрд░реАрдХреЗ рдмрдЪрд╛рд╡ рдореЗрдВ рдЖ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣рд╛рдБ рдПрдХ рдирдореВрдирд╛ рд╕рдорд╛рдзрд╛рди рд╣реИ:


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


рдлрд┐рд░ рдкрд╛рда рд░реИрдкрд┐рдВрдЧ рдХреЗ рд╕рднреА рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП 4 рдЖрдХрд░реНрд╖рд┐рдд рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╕рдВрд╕рд╛рдзрди рдмрдирд╛рдПрдВ, рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдпрддреЛрдВ рдореЗрдВ рд╕рдВрд▓рдЧреНрди рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:



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


 val startLine = layout.getLineForOffset(spanStartIndex) val endLine = layout.getLineForOffset(spanEndIndex) 

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


 ... if (startLine == endLine) { val lineTop = layout.getLineTop(startLine) //    val lineBottom = layout.getLineBottom(startLine) //    val startCoor = layout.getPrimaryHorizontal(spanStartIndex).toInt() //    val endCoor = layout.getPrimaryHorizontal(spanEndIndex).toInt() //    //   drawable.setBounds(startCoor, lineTop, endCoor, lineBottom) drawable.draw(canvas) ... 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рд╕реЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдЖрдЙрдЯ рдкреНрд░рджрд░реНрд╢рд┐рдд рдкрд╛рда рдкрд░ рдмрд╣реБрдд рдЙрдкрдпреЛрдЧреА рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рд╡рд┐рднрд┐рдиреНрди рдЧреИрд░-рдорд╛рдирдХ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИред


TextView рдкреНрд░рджрд░реНрд╢рди


onMeasure() рд╡реНрдпреВ, рдХрд┐рд╕реА рднреА рджреГрд╢реНрдп рдХреА рддрд░рд╣, рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрдиреЗ рдкрд░ рддреАрди рдЪрд░рдгреЛрдВ рд╕реЗ onMeasure() : onMeasure() , onLayout() рдФрд░ onLayout() onDraw() ред рдЙрд╕реА рд╕рдордп, onMeasure() рдХреЛ рдЕрдиреНрдп рджреЛ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рд╡рд┐рдкрд░реАрдд, рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдордп рд▓рдЧрддрд╛ рд╣реИ: рдЗрд╕ рд╕рдордп, рд▓реЗрдЖрдЙрдЯ рд╡рд░реНрдЧ рдХреЛ рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдкрд╛рда рдЖрдХрд╛рд░ рдХреА рдЧрдгрдирд╛ рдХреА рдЬрд╛рддреА рд╣реИред рдЗрд╕рд▓рд┐рдП рдкрд╛рда рдХрд╛ рдЖрдХрд╛рд░ рдмрджрд▓рдирд╛ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдлрд╝реЙрдиреНрдЯ рдмрджрд▓рдирд╛) рдмрд╣реБрдд рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдкрд╛рда рдХрд╛ рд░рдВрдЧ рдмрджрд▓рдирд╛ рдЕрдзрд┐рдХ рд╣рд▓реНрдХрд╛ рд╣реЛрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдореЗрдВ рдХреЗрд╡рд▓ onDraw() рдХреЙрд▓рд┐рдВрдЧ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдЧрдгрдирд╛ рдЖрдХрд╛рд░ рдХреЗ рд╕рд╛рде рдПрдХ рд╡реИрд╢реНрд╡рд┐рдХ рд╢рдмреНрдж рдХреИрд╢ рд╣реИред рдпрджрд┐ рд╢рдмреНрдж рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХреИрд╢ рдореЗрдВ рд╣реИ, рддреЛ рдЗрд╕рдХреЗ рд▓рд┐рдП onMeasure() рдХреЙрд▓ рдХрд░рдиреЗ рдкрд░ рдЙрд╕ рд╕рдордп рдХрд╛ 11-16% рд▓рдЧреЗрдЧрд╛ рдЬреЛ рдПрдХ рдкреВрд░реНрдг рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдерд╛ред


рдкрд╛рда рддреНрд╡рд░рдг


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


рдПрдВрдбреНрд░реЙрдЗрдб рдкреА (28) рдХреЗ рд╕рд╛рде рд╢реБрд░реВ, Google рдбреЗрд╡рд▓рдкрд░реНрд╕ рдиреЗ рдПрдкреАрдЖрдИ рдХреЛ рдкреГрд╖реНрдарднреВрдорд┐ рдХреЗ рдзрд╛рдЧреЗ рдореЗрдВ рдЕрдЧреНрд░рд┐рдо рдореЗрдВ рдЯреЗрдХреНрд╕реНрдЯ рдЖрдХрд╛рд░ рдХреЛ рдорд╛рдкрдиреЗ рдХреЗ рдЪрд░рдг рдХреЛ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рд╣реИ - PrecomputedText (рдФрд░ Android I (14) - PrecomputedTextCompat рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП рдмреИрдХрдкреЛрд░реНрдЯ)ред рдирдИ рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, 90% рдХрд╛рдо рдкреГрд╖реНрдарднреВрдорд┐ рдереНрд░реЗрдб рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред


рдПрдХ рдЙрджрд╛рд╣рд░рдг:


 // UI thread val params: PrecomputedText.Params = textView.getTextMetricsParams() val ref = WeakReference(textView) executor.execute { // background thread val text = PrecomputedText.create("Hello", params) val textView = ref.get() textView?.post { // UI thread val textView = ref.get() textView?.text = text } } 

рдмрдбрд╝рд╛ рдкрд╛рда рджрд┐рдЦрд╛рдУ


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


RecyclerView рдореЗрдВ PrecomputedText рдХреА рдПрдореНрдмреЗрдбрд┐рдВрдЧ рдХреА рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, Google рдбреЗрд╡рд▓рдкрд░реНрд╕ рдиреЗ PrecomputedTextCompat.getTextFuture() рдФрд░ AppCompatTextView.setTextFuture() рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖ рддрд░реАрдХреЗ рдмрдирд╛рдПред


 fun onBindViewHolder(vh: ViewHolder, position: Int) { val data = getData(position) vh.textView.setTextSize(...) vh.textView.setFontVariationSettings(...) //    val future = PrecomputedTextCompat.getTextFuture( data.text, vh.textView.getTextMetricsParamsCompat(), myExecutor ) //  future  TextView,      onMeasure() vh.textView.setTextFuture(future) } 

RecyclerView , , , .


, getTextFuture() (, ), , , getTextFuture() , , TextView.


, TextView


TextView.setText() :


 if (type == SPANNABLE || movementMethod != null) { text = spannableFactory.newSpannable(spannable) //  } else { text = new SpannedString(spannable) //  } 

span' TextView, setText() , .


, . TextView , -, . , . , , TextView spannableFactory :


 class MySpannableFactory : Spannable.Factory() { override fun newSpannable(source: CharSequence): Spannable { return source as? Spannable ?: super.newSpannable(source) } } textView.spannableFactory = MySpannableFactory() 

textView.setText(spannable, BufferType.SPANNABLE) , .


Google span' RecyclerView, .


TextView, span, setText() . TextView span. TextView spannable- span', :


 val spannable = textView.getText() as Spannable val span = CustomTypefaceSpan(span) spannable.setSpan(span, ...) 

span, TextView, TextView . , invalidate() , тАУ requestLayout() :


 val spannable = textView.getText() as Spannable val span = CustomTypefaceSpan(span) spannable.setSpan(span, ...) span.setTypeface(anotherTypeface) textView.requestLayout() // re-measure and re-draw // or textView.invalidate() // re-draw 


TextView . autoLink . autoLink=тАЭwebтАЭ TextView URL URLSpan . , SDK setText() :


 spannable = new SpannableString(string); Matcher m = pattern.matcher(text); while (...) { //      String utl = тАж URLSpan span = new URLSpan(url); spannable.setSpan(span, ...); } 

UI , autoLink=тАЭwebтАЭ RecyclerView. . LinkifyCompat :


 //  ,       background thread val spannable = SpannableString(string) LinkifyCompat.addLinks(spannable, Linkify.WEB_URLS) //   RecyclerView override fun onBindViewHolder(holder: ViewHolder, position: Int) { holder.textView.setText(spannable, BufferType.SPANNABLE) // ... } 

autoLink map тАУ ( all ). . , WebView, ! SDK Linkify.gatherMapLinks() , :


 while ((address = WebView.findAddress(string)) != null) { ... } 

WebView TODO SDK:


 public static String findAddress(String addr) { // TODO: Rewrite this in Java so it is not needed to start up chromium // Could also be deprecated return getFactory().getStatics().findAddress(addr); } 

? Smart Linkify, Android P (28) , , . :


 // UI thread val text: Spannable = тАж val request = TextLinks.Request.Builder(text) val ref = WeakReference(textView) executor.execute { // background thread TextClassifier.generateLinks(request).apply(text) val textView = ref.get() textView?.post { // UI thread val textView = ref.get() textView?.text = text } } 

Linkify, . toolbar , Google .


Smart Linkify : , .



Magnifier


Android P (28) , тАУ Magnifier, . .



TextView, EditText WebView, : API .


рдирд┐рд╖реНрдХрд░реНрд╖


Android , , :


  • , TextView (, EditText)

- , Google I/O'19 тАЬBest Practices for Using Text in AndroidтАЭ .



рдЙрдкрдпреЛрдЧреА рд▓рд┐рдВрдХ




рд░рд┐рдкреЛрд░реНрдЯ


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


All Articles