Advertisement
Guest User

Untitled

a guest
Jul 21st, 2017
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.10 KB | None | 0 0
  1. public class ExpandableRecyclerView extends RecyclerView {
  2. public ExpandableRecyclerView(Context context) {
  3. super(context, null);
  4. initRecycler();
  5. }
  6.  
  7. public ExpandableRecyclerView(Context context, AttributeSet attrs) {
  8. super(context, attrs);
  9. initRecycler();
  10. }
  11.  
  12. public ExpandableRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {
  13. super(context, attrs, defStyleAttr);
  14. initRecycler();
  15. }
  16.  
  17. private void initRecycler() {
  18. setClipToPadding(false);
  19. setItemAnimator(new DefaultItemAnimator());
  20.  
  21. }
  22.  
  23. @Override
  24. public Parcelable onSaveInstanceState() {
  25. //begin boilerplate code that allows parent classes to save state
  26. Parcelable superState = super.onSaveInstanceState();
  27.  
  28. SavedState ss = new SavedState(superState);
  29. //end
  30.  
  31. if (getAdapter() != null)
  32. ss.stateToSave = ((Adapter) this.getAdapter()).getExpandedGroups();
  33.  
  34. return ss;
  35. }
  36.  
  37. @Override
  38. public void onRestoreInstanceState(Parcelable state) {
  39. //begin boilerplate code so parent classes can restore state
  40. if (!(state instanceof SavedState)) // if state is not instance of out SaveState just restore in reg way
  41. {
  42. super.onRestoreInstanceState(state);
  43. return;
  44. }
  45. // else if cast him to SavedState
  46.  
  47. SavedState ss = (SavedState) state;
  48. super.onRestoreInstanceState(ss.getSuperState());
  49. //end
  50.  
  51. if (getAdapter() != null)
  52. ((Adapter) getAdapter()).setExpandedGroups(ss.stateToSave);
  53. }
  54.  
  55. @Override
  56. public void setAdapter(RecyclerView.Adapter adapter) {
  57. if (!(adapter instanceof Adapter))
  58. throw new IllegalArgumentException("adapter has to be of type ExpandableRecyclerView.Adapter");
  59. super.setAdapter(adapter);
  60. }
  61.  
  62.  
  63. public interface OnChildItemClickedListener {
  64. void onChildItemClicked(int group, int position);
  65. }
  66.  
  67. static class SavedState implements Parcelable {
  68. public static final SavedState EMPTY_STATE = new SavedState() {
  69. };
  70. //required field that makes Parcelables from a Parcel
  71. public static final Creator<SavedState> CREATOR =
  72. new Creator<SavedState>() {
  73. public SavedState createFromParcel(Parcel in) {
  74. return new SavedState(in);
  75. }
  76.  
  77. public SavedState[] newArray(int size) {
  78. return new SavedState[size];
  79. }
  80. };
  81. SparseBooleanArray stateToSave;
  82. Parcelable superState;
  83.  
  84. SavedState() {
  85. superState = null;
  86. }
  87.  
  88. SavedState(Parcelable superState) {
  89. this.superState = superState != EMPTY_STATE ? superState : null;
  90. }
  91.  
  92. private SavedState(Parcel in) {
  93. Parcelable superState = in.readParcelable(ExpandableRecyclerView.class.getClassLoader());
  94. this.superState = superState != null ? superState : EMPTY_STATE;
  95. this.stateToSave = in.readSparseBooleanArray();
  96. }
  97.  
  98. @Override
  99. public int describeContents() {
  100. return 0;
  101. }
  102.  
  103. @Override
  104. public void writeToParcel(@NonNull Parcel out, int flags) {
  105. out.writeParcelable(superState, flags);
  106. out.writeSparseBooleanArray(this.stateToSave);
  107. }
  108.  
  109. public Parcelable getSuperState() {
  110. return superState;
  111. }
  112. }
  113.  
  114. public static abstract class Adapter<CVH extends ViewHolder, GVH extends ViewHolder, C, G> extends RecyclerView.Adapter<ViewHolder> {
  115.  
  116. private static final int TYPE_HEADER = 0;
  117. SparseBooleanArray expanded = new SparseBooleanArray();
  118. private OnChildItemClickedListener onChildItemClickedListener;
  119.  
  120. public Adapter() {
  121. }
  122.  
  123. boolean isExpanded(int group) {
  124. return expanded.get(group);
  125. }
  126.  
  127. SparseBooleanArray getExpandedGroups() {
  128. return expanded;
  129. }
  130.  
  131. public void setExpandedGroups(SparseBooleanArray expanded) {
  132. this.expanded = expanded;
  133. }
  134.  
  135. public void expand(int group) {
  136. if (isExpanded(group))
  137. return;
  138.  
  139. // this lines of code calculate number of shown item in recycler view. also group is counting .
  140. int position = 0;
  141. for (int i = 0; i < group; i++) {
  142. position++;
  143. if (isExpanded(i))
  144. position += getChildItemCount(i);
  145. }
  146. position++; // this for percent group
  147.  
  148. notifyItemRangeInserted(position, getChildItemCount(group)); // notify recycler view for expanding
  149. expanded.put(group, true); // save expanding in sparce array
  150. }
  151.  
  152. public void collapse(int group) {
  153. if (!isExpanded(group)) // if is not expanded . so nothing to collapse.
  154. return;
  155.  
  156. int position = 0;
  157. for (int i = 0; i < group; i++) {
  158. position++;
  159. if (isExpanded(i))
  160. position += getChildItemCount(i); // item
  161. }
  162. position++;
  163. notifyItemRangeRemoved(position, getChildItemCount(group));
  164. expanded.put(group, false);
  165. }
  166.  
  167. public abstract int getGroupItemCount();
  168.  
  169. public abstract int getChildItemCount(int group);
  170.  
  171. @Override
  172. public int getItemCount() {
  173. int count = 0;
  174. for (int i = 0; i <= getGroupItemCount(); i++) {
  175. count += isExpanded(i) ? getChildItemCount(i) + 1 : 1;
  176. }
  177. return count;
  178. }
  179.  
  180. public abstract G getGroupItem(int position);
  181.  
  182. public abstract C getChildItem(int group, int position);
  183.  
  184. public Object getItem(int i) {
  185. int group = 0;
  186. while (group <= getGroupItemCount()) {
  187. if (i > 0 && !isExpanded(group)) {
  188. i--;
  189. group++;
  190. continue;
  191. }
  192. if (i > 0 && isExpanded(group)) {
  193. i--;
  194. if (i < getChildItemCount(group))
  195. return getChildItem(group, i);
  196. i -= getChildItemCount(group);
  197. group++;
  198. continue;
  199. }
  200. if (i == 0)
  201. return getGroupItem(group);
  202. }
  203. throw new IndexOutOfBoundsException();
  204. }
  205.  
  206. @Override
  207. public void onBindViewHolder(ViewHolder holder, int i) {
  208. int group = 0;
  209. while (group <= getGroupItemCount()) {
  210. if (i > 0 && !isExpanded(group)) {
  211. i--;
  212. group++;
  213. continue;
  214. }
  215. if (i > 0 && isExpanded(group)) {
  216. i--;
  217. if (i < getChildItemCount(group)) {
  218. onBindChildViewHolder((CVH) holder, group, i);
  219. return;
  220. }
  221. i -= getChildItemCount(group);
  222. group++;
  223. continue;
  224. }
  225. if (i == 0) {
  226. onBindGroupViewHolder((GVH) holder, group);
  227. return;
  228. }
  229. }
  230. throw new IndexOutOfBoundsException();
  231. }
  232.  
  233. @Override
  234. public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  235. return viewType == TYPE_HEADER ? onCreateGroupViewHolder(parent) : onCreateChildViewHolder(parent, viewType);
  236. }
  237.  
  238. protected abstract GVH onCreateGroupViewHolder(ViewGroup parent);
  239.  
  240. protected abstract CVH onCreateChildViewHolder(ViewGroup parent, int viewType);
  241.  
  242. public abstract int getChildItemViewType(int group, int position);
  243.  
  244. @Override
  245. public int getItemViewType(int i) {
  246. int group = 0;
  247. while (group <= getGroupItemCount()) {
  248. if (i > 0 && !isExpanded(group)) {
  249. i--;
  250. group++;
  251. continue;
  252. }
  253. if (i > 0 && isExpanded(group)) {
  254. i--;
  255. if (i < getChildItemCount(group))
  256. return getChildItemViewType(group, i);
  257. i -= getChildItemCount(group);
  258. group++;
  259. continue;
  260. }
  261. if (i == 0)
  262. return TYPE_HEADER;
  263. }
  264. throw new IndexOutOfBoundsException();
  265. }
  266.  
  267. public void setOnChildItemClickedListener(OnChildItemClickedListener onItemClickedListener) {
  268. this.onChildItemClickedListener = onItemClickedListener;
  269. }
  270.  
  271. public void onBindChildViewHolder(CVH holder, final int group, final int position) {
  272. holder.itemView.setOnClickListener(new OnClickListener() {
  273. public void onClick(View v) {
  274. if (Adapter.this.onChildItemClickedListener != null) {
  275. Adapter.this.onChildItemClickedListener.onChildItemClicked(group, position);
  276. }
  277.  
  278. }
  279. });
  280. }
  281.  
  282. public void onBindGroupViewHolder(final GVH holder, final int group) {
  283. if (holder instanceof GroupViewHolder)
  284. ((GroupViewHolder) holder).setExpanded(isExpanded(group));
  285.  
  286. holder.itemView.setOnClickListener(new OnClickListener() {
  287. @Override
  288. public void onClick(View v) {
  289. if (isExpanded(group)) {
  290. collapse(group);
  291. if (holder instanceof GroupViewHolder)
  292. ((GroupViewHolder) holder).collapse();
  293. } else {
  294. expand(group);
  295. if (holder instanceof GroupViewHolder)
  296. ((GroupViewHolder) holder).expand();
  297. }
  298. }
  299. });
  300. }
  301. }
  302.  
  303. public static abstract class GroupViewHolder extends ViewHolder {
  304.  
  305. public GroupViewHolder(View itemView) {
  306. super(itemView);
  307. }
  308.  
  309. public abstract void expand();
  310.  
  311. public abstract void collapse();
  312.  
  313. public abstract boolean isExpanded();
  314.  
  315. public abstract void setExpanded(boolean expanded);
  316. }
  317.  
  318. public static class SimpleGroupViewHolder extends GroupViewHolder {
  319. ImageView expandedIndicator;
  320. TextView text;
  321. private boolean expanded;
  322.  
  323. public SimpleGroupViewHolder(Context context) {
  324. super(View.inflate(context, R.layout.group_header, null));
  325.  
  326. itemView.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
  327. expandedIndicator = (ImageView) itemView.findViewById(R.id.carbon_groupExpandedIndicator);
  328. text = (TextView) itemView.findViewById(R.id.carbon_groupText);
  329. }
  330.  
  331. public SimpleGroupViewHolder(Context context, int layout) {
  332. super(View.inflate(context, layout, null));
  333.  
  334. itemView.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
  335. expandedIndicator = (ImageView) itemView.findViewById(R.id.carbon_groupExpandedIndicator);
  336. text = (TextView) itemView.findViewById(R.id.carbon_groupText);
  337. }
  338.  
  339. public void expand() {
  340. ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
  341. animator.setInterpolator(new DecelerateInterpolator());
  342. animator.setDuration(200);
  343. animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
  344. @Override
  345. public void onAnimationUpdate(ValueAnimator animation) {
  346. ViewHelper.setRotation(expandedIndicator, 180 * (float) (animation.getAnimatedValue()));
  347. expandedIndicator.postInvalidate();
  348. }
  349. });
  350. animator.start();
  351. expanded = true;
  352. }
  353.  
  354. public void collapse() {
  355. ValueAnimator animator = ValueAnimator.ofFloat(1, 0);
  356. animator.setInterpolator(new DecelerateInterpolator());
  357. animator.setDuration(200);
  358. animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
  359. @Override
  360. public void onAnimationUpdate(ValueAnimator animation) {
  361. ViewHelper.setRotation(expandedIndicator, 180 * (float) (animation.getAnimatedValue()));
  362. expandedIndicator.postInvalidate();
  363. }
  364. });
  365. animator.start();
  366. expanded = false;
  367. }
  368.  
  369. @Override
  370. public boolean isExpanded() {
  371. return expanded;
  372. }
  373.  
  374. public void setExpanded(boolean expanded) {
  375. ViewHelper.setRotation(expandedIndicator, expanded ? 180 : 0);
  376. this.expanded = expanded;
  377. }
  378.  
  379. public String getText() {
  380. return text.getText().toString();
  381. }
  382.  
  383. public void setText(String t) {
  384. text.setText(t);
  385. }
  386. }
  387.  
  388. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement