RecyclerView рдХреЗ рдкреЗрд╢реЗрд╡рд░ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рд╕реБрдЭрд╛рд╡ред рднрд╛рдЧ реи

RecyclerView рдХреЗ рдкреЗрд╢реЗрд╡рд░ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рд╕реБрдЭрд╛рд╡ред рднрд╛рдЧ реи


рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рдХреЛ рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реБрдП, рдЗрд╕рдореЗрдВ рдореИрдВ ItemDecoration рдФрд░ ItemAnimator рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд ItemDecoration рдФрд░ рдПрдХ рд╕рд░рд▓ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ RecyclerView рдореЗрдВ рдЙрдирдХреЗ рдХрд╛рдо рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЛ рд╕рдордЭрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддрд╛ рд╣реВрдБ рдЬреЛ рдХрд┐ Github рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИред


1. рдорджрдХрд░рдг


ItemDecoration рдЙрдкрдпреЛрдЧ RecyclerView рдореЗрдВ рд╕реВрдЪреА рдЖрдЗрдЯрдо рдХреЛ рд╕рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


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


 mDividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), mLayoutManager.getOrientation()); recyclerView.addItemDecoration(mDividerItemDecoration); 

рдЕрдкрдирд╛ рд╕реНрд╡рдпрдВ рдХрд╛ рд╡рд┐рднрд╛рдЬрдХ рдмрдирд╛рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рд╣реИ RecyclerView.ItemDecoration рд╡рд░реНрдЧ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдирд╛ред рдирдореВрдирд╛ рдЖрд╡реЗрджрди рдореЗрдВ, рдореИрдВрдиреЗ GridLayoutManager рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдФрд░ RecyclerView рд▓рд┐рдП CharacterItemDecoration рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛:


 recyclerView.addItemDecoration(new CharacterItemDecoration(50)); 

рдпрд╣рд╛рдБ CharacterItemDecoration рдЕрдкрдиреЗ рдирд┐рд░реНрдорд╛рддрд╛ рдХреЛ 50 рдкрд┐рдХреНрд╕реЗрд▓ рдореЗрдВ рдСрдлрд╕реЗрдЯ ( engред рдСрдлрд╕реЗрдЯ) рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ рдФрд░ getItemOffsets(...) рдУрд╡рд░рд░рд╛рдЗрдб getItemOffsets(...) ред getItemOffsets() рд╡рд┐рдзрд┐ рдХреЗ рдЕрдВрджрд░, рдкреНрд░рддреНрдпреЗрдХ outRects рдлрд╝реАрд▓реНрдб рдЗрдВрдбреЗрдВрдЯреЗрд╢рди рдФрд░ рдЗрдВрдбреЗрдВрдЯреЗрд╢рди рдХреЗ рд╕рдорд╛рди рдкреНрд░рддреНрдпреЗрдХ view рдШрдЯрдХ рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдкрд┐рдХреНрд╕реЗрд▓ рдХреА рд╕рдВрдЦреНрдпрд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИред рдЪреВрдБрдХрд┐ рдореИрдВрдиреЗ GridLayoutManager рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдерд╛ рдФрд░ рдЧреНрд░рд┐рдб рддрддреНрд╡реЛрдВ рдХреЗ рдмреАрдЪ рд╕рдорд╛рди рджреВрд░реА рддрдп рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдкреНрд░рддреНрдпреЗрдХ рд╕рдорд╛рди рддрддреНрд╡ рдХреЗ рд▓рд┐рдП 25 рдкрд┐рдХреНрд╕реЗрд▓ (рдпрд╛рдиреА рдСрдлрд╕реЗрдЯ / 2) рдХреЗ рджрд╛рдИрдВ рдУрд░ рдЗрдВрдбреЗрдВрдЯ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реВрдВ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рд╖рдо рддрддреНрд╡ рдХреЗ рдмрд╛рдИрдВ рдУрд░ 25 рдкрд┐рдХреНрд╕реЗрд▓ рддрдХ рдЗрдВрдбреЗрдВрдЯ рдХрд░рддрд╛ рд╣реВрдВ, рдЬрдмрдХрд┐ рд╢реАрд░реНрд╖ рдЗрдВрдбреЗрдВрдЯ рдХреЛ рд╕рдорд╛рди рд░рдЦрддрд╛ рд╣реВрдВред рд╕рднреА рддрддреНрд╡реЛрдВ рдХреЗ рд▓рд┐рдПред


рдЧреНрд░рд┐рдб рдЗрдВрдбреЗрдВрдЯреЗрд╢рди


2. рдЖрдЗрдЯрдордПрдиреАрдореЗрдЯрд░


ItemAnimator рдЙрдкрдпреЛрдЧ RecyclerView рдЕрдВрджрд░ рддрддреНрд╡реЛрдВ рдХреЛ view рдпрд╛ рдШрдЯрдХреЛрдВ рдХреЛ view рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


рдПрдХ рд╕реВрдЪреА рдореЗрдВ рдЖрдЗрдЯрдо рдЪреЗрддрди


рдЪрд▓рд┐рдП DefaultItemAnimator рдХреЛ рдмрдврд╝рд╛рдХрд░ рдФрд░ рдХрдИ рддрд░реАрдХреЛрдВ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдХреЗ рдЕрдкрдиреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдЗрдВрд╕реНрдЯрд╛рдЧреНрд░рд╛рдо рдХреА рддрд░рд╣ рдмрдирд╛рддреЗ рд╣реИрдВред


 public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder) { return true; } 

canReuseUpdatedViewHolder(...) рд╡рд┐рдзрд┐ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреА рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЗрд╕ рддрддреНрд╡ рдХреЗ рдбреЗрдЯрд╛ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рд╣реЛрдиреЗ рдкрд░ рд╕рдорд╛рди ViewHolder рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ ViewHolder ред рдпрджрд┐ рдпрд╣ false , рддреЛ ViewHolders - рдкреБрд░рд╛рдиреЗ рдФрд░ рдЕрджреНрдпрддрди - рджреЛрдиреЛрдВ рдХреЛ animateChange(...) рд╡рд┐рдзрд┐ рд╕реЗ рдкрд╛рд░рд┐рдд рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


 public ItemHolderInfo recordPreLayoutInformation(@NonNull RecyclerView.State state, @NonNull RecyclerView.ViewHolder viewHolder, int changeFlags, @NonNull List<Object> payloads) { if (changeFlags == FLAG_CHANGED) { for (Object payload : payloads) { if (payload instanceof String) { return new CharacterItemHolderInfo((String) payload); } } } return super.recordPreLayoutInformation(state, viewHolder, changeFlags, payloads); } public static class CharacterItemHolderInfo extends ItemHolderInfo { public String updateAction; public CharacterItemHolderInfo(String updateAction) { this.updateAction = updateAction; } } 

RecyclerView layout рд░реЗрдВрдбрд░рд┐рдВрдЧ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП recordPreLayoutInformation(...) рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИред ItemAnimator рдХреЛ view рдШрдЯрдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдЬрд╛рдирдХрд╛рд░реА рд░рд┐рдХреЙрд░реНрдб рдХрд░рдиреЗ, рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ, рд╣рдЯрд╛рдиреЗ рдпрд╛ рд╣рдЯрд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рджрд░реНрдЬ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕ рд╡рд┐рдзрд┐ рджреНрд╡рд╛рд░рд╛ рд▓реМрдЯрд╛рдП рдЧрдП рдбреЗрдЯрд╛ рдХреЛ рд╕рдВрдмрдВрдзрд┐рдд рдПрдиреАрдореЗрд╢рди рд╡рд┐рдзрд┐ (рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ animateChange(...) рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред


 @Override public boolean animateChange(@NonNull RecyclerView.ViewHolder oldHolder, @NonNull RecyclerView.ViewHolder newHolder, @NonNull ItemHolderInfo preInfo, @NonNull ItemHolderInfo postInfo) { if (preInfo instanceof CharacterItemHolderInfo) { CharacterItemHolderInfo recipesItemHolderInfo = (CharacterItemHolderInfo) preInfo; CharacterRVAdapter.CharacterViewHolder holder = (CharacterRVAdapter.CharacterViewHolder) newHolder; if (CharacterRVAdapter.ACTION_LIKE_IMAGE_DOUBLE_CLICKED.equals(recipesItemHolderInfo.updateAction)) { animatePhotoLike(holder); } } return false; } private void animatePhotoLike(final CharacterRVAdapter.CharacterViewHolder holder) { holder.likeIV.setVisibility(View.VISIBLE); holder.likeIV.setScaleY(0.0f); holder.likeIV.setScaleX(0.0f); AnimatorSet animatorSet = new AnimatorSet(); ObjectAnimator scaleLikeIcon = ObjectAnimator.ofPropertyValuesHolder (holder.likeIV, PropertyValuesHolder.ofFloat("scaleX", 0.0f, 2.0f), PropertyValuesHolder.ofFloat("scaleY", 0.0f, 2.0f), PropertyValuesHolder.ofFloat("alpha", 0.0f, 1.0f, 0.0f)); scaleLikeIcon.setInterpolator(DECELERATE_INTERPOLATOR); scaleLikeIcon.setDuration(1000); ObjectAnimator scaleLikeBackground = ObjectAnimator.ofPropertyValuesHolder (holder.characterCV, PropertyValuesHolder.ofFloat("scaleX", 1.0f, 0.95f, 1.0f), PropertyValuesHolder.ofFloat("scaleY", 1.0f, 0.95f, 1.0f)); scaleLikeBackground.setInterpolator(DECELERATE_INTERPOLATOR); scaleLikeBackground.setDuration(600); animatorSet.playTogether(scaleLikeIcon, scaleLikeBackground); animatorSet.start(); } 

RecyclerView , animateChange(...) рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ, рдЬрдм рдПрдбреЗрдкреНрдЯрд░ рддрддреНрд╡, notifyItemChanged(int) рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдФрд░ рдмрд╛рдж рдореЗрдВ рджреЛрдиреЛрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рддрдм рднреА рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬрдм notifyDataSetChanged() рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрджрд┐ рдПрдбреЗрдкреНрдЯрд░ рд╕реНрдерд┐рд░ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рддрд╛рдХрд┐ RecyclerView рд╕рдорд╛рди ViewHolders рдореЗрдВ view рдШрдЯрдХреЛрдВ рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХреЗред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрд╣ рд╡рд┐рдзрд┐ рддрд░реНрдХреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗрддреА рд╣реИ: (ViewHolder oldHolder, ViewHolder newHolder, ItemHolderInfo preInfo, ItemHolderInfo postInfo) ред рдЪреВрдВрдХрд┐ рд╣рдо ViewHolder рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдкреБрд░рд╛рдиреЗ рдлрд╝реЛрд▓реНрдбрд░ рдФрд░ newHolder рджреЛрдиреЛрдВ рд╕рдорд╛рди рд╣реИрдВред


рдЬрдм рднреА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд┐рд╕реА рднреА рдЖрдЗрдЯрдо рдкрд░ рдбрдмрд▓-рдХреНрд▓рд┐рдХ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдирд┐рдореНрди рд╡рд┐рдзрд┐ рдХрд╣рд▓рд╛рддреА рд╣реИ:


 notifyItemChanged(position, ACTION_LIKE_IMAGE_DOUBLE_CLICKED); 

рдпрд╣ рдХреЙрд▓ рдХреА рдкреВрд░реА рд╢реНрд░реГрдВрдЦрд▓рд╛ рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИ: canReuseUpdatedViewHolder(...) , recordPreLayoutInformation(...) рдФрд░, рдЖрдЦрд┐рд░рдХрд╛рд░, animateChange(...) , рдЬреЛ рдмрджрд▓реЗ рдореЗрдВ, рдЗрд╕ рдордж рдореЗрдВ рд╕реВрдЪреА рдЖрдЗрдЯрдо рдФрд░ рд╣реГрджрдп рдЖрдЗрдХрди рдХреЛ рдПрдирд┐рдореЗрдЯ рдХрд░рддрд╛ рд╣реИ ( рдКрдкрд░ GIF рдореЗрдВ рдЙрджрд╛рд╣рд░рдг)ред


рдпрд╣ RecyclerView рдмрд╛рд░реЗ рдореЗрдВ рд▓реЗрдЦреЛрдВ рдХреА рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХрд╛ рджреВрд╕рд░рд╛ рднрд╛рдЧ рд╣реИред рдпрджрд┐ рдЖрдк рдкрд╣рд▓реЗ рднрд╛рдЧ рд╕реЗ рдЪреВрдХ рдЧрдП рд╣реИрдВ, рддреЛ рдЗрд╕реЗ рдпрд╣рд╛рдБ рдкрдврд╝реЗрдВред


RecyclerView рдкрд░ рдХреБрдЫ рдФрд░ рдЕрдЪреНрдЫреЗ рд▓реЗрдЦ:



тЖР рдкреЗрд╢реЗрд╡рд░ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдЯрд┐рдкреНрд╕ RecyclerViewред рднрд╛рдЧ 1

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


All Articles