onSegmentClickListener) {
429 | getControllerComponent().addOnSegmentClickListener(onSegmentClickListener);
430 | }
431 |
432 | /**
433 | * @param onSegmentClickListener, every time click event will be notified,
434 | * even if the segment is already selected
435 | *
436 | * Remove listener
437 | */
438 | public void removeOnSegmentClickListener(OnSegmentClickListener onSegmentClickListener) {
439 | getControllerComponent().removeOnSegmentClickListener(onSegmentClickListener);
440 | }
441 |
442 | /**
443 | * @param onSegmentSelectedListener, event will be notified, when segment is selected and unSelected and reselected,
444 | * for more info check out {@link OnSegmentSelectedListener} class
445 | */
446 | public void addOnSegmentSelectListener(OnSegmentSelectedListener onSegmentSelectedListener) {
447 | getControllerComponent().addOnSegmentSelectListener(onSegmentSelectedListener);
448 | }
449 |
450 | /**
451 | * @param onSegmentSelectedListener, event will be notified, when segment is selected and unSelected and reselected,
452 | * for more info check out {@link OnSegmentSelectedListener} class
453 | *
454 | * Remove listener
455 | */
456 | public void removeOnSegmentSelectListener(OnSegmentSelectedListener onSegmentSelectedListener) {
457 | getControllerComponent().removeOnSegmentSelectListener(onSegmentSelectedListener);
458 | }
459 |
460 | /**
461 | * @param onSegmentSelectRequestListener, event will be triggered after click event and before selection event
462 | * for more info click out {@link OnSegmentSelectRequestListener} class
463 | */
464 | public void setOnSegmentSelectRequestListener(OnSegmentSelectRequestListener onSegmentSelectRequestListener) {
465 | getControllerComponent().setOnSegmentSelectRequestListener(onSegmentSelectRequestListener);
466 | }
467 |
468 | /**
469 | * Removes all segments
470 | */
471 | public void removeAllSegments() {
472 | getControllerComponent().removeAllSegments();
473 | }
474 |
475 | /**
476 | * find the segment view holder with the segment absolute position
477 | *
478 | * @param position, the segment position
479 | * @return SegmentViewHolder instance for specified position
480 | */
481 | public SegmentViewHolder findSegmentByAbsolutePosition(int position) {
482 | Assert.outOfBounds(position, size(), "SegmentedControl#findSegmentByAbsolutePosition");
483 | return getControllerComponent().findSegmentByAbsolutePosition(position);
484 | }
485 |
486 | /**
487 | * find the segment with column number and row position
488 | *
489 | * @param column, Segment column number
490 | * @param row, Segment row position
491 | * @return SegmentViewHolder instance for specified column and row numbers
492 | */
493 | public SegmentViewHolder findSegmentByColumnAndRow(int column, int row) {
494 | Assert.outOfBounds(getControllerComponent().getAbsolutePosition(column, row), size(), "SegmentedControl#setSelectedSegment");
495 | return getControllerComponent().findSegmentByColumnAndRow(column, row);
496 | }
497 |
498 | /**
499 | * Select the selected position
500 | *
501 | * @param position, Segment position
502 | */
503 | public void setSelectedSegment(int position) {
504 | Assert.outOfBounds(position, size(), "SegmentedControl#setSelectedSegment");
505 | getControllerComponent().setSelectedSegment(position);
506 | }
507 |
508 | /**
509 | * Select the segment with specified column number and row position
510 | *
511 | * @param column, Segment column number
512 | * @param row, Segment row position
513 | */
514 | public void setSelectedSegment(int column, int row) {
515 | Assert.outOfBounds(getControllerComponent().getAbsolutePosition(column, row), size(), "SegmentedControl#setSelectedSegment");
516 | getControllerComponent().setSelectedSegment(column, row);
517 | }
518 |
519 | /**
520 | * Iterate on segments, and pass the view holders as an argument for {@link SegmentConsumer}
521 | *
522 | * @param segmentConsumer, Segment consumer
523 | */
524 | public void forEachSegment(SegmentConsumer segmentConsumer) {
525 | getControllerComponent().forEachSegment(segmentConsumer);
526 | }
527 |
528 | public void setSelectedStrokeColor(int color) {
529 | getControllerComponent().setSelectedStrokeColor(color);
530 | }
531 |
532 | public void setUnSelectedStrokeColor(int color) {
533 | getControllerComponent().setUnSelectedStrokeColor(color);
534 | }
535 |
536 | public void setFocusedBackgroundColor(int color) {
537 | getControllerComponent().setFocusedBackgroundColor(color);
538 | }
539 |
540 | /**
541 | * Set segments selection animation duration value
542 | *
543 | * @param duration in milliseconds
544 | */
545 | public void setSelectionAnimationDuration(int duration) {
546 | getControllerComponent().setSelectionAnimationDuration(duration);
547 | }
548 |
549 | public void setStrokeWidth(int width) {
550 | getControllerComponent().setStrokeWidth(width);
551 | }
552 |
553 | public void setSelectedBackgroundColor(int color) {
554 | getControllerComponent().setSelectedBackgroundColor(color);
555 | }
556 |
557 | public void setUnSelectedBackgroundColor(int color) {
558 | getControllerComponent().setUnSelectedBackgroundColor(color);
559 | }
560 |
561 | public void setSelectedTextColor(int color) {
562 | getControllerComponent().setSelectedTextColor(color);
563 | }
564 |
565 | public void setUnSelectedTextColor(int color) {
566 | getControllerComponent().setUnSelectedTextColor(color);
567 | }
568 |
569 | public void setTextSize(int textSize) {
570 | getControllerComponent().setTextSize(textSize);
571 | }
572 |
573 | public void setTypeFace(Typeface typeFace) {
574 | getControllerComponent().setTypeFace(typeFace);
575 | }
576 |
577 | public void setTextVerticalPadding(int padding) {
578 | getControllerComponent().setTextVerticalPadding(padding);
579 | }
580 |
581 | public void setTextHorizontalPadding(int padding) {
582 | getControllerComponent().setTextHorizontalPadding(padding);
583 | }
584 |
585 | public void setSegmentVerticalMargin(int margin) {
586 | getControllerComponent().setSegmentVerticalMargin(margin);
587 | }
588 |
589 | public void setSegmentHorizontalMargin(int margin) {
590 | getControllerComponent().setSegmentHorizontalMargin(margin);
591 | }
592 |
593 | public void setRadius(int radius) {
594 | getControllerComponent().setRadius(radius);
595 | }
596 |
597 | public void setTopLeftRadius(int radius) {
598 | getControllerComponent().setTopLeftRadius(radius);
599 | }
600 |
601 | public void setTopRightRadius(int radius) {
602 | getControllerComponent().setTopRightRadius(radius);
603 | }
604 |
605 | public void setBottomRightRadius(int radius) {
606 | getControllerComponent().setBottomRightRadius(radius);
607 | }
608 |
609 | public void setBottomLeftRadius(int radius) {
610 | getControllerComponent().setBottomLeftRadius(radius);
611 | }
612 |
613 | /**
614 | * @param radiusForEverySegment, true every segment corners will be rounded, false only top left,top right, bottom right and bottom left corners will be rounded
615 | */
616 | public void setRadiusForEverySegment(boolean radiusForEverySegment) {
617 | getControllerComponent().setRadiusForEverySegment(radiusForEverySegment);
618 | }
619 |
620 | /**
621 | * Removes the last selected segment selection, SegmentViewHolder's onSegmentSelected method will be called
622 | * with isSelected = false, isReselected = false
623 | */
624 | public void clearSelection() {
625 | getControllerComponent().clearSelection(false);
626 | }
627 |
628 | /**
629 | * Removes the last selected segment selection, SegmentViewHolder's onSegmentSelected method will be called
630 | * with isSelected = false, isReselected = false.
631 | *
632 | * @param notifySegmentSelectedListener if true SegmentSelectedListeners will be notified.
633 | */
634 | public void clearSelection(boolean notifySegmentSelectedListener) {
635 | getControllerComponent().clearSelection(notifySegmentSelectedListener);
636 | }
637 |
638 | /**
639 | * Call this method after every configuration change
640 | * setColumnCount, setRadius et...
641 | */
642 | public void notifyConfigIsChanged() {
643 | getControllerComponent().notifyConfigIsChanged();
644 | }
645 |
646 | public int size() {
647 | return getControllerComponent().size();
648 | }
649 |
650 | // public SegmentViewHolder getSelectedViewHolder() {
651 | // return getControllerComponent().getSelectedViewHolder();
652 | // }
653 |
654 | /**
655 | * @return int[]{column,row} Section column and row numbers
656 | */
657 | public int[] getLastSelectedColumnAndRow() {
658 | return getControllerComponent().getLastSelectedColumnAndRow();
659 | }
660 |
661 | public int getLastSelectedAbsolutePosition() {
662 | return getControllerComponent().getLastSelectedAbsolutePosition();
663 | }
664 |
665 | public boolean hasSelectedSegment() {
666 | return getControllerComponent().isSelected();
667 | }
668 | }
669 |
--------------------------------------------------------------------------------
/segmentedcontrolmodule/src/main/java/segmented_control/widget/custom/android/com/segmentedcontrol/SegmentedControlControllerComponent.java:
--------------------------------------------------------------------------------
1 | package segmented_control.widget.custom.android.com.segmentedcontrol;
2 |
3 | import android.graphics.Typeface;
4 | import android.support.annotation.Nullable;
5 |
6 | import java.util.ArrayList;
7 | import java.util.Arrays;
8 | import java.util.LinkedList;
9 | import java.util.List;
10 | import java.util.Queue;
11 |
12 | import section_layout.widget.custom.android.com.sectionlayout.SectionLayout;
13 | import section_layout.widget.custom.android.com.sectionlayout.distributive_section_layout.DistributiveSectionLayout;
14 | import segmented_control.widget.custom.android.com.segmentedcontrol.item_row.SegmentRowAdapter;
15 | import segmented_control.widget.custom.android.com.segmentedcontrol.item_row.SegmentRowViewHolder;
16 | import segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentAdapter;
17 | import segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentData;
18 | import segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentDecoration;
19 | import segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentViewHolder;
20 | import segmented_control.widget.custom.android.com.segmentedcontrol.listeners.OnSegmentClickListener;
21 | import segmented_control.widget.custom.android.com.segmentedcontrol.listeners.OnSegmentSelectRequestListener;
22 | import segmented_control.widget.custom.android.com.segmentedcontrol.listeners.OnSegmentSelectedListener;
23 | import view_component.lib_android.com.view_component.base_view.ControllerComponent;
24 |
25 | /**
26 | * Created by Robert Apikyan on 9/5/2017.
27 | */
28 |
29 | class SegmentedControlControllerComponent extends ControllerComponent> {
30 | private final Configs configs = Configs.getDefault();
31 | // private SegmentViewHolder lastClickedSegmentViewHolder;
32 | private LinkedList> selectedSegments = new LinkedList<>();
33 | private final Notifier notifier = new Notifier<>();
34 | private final List dataList = new ArrayList<>();
35 |
36 | // private final OnSegmentClickListener _onSegmentClickListener = new OnSegmentClickListener() {
37 | // @Override
38 | // public void onSegmentClick(SegmentViewHolder segmentViewHolder) {
39 | // notifier.onSegmentClick(segmentViewHolder);
40 | //
41 | // if (segmentViewHolder.equals(lastClickedSegmentViewHolder)) {
42 | // // on section reselected
43 | // segmentViewHolder.setSelected(true);
44 | // notifier.onSegmentSelected(segmentViewHolder, true, true);
45 | // } else if (notifier.onSegmentSelectRequest(segmentViewHolder)) {
46 | // // on section selected
47 | // // unSelect the last one
48 | // if (lastClickedSegmentViewHolder != null) {
49 | // lastClickedSegmentViewHolder.setSelected(false);
50 | // notifier.onSegmentSelected(lastClickedSegmentViewHolder, false, false);
51 | // }
52 | // // select the current
53 | // lastClickedSegmentViewHolder = segmentViewHolder;
54 | // segmentViewHolder.setSelected(true);
55 | // notifier.onSegmentSelected(segmentViewHolder, true, false);
56 | // }
57 | // }
58 | // };
59 |
60 | private final OnSegmentClickListener onSegmentClickListener = new OnSegmentClickListener() {
61 | @Override
62 | public void onSegmentClick(SegmentViewHolder segmentViewHolder) {
63 | notifier.onSegmentClick(segmentViewHolder);
64 |
65 | int index = selectedSegments.indexOf(segmentViewHolder);
66 | boolean contains = index != -1;
67 | if (contains) {
68 | // on section reselected
69 | SegmentViewHolder viewHolder = selectedSegments.get(index);
70 | if (configs.reselectionEnabled){
71 | viewHolder.setSelected(true);
72 | notifier.onSegmentSelected(segmentViewHolder, true, true);
73 | }else{
74 | selectedSegments.remove(index);
75 | viewHolder.setSelected(false);
76 | notifier.onSegmentSelected(segmentViewHolder, false, false);
77 | }
78 |
79 | } else if (notifier.onSegmentSelectRequest(segmentViewHolder)) {
80 | // on section selected
81 | // unSelect the last one
82 | SegmentViewHolder lastSelected = addSelectedSegmentViewHolder(segmentViewHolder);
83 | if (lastSelected != null) {
84 | lastSelected.setSelected(false);
85 | notifier.onSegmentSelected(lastSelected, false, false);
86 | }
87 | // select the current
88 | segmentViewHolder.setSelected(true);
89 | notifier.onSegmentSelected(segmentViewHolder, true, false);
90 | }
91 | }
92 | };
93 |
94 | /**
95 | * Watch the supported selections count, if limit is reached the oldest segment will be removed from
96 | * selections list and returned back to method caller
97 | *
98 | * @param segmentViewHolder new selected segment;
99 | * @return oldest selection
100 | */
101 | @Nullable
102 | private SegmentViewHolder addSelectedSegmentViewHolder(SegmentViewHolder segmentViewHolder) {
103 | selectedSegments.add(segmentViewHolder);
104 | if (selectedSegments.size() > configs.supportedSelectionsCount) {
105 | return selectedSegments.remove(0);
106 | }
107 | return null;
108 | }
109 |
110 | private SegmentViewHolder getLastSelectedViewHolder() {
111 | return selectedSegments.size() > 0 ? selectedSegments.getLast() : null;
112 | }
113 |
114 | private void addSegment(D segmentData) {
115 | if (getVerticalSectionLayout().size() == 0 || !canAddToLastRow()) {
116 | addNewRow();
117 | }
118 |
119 | addSegmentToLastRow(segmentData);
120 | }
121 |
122 | // removeLastSelected = true
123 | // private void removeAllSegments(boolean removeLastSelected) {
124 | // for (int row = 0; row < getVerticalSectionLayout().size(); row++) {
125 | // getHorizontalSectionLayout(row).removeAllSections();
126 | // }
127 | // getVerticalSectionLayout().removeAllSections();
128 | // dataList.clear();
129 | //
130 | // if (removeLastSelected) {
131 | // lastClickedSegmentViewHolder = null;
132 | // }
133 | // }
134 |
135 | private void removeAllSegments(boolean removeLastSelected) {
136 | for (int row = 0; row < getVerticalSectionLayout().size(); row++) {
137 | getHorizontalSectionLayout(row).removeAllSections();
138 | }
139 | getVerticalSectionLayout().removeAllSections();
140 | dataList.clear();
141 |
142 | if (removeLastSelected) {
143 | selectedSegments.clear();
144 | }
145 | }
146 |
147 | private void addSegmentToLastRow(D segmentData) {
148 | DistributiveSectionLayout> horizontalSectionLayout = getHorizontalSectionLayout(getLastRowIndex());
149 | horizontalSectionLayout
150 | .addSection(SegmentData.create(segmentData, onSegmentClickListener, getAbsolutePosition(getLastHorizontalSectionLayout().size(),
151 | getVerticalSectionLayout().size() - 1), getLastRowIndex(), horizontalSectionLayout.size(), size(), configs.columnCount, configs.segmentDecoration));
152 | horizontalSectionLayout.requestLayout();
153 | }
154 |
155 | private int[] getRowAndColumnWithAbsolutePosition(int position) {
156 | int smallDiff = position % configs.columnCount;
157 | int diff = position - smallDiff;
158 | int row = (diff / configs.columnCount) + (smallDiff == configs.columnCount ? 1 : 0);
159 | int column = position % configs.columnCount;
160 | return new int[]{row, column};
161 | }
162 |
163 | void notifyConfigIsChanged() {
164 | recreate(false);
165 | }
166 |
167 | // public void clearSelection(boolean notifySegmentSelectedListener) {
168 | // if (lastClickedSegmentViewHolder != null) {
169 | // lastClickedSegmentViewHolder.setSelected(false);
170 | //
171 | // if (notifySegmentSelectedListener) {
172 | // notifier.onSegmentSelected(lastClickedSegmentViewHolder, false, false);
173 | // }
174 | //
175 | // lastClickedSegmentViewHolder = null;
176 | // }
177 | // }
178 |
179 | public void clearSelection(boolean notifySegmentSelectedListener) {
180 | if (!selectedSegments.isEmpty()) {
181 | for (SegmentViewHolder selectedSegment : selectedSegments) {
182 | selectedSegment.setSelected(false);
183 |
184 | if (notifySegmentSelectedListener) {
185 | notifier.onSegmentSelected(selectedSegment, false, false);
186 | }
187 | }
188 |
189 | selectedSegments.clear();
190 | }
191 | }
192 |
193 | // private void recreate(boolean removeLastSelected) {
194 | // if (dataList.size() == 0) return;
195 | // List itemsData = new ArrayList<>(dataList);
196 | // removeAllSegments(removeLastSelected);
197 | // addSegments(itemsData);
198 | // if (lastClickedSegmentViewHolder != null) {
199 | // setSelectedSegment(lastClickedSegmentViewHolder.getAbsolutePosition());
200 | // }
201 | // }
202 |
203 | private void recreate(boolean removeLastSelected) {
204 | if (dataList.size() == 0) return;
205 | List itemsData = new ArrayList<>(dataList);
206 | removeAllSegments(removeLastSelected);
207 | addSegments(itemsData);
208 |
209 | SegmentViewHolder lastSelection = getLastSelectedViewHolder();
210 | if (lastSelection != null) {
211 | setSelectedSegment(lastSelection.getAbsolutePosition());
212 | }
213 | }
214 |
215 | private boolean canAddToLastRow() {
216 | return getHorizontalSectionLayout(getLastRowIndex()).size() < configs.columnCount;
217 | }
218 |
219 | private void addNewRow() {
220 | //noinspection unchecked
221 | getVerticalSectionLayout().addSection(configs.willDistributeEvenly);
222 | }
223 |
224 | private SectionLayout getVerticalSectionLayout() {
225 | //noinspection ConstantConditions
226 | return getViewComponent().verticalSectionLayout;
227 | }
228 |
229 | private DistributiveSectionLayout> getHorizontalSectionLayout(int row) {
230 | //noinspection unchecked
231 | SegmentRowViewHolder segmentedViewHolder = (SegmentRowViewHolder) getVerticalSectionLayout().getViewHolderForAdapterPosition(row);
232 | return segmentedViewHolder.getDistributiveSectionLayout();
233 | }
234 |
235 | private DistributiveSectionLayout> getLastHorizontalSectionLayout() {
236 | return getHorizontalSectionLayout(getLastRowIndex());
237 | }
238 |
239 | private int getLastRowIndex() {
240 | return getVerticalSectionLayout().size() - 1;
241 | }
242 |
243 | SegmentViewHolder findSegmentByAbsolutePosition(int position) {
244 | int[] point = getRowAndColumnWithAbsolutePosition(position);
245 | return findSegmentByColumnAndRow(point[0], point[1]);
246 | }
247 |
248 | SegmentViewHolder findSegmentByColumnAndRow(int column, int row) {
249 | return (SegmentViewHolder) getHorizontalSectionLayout(column).getViewHolderForAdapterPosition(row);
250 | }
251 |
252 | void forEachSegment(SegmentConsumer segmentConsumer) {
253 | for (int row = 0; row < getVerticalSectionLayout().size(); row++) {
254 | DistributiveSectionLayout> horizontalSectionLayout = getHorizontalSectionLayout(row);
255 | for (int column = 0; column < horizontalSectionLayout.size(); column++) {
256 | segmentConsumer.apply(findSegmentByColumnAndRow(row, column));
257 | }
258 | }
259 | }
260 |
261 | void setAccentColor(int color) {
262 | configs.segmentDecoration = SegmentDecoration.createDefault(getContext(), color);
263 | }
264 |
265 | void setSelectedStrokeColor(int color) {
266 | configs.segmentDecoration.selectedStrokeColor = color;
267 | }
268 |
269 | void setUnSelectedStrokeColor(int color) {
270 | configs.segmentDecoration.unSelectedStrokeColor = color;
271 | }
272 |
273 | void setStrokeWidth(int width) {
274 | configs.segmentDecoration.strokeWidth = width;
275 | }
276 |
277 | void setSelectedBackgroundColor(int color) {
278 | configs.segmentDecoration.selectBackgroundColor = color;
279 | }
280 |
281 | void setUnSelectedBackgroundColor(int color) {
282 | configs.segmentDecoration.unSelectedBackgroundColor = color;
283 | }
284 |
285 | void setFocusedBackgroundColor(int color) {
286 | configs.segmentDecoration.focusedBackgroundColor = color;
287 | }
288 |
289 | void setReselectionEnabled(boolean isEnabled){
290 | configs.reselectionEnabled = isEnabled;
291 | }
292 |
293 | void setSelectionAnimationDuration(int duration) {
294 | configs.segmentDecoration.selectionAnimationDuration = duration;
295 | }
296 |
297 | void setSelectedTextColor(int color) {
298 | configs.segmentDecoration.selectedTextColor = color;
299 | }
300 |
301 | void setUnSelectedTextColor(int color) {
302 | configs.segmentDecoration.unSelectedTextColor = color;
303 | }
304 |
305 | void setTextSize(int textSize) {
306 | configs.segmentDecoration.textSize = textSize;
307 | }
308 |
309 | void setTypeFace(Typeface typeFace) {
310 | configs.segmentDecoration.typeface = typeFace;
311 | }
312 |
313 | void setTextVerticalPadding(int padding) {
314 | configs.segmentDecoration.textVerticalPadding = padding;
315 | }
316 |
317 | void setTextHorizontalPadding(int padding) {
318 | configs.segmentDecoration.textHorizontalPadding = padding;
319 | }
320 |
321 | void setSegmentVerticalMargin(int margin) {
322 | configs.segmentDecoration.segmentVerticalMargin = margin;
323 | }
324 |
325 | void setSegmentHorizontalMargin(int margin) {
326 | configs.segmentDecoration.segmentHorizontalMargin = margin;
327 | }
328 |
329 | void setRadius(int radius) {
330 | setTopLeftRadius(radius);
331 | setTopRightRadius(radius);
332 | setBottomRightRadius(radius);
333 | setBottomLeftRadius(radius);
334 | }
335 |
336 | void setTopLeftRadius(int radius) {
337 | configs.segmentDecoration.topLeftRadius = radius;
338 | }
339 |
340 | void setTopRightRadius(int radius) {
341 | configs.segmentDecoration.topRightRadius = radius;
342 | }
343 |
344 | void setBottomRightRadius(int radius) {
345 | configs.segmentDecoration.bottomRightRadius = radius;
346 | }
347 |
348 | void setBottomLeftRadius(int radius) {
349 | configs.segmentDecoration.bottomLeftRadius = radius;
350 | }
351 |
352 | void setRadiusForEverySegment(boolean radiusForEverySegment) {
353 | configs.segmentDecoration.radiusForEverySegment = radiusForEverySegment;
354 | }
355 |
356 | void setAdapter(SegmentAdapter adapter) {
357 | //noinspection ConstantConditions, setAdapter will be called from SegmentedControl
358 | getViewComponent().verticalSectionLayout.withAdapter(new SegmentRowAdapter(adapter));
359 | }
360 |
361 | void addSegments(D[] segmentDataArray) {
362 | if (segmentDataArray == null || segmentDataArray.length == 0) return;
363 | addSegments(new ArrayList<>(Arrays.asList(segmentDataArray)));
364 | }
365 |
366 | void addSegments(List segmentDataList) {
367 | if (segmentDataList == null || segmentDataList.size() == 0) return;
368 |
369 | dataList.addAll(new ArrayList<>(segmentDataList));
370 |
371 | for (D segmentData : dataList) {
372 | addSegment(segmentData);
373 | }
374 | }
375 |
376 | void removeAllSegments() {
377 | removeAllSegments(true);
378 | }
379 |
380 | void setDistributeEvenly(boolean willDistributeEvenly) {
381 | configs.willDistributeEvenly = willDistributeEvenly;
382 | }
383 |
384 | void setSupportedSelectionsCount(int supportedSelectionsCount) {
385 | configs.supportedSelectionsCount = supportedSelectionsCount;
386 | }
387 |
388 | void setColumnCount(int columnCount) {
389 | configs.columnCount = columnCount;
390 | }
391 |
392 | void addOnSegmentClickListener(OnSegmentClickListener onSegmentClickListener) {
393 | notifier.addOnSegmentClickListener(onSegmentClickListener);
394 | }
395 |
396 | void removeOnSegmentClickListener(OnSegmentClickListener onSegmentClickListener) {
397 | notifier.removeOnSegmentClickListener(onSegmentClickListener);
398 | }
399 |
400 | void addOnSegmentSelectListener(OnSegmentSelectedListener onSegmentSelectedListener) {
401 | notifier.addOnSegmentSelectListener(onSegmentSelectedListener);
402 | }
403 |
404 | void removeOnSegmentSelectListener(OnSegmentSelectedListener onSegmentSelectedListener) {
405 | notifier.removeOnSegmentSelectListener(onSegmentSelectedListener);
406 | }
407 |
408 | void setOnSegmentSelectRequestListener(OnSegmentSelectRequestListener onSegmentSelectRequestListener) {
409 | notifier.setOnSegmentSelectRequestListener(onSegmentSelectRequestListener);
410 | }
411 |
412 | void setSelectedSegment(int absolutePosition) {
413 | int[] point = getRowAndColumnWithAbsolutePosition(absolutePosition);
414 | setSelectedSegment(point[0], point[1]);
415 | }
416 |
417 | void setSelectedSegment(int column, int row) {
418 | onSegmentClickListener.onSegmentClick(findSegmentByColumnAndRow(column, row));
419 | }
420 |
421 | // SegmentViewHolder getSelectedViewHolder() {
422 | // return lastClickedSegmentViewHolder;
423 | // }
424 |
425 | List> getSelectedViewHolders() {
426 | return selectedSegments;
427 | }
428 |
429 | int[] getLastSelectedColumnAndRow() {
430 | SegmentViewHolder lastSelection = getLastSelectedViewHolder();
431 | if (lastSelection != null) {
432 | return new int[]{lastSelection.getColumn(), lastSelection.getRow()};
433 | } else {
434 | return new int[]{-1, -1};
435 | }
436 | }
437 |
438 | //
439 | int getLastSelectedAbsolutePosition() {
440 | SegmentViewHolder lastSelection = getLastSelectedViewHolder();
441 | if (lastSelection != null) {
442 | return lastSelection.getAbsolutePosition();
443 | } else {
444 | return -1;
445 | }
446 | }
447 |
448 | // boolean isSelected() {
449 | // return lastClickedSegmentViewHolder != null;
450 | // }
451 |
452 | boolean isSelected() {
453 | return !selectedSegments.isEmpty();
454 | }
455 |
456 | int size() {
457 | return dataList.size();
458 | }
459 |
460 | int getAbsolutePosition(int column, int row) {
461 | return row * configs.columnCount + column;
462 | }
463 | }
464 |
--------------------------------------------------------------------------------
/segmentedcontrolmodule/src/main/java/segmented_control/widget/custom/android/com/segmentedcontrol/SegmentedControlViewComponent.java:
--------------------------------------------------------------------------------
1 | package segmented_control.widget.custom.android.com.segmentedcontrol;
2 |
3 | import android.support.annotation.NonNull;
4 | import android.view.View;
5 | import android.widget.LinearLayout;
6 |
7 | import section_layout.widget.custom.android.com.sectionlayout.SectionLayout;
8 | import view_component.lib_android.com.view_component.base_view.ViewComponent;
9 |
10 | /**
11 | * Created by Robert Apikyan on 9/5/2017.
12 | */
13 |
14 | class SegmentedControlViewComponent extends ViewComponent {
15 | final SectionLayout verticalSectionLayout;
16 |
17 | SegmentedControlViewComponent(@NonNull View rootView) {
18 | super(rootView);
19 | //noinspection unchecked
20 | verticalSectionLayout = (SectionLayout) getRootViewGroup().getChildAt(0);
21 | verticalSectionLayout.setOrientation(LinearLayout.VERTICAL);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/segmentedcontrolmodule/src/main/java/segmented_control/widget/custom/android/com/segmentedcontrol/custom_segment/SegmentAdapterImpl.java:
--------------------------------------------------------------------------------
1 | package segmented_control.widget.custom.android.com.segmentedcontrol.custom_segment;
2 |
3 | import android.support.annotation.NonNull;
4 | import android.view.LayoutInflater;
5 | import android.view.ViewGroup;
6 |
7 | import segmented_control.widget.custom.android.com.segmented_control.R;
8 | import segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentAdapter;
9 |
10 | /**
11 | * Created by Robert Apikyan on 9/8/2017.
12 | */
13 |
14 | public class SegmentAdapterImpl extends SegmentAdapter {
15 |
16 | @NonNull
17 | @Override
18 | protected SegmentViewHolderImpl onCreateViewHolder(@NonNull LayoutInflater layoutInflater, ViewGroup viewGroup, int i) {
19 | return new SegmentViewHolderImpl(layoutInflater.inflate(R.layout.item_segment_impl, null));
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/segmentedcontrolmodule/src/main/java/segmented_control/widget/custom/android/com/segmentedcontrol/custom_segment/SegmentViewHolderImpl.java:
--------------------------------------------------------------------------------
1 | package segmented_control.widget.custom.android.com.segmentedcontrol.custom_segment;
2 |
3 | import android.animation.ValueAnimator;
4 | import android.annotation.SuppressLint;
5 | import android.graphics.drawable.Drawable;
6 | import android.os.Build;
7 | import android.support.annotation.NonNull;
8 | import android.util.TypedValue;
9 | import android.view.MotionEvent;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 | import android.widget.TextView;
13 |
14 | import segmented_control.widget.custom.android.com.segmented_control.R;
15 | import segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentViewHolder;
16 |
17 | import static segmented_control.widget.custom.android.com.segmentedcontrol.utils.Utils.createBackgroundAnimation;
18 | import static segmented_control.widget.custom.android.com.segmentedcontrol.utils.Utils.createRadius;
19 | import static segmented_control.widget.custom.android.com.segmentedcontrol.utils.Utils.defineRadiusForPosition;
20 | import static segmented_control.widget.custom.android.com.segmentedcontrol.utils.Utils.getBackground;
21 | import static segmented_control.widget.custom.android.com.segmentedcontrol.utils.Utils.isInBounds;
22 |
23 | /**
24 | * Created by Robert Apikyan on 9/8/2017.
25 | */
26 |
27 | public class SegmentViewHolderImpl extends SegmentViewHolder {
28 |
29 | private TextView itemTV;
30 | private float[] radius;
31 | private ValueAnimator va;
32 | private int[] windowLocation;
33 |
34 | private final ValueAnimator.AnimatorUpdateListener bgAnimListener = new ValueAnimator.AnimatorUpdateListener() {
35 | @Override
36 | public void onAnimationUpdate(ValueAnimator animation) {
37 | int colorArgb = (int) animation.getAnimatedValue();
38 | Drawable bg = getBackground(getStrokeWidth(), isSelected() ? getSelectedStrokeColor() : getUnSelectedStrokeColor(), colorArgb, radius);
39 | setBackground(bg);
40 | }
41 | };
42 |
43 | @SuppressWarnings("FieldCanBeLocal")
44 | private final View.OnTouchListener segmentTouchListener = new View.OnTouchListener() {
45 | @SuppressLint("ClickableViewAccessibility")
46 | @Override
47 | public boolean onTouch(View v, MotionEvent event) {
48 | if (isSelected()) {
49 | return false;
50 | }
51 | if (event.getAction() == MotionEvent.ACTION_DOWN) {
52 | setBackground(getFocusedBackground());
53 |
54 | } else if (event.getAction() == MotionEvent.ACTION_UP ||
55 | event.getAction() == MotionEvent.ACTION_CANCEL ||
56 | event.getAction() == MotionEvent.ACTION_POINTER_UP ||
57 | event.getAction() == MotionEvent.ACTION_OUTSIDE) {
58 |
59 | if (!isInBounds(event.getX(), event.getY(), windowLocation[0], windowLocation[1],
60 | getSectionView().getMeasuredWidth(), getSectionView().getMeasuredHeight())) {
61 |
62 | setBackground(isSelected() ? getSelectedBackground() : getUnSelectedBackground());
63 | }
64 | }
65 | return false;
66 | }
67 | };
68 |
69 | public SegmentViewHolderImpl(@NonNull View sectionView) {
70 | super(sectionView);
71 | itemTV = sectionView.findViewById(R.id.item_segment_tv);
72 | sectionView.setOnTouchListener(segmentTouchListener);
73 | }
74 |
75 | @Override
76 | protected void onSegmentBind(CharSequence segmentData) {
77 | initScreenLocation();
78 | itemTV.setText(segmentData);
79 | if (isRadiusForEverySegment()) {
80 | radius = createRadius(getTopLeftRadius(), getTopRightRadius(), getBottomRightRadius(), getBottomLeftRadius());
81 | } else {
82 | radius = defineRadiusForPosition(getAbsolutePosition(), getColumnCount(), getCurrentSize(), getTopLeftRadius(), getTopRightRadius(), getBottomRightRadius(), getBottomLeftRadius());
83 | }
84 | setSectionDecorationSelected(false, false);
85 | itemTV.setTextSize(TypedValue.COMPLEX_UNIT_PX, getTextSize());
86 | if (getTypeFace() != null) {
87 | itemTV.setTypeface(getTypeFace());
88 | }
89 | itemTV.setPadding(getTextHorizontalPadding(), getTextVerticalPadding(), getTextHorizontalPadding(), getTextVerticalPadding());
90 | ((ViewGroup.MarginLayoutParams) itemTV.getLayoutParams()).setMargins(getSegmentHorizontalMargin(), getSegmentVerticalMargin(), getSegmentHorizontalMargin(), getSegmentVerticalMargin());
91 | }
92 |
93 | private void initScreenLocation() {
94 | windowLocation = new int[2];
95 | getSectionView().getLocationOnScreen(windowLocation);
96 | }
97 |
98 | @Override
99 | public void onSegmentSelected(boolean isSelected, boolean isReselected) {
100 | super.onSegmentSelected(isSelected, isReselected);
101 | setSectionDecorationSelected(isSelected, isReselected);
102 | }
103 |
104 | private Drawable getSelectedBackground() {
105 | return getBackground(getStrokeWidth(), getSelectedStrokeColor(), getSelectBackgroundColor(), radius);
106 | }
107 |
108 | private Drawable getUnSelectedBackground() {
109 | return getBackground(getStrokeWidth(), getUnSelectedStrokeColor(), getUnSelectedBackgroundColor(), radius);
110 | }
111 |
112 | private Drawable getFocusedBackground() {
113 | return getBackground(getStrokeWidth(), isSelected() ? getSelectedStrokeColor() : getUnSelectedStrokeColor(), getFocusedBackgroundColor(), radius);
114 | }
115 |
116 | private void setSectionDecorationSelected(boolean isSelected, boolean isReselected) {
117 | if (isReselected)
118 | return;
119 |
120 | if (hasBackground()) {
121 | animateNewBackground(isSelected);
122 | } else {
123 | setBackground(isSelected ? getSelectedBackground() : getUnSelectedBackground());
124 | }
125 |
126 | itemTV.setTextColor(isSelected ? getSelectedTextColor() : getUnSelectedTextColor());
127 | }
128 |
129 | private void animateNewBackground(boolean isSelected) {
130 |
131 | if (va != null) {
132 | va.end();
133 | va.removeUpdateListener(bgAnimListener);
134 | }
135 |
136 | // animate
137 | int startColor = isSelected ? getFocusedBackgroundColor() : getSelectBackgroundColor();
138 | int endColor = isSelected ? getSelectBackgroundColor() : getUnSelectedBackgroundColor();
139 |
140 | va = createBackgroundAnimation(startColor, endColor);
141 |
142 | va.addUpdateListener(bgAnimListener);
143 |
144 | va.setDuration(getSelectionAnimationDuration());
145 |
146 | va.start();
147 | }
148 |
149 | private void setBackground(Drawable drawable) {
150 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
151 | itemTV.setBackground(drawable);
152 | } else {
153 | //noinspection deprecation
154 | itemTV.setBackgroundDrawable(drawable);
155 | }
156 | }
157 |
158 | private boolean hasBackground() {
159 | return itemTV.getBackground() != null;
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/segmentedcontrolmodule/src/main/java/segmented_control/widget/custom/android/com/segmentedcontrol/item_row/SegmentRowAdapter.java:
--------------------------------------------------------------------------------
1 | package segmented_control.widget.custom.android.com.segmentedcontrol.item_row;
2 |
3 | import android.support.annotation.NonNull;
4 | import android.view.LayoutInflater;
5 | import android.view.ViewGroup;
6 |
7 | import section_layout.widget.custom.android.com.sectionlayout.SectionLayout;
8 | import section_layout.widget.custom.android.com.sectionlayout.distributive_section_layout.DistributiveSectionLayout;
9 | import segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentAdapter;
10 | import segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentData;
11 |
12 | /**
13 | * Created by Robert Apikyan on 9/7/2017.
14 | */
15 |
16 | public class SegmentRowAdapter extends SectionLayout.Adapter>> {
17 |
18 | private final SegmentAdapter segmentAdapter;
19 |
20 | public SegmentRowAdapter(SegmentAdapter segmentAdapter) {
21 | this.segmentAdapter = segmentAdapter;
22 | }
23 |
24 | @NonNull
25 | @Override
26 | protected SegmentRowViewHolder> onCreateViewHolder(@NonNull LayoutInflater layoutInflater, ViewGroup viewGroup, int i) {
27 | return new SegmentRowViewHolder<>(new DistributiveSectionLayout>(layoutInflater.getContext()), segmentAdapter);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/segmentedcontrolmodule/src/main/java/segmented_control/widget/custom/android/com/segmentedcontrol/item_row/SegmentRowViewHolder.java:
--------------------------------------------------------------------------------
1 | package segmented_control.widget.custom.android.com.segmentedcontrol.item_row;
2 |
3 | import android.support.annotation.NonNull;
4 | import android.view.View;
5 | import android.widget.LinearLayout;
6 |
7 | import section_layout.widget.custom.android.com.sectionlayout.SectionLayout;
8 | import section_layout.widget.custom.android.com.sectionlayout.distributive_section_layout.DistributiveSectionLayout;
9 | import segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentAdapter;
10 | import segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentData;
11 |
12 | /**
13 | * Created by Robert Apikyan on 9/7/2017.
14 | */
15 |
16 | public class SegmentRowViewHolder extends SectionLayout.ViewHolder {
17 | private final DistributiveSectionLayout> distributiveSectionLayout;
18 |
19 | SegmentRowViewHolder(@NonNull View sectionView, SegmentAdapter segmentAdapter) {
20 | super(sectionView);
21 | //noinspection unchecked
22 | distributiveSectionLayout = (DistributiveSectionLayout>) sectionView;
23 | distributiveSectionLayout.setOrientation(LinearLayout.HORIZONTAL);
24 | distributiveSectionLayout.withAdapter(segmentAdapter);
25 | }
26 |
27 | @Override
28 | protected void onBind(Boolean willDistributeEvenly) {
29 | distributiveSectionLayout.distributeEvenly(willDistributeEvenly);
30 | }
31 |
32 | public DistributiveSectionLayout> getDistributiveSectionLayout() {
33 | return distributiveSectionLayout;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/segmentedcontrolmodule/src/main/java/segmented_control/widget/custom/android/com/segmentedcontrol/item_row_column/SegmentAdapter.java:
--------------------------------------------------------------------------------
1 | package segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column;
2 |
3 | import section_layout.widget.custom.android.com.sectionlayout.distributive_section_layout.DistributiveSectionLayout;
4 |
5 | /**
6 | * Created by Robert Apikyan on 9/7/2017.
7 | */
8 |
9 | public abstract class SegmentAdapter> extends DistributiveSectionLayout.Adapter, VH> {
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/segmentedcontrolmodule/src/main/java/segmented_control/widget/custom/android/com/segmentedcontrol/item_row_column/SegmentBackgroundType.java:
--------------------------------------------------------------------------------
1 | package segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column;
2 |
3 | import android.support.annotation.IntDef;
4 |
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.RetentionPolicy;
7 |
8 | import static segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentBackgroundType.BOTTOM_LEFT_BG;
9 | import static segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentBackgroundType.BOTTOM_RIGHT_BG;
10 | import static segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentBackgroundType.BOTTOM_SINGLE_BG;
11 | import static segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentBackgroundType.MIDDLE_BG;
12 | import static segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentBackgroundType.SINGLE_BG;
13 | import static segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentBackgroundType.TOP_LEFT_BG;
14 | import static segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentBackgroundType.TOP_LEFT_SINGLE_BG;
15 | import static segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentBackgroundType.TOP_RIGHT_BG;
16 | import static segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentBackgroundType.TOP_RIGHT_SINGLE_BG;
17 | import static segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentBackgroundType.TOP_SINGLE_BG;
18 |
19 | /**
20 | * Created by Robert Apikyan on 9/12/2017.
21 | */
22 | @IntDef(value = {SINGLE_BG,
23 | TOP_SINGLE_BG,
24 | TOP_LEFT_BG,
25 | TOP_LEFT_SINGLE_BG,
26 | TOP_RIGHT_SINGLE_BG,
27 | TOP_RIGHT_BG,
28 | MIDDLE_BG,
29 | BOTTOM_SINGLE_BG,
30 | BOTTOM_LEFT_BG,
31 | BOTTOM_RIGHT_BG})
32 | @Retention(RetentionPolicy.SOURCE)
33 | public @interface SegmentBackgroundType {
34 | int SINGLE_BG = 0;
35 | int TOP_SINGLE_BG = 1;
36 | int TOP_LEFT_BG = 2;
37 | int TOP_LEFT_SINGLE_BG = 3;
38 | int TOP_RIGHT_SINGLE_BG = 4;
39 | int TOP_RIGHT_BG = 5;
40 | int MIDDLE_BG = 6;
41 | int BOTTOM_SINGLE_BG = 7;
42 | int BOTTOM_LEFT_BG = 8;
43 | int BOTTOM_RIGHT_BG = 9;
44 | }
45 |
--------------------------------------------------------------------------------
/segmentedcontrolmodule/src/main/java/segmented_control/widget/custom/android/com/segmentedcontrol/item_row_column/SegmentData.java:
--------------------------------------------------------------------------------
1 | package segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column;
2 |
3 | import android.graphics.Typeface;
4 |
5 | import segmented_control.widget.custom.android.com.segmentedcontrol.listeners.OnSegmentClickListener;
6 |
7 | /**
8 | * Created by Robert Apikyan on 9/7/2017.
9 | */
10 |
11 | public class SegmentData {
12 | boolean isSelected;
13 | int absolutePosition;
14 |
15 | private int row;
16 | private int column;
17 |
18 | private D segmentData;
19 | private OnSegmentClickListener onSegmentClickListener;
20 |
21 | private SegmentDecoration segmentDecoration;
22 | private int currentSize;
23 | private int columnCount;
24 |
25 | public static SegmentData create(D segmentData, OnSegmentClickListener onSegmentClickListener, int absolutePosition, int row, int column, int currentSize, int columnCount, SegmentDecoration segmentDecoration) {
26 | SegmentData sd = new SegmentData<>();
27 | sd.segmentData = segmentData;
28 | sd.absolutePosition = absolutePosition;
29 | sd.row = row;
30 | sd.column = column;
31 | sd.currentSize = currentSize;
32 | sd.columnCount = columnCount;
33 | sd.segmentDecoration = segmentDecoration;
34 | sd.onSegmentClickListener = onSegmentClickListener;
35 | return sd;
36 | }
37 |
38 | public boolean isSelected() {
39 | return isSelected;
40 | }
41 |
42 | public int getAbsolutePosition() {
43 | return absolutePosition;
44 | }
45 |
46 | public int getRow() {
47 | return row;
48 | }
49 |
50 | public int getColumn() {
51 | return column;
52 | }
53 |
54 | public D getSegmentData() {
55 | return segmentData;
56 | }
57 |
58 | public OnSegmentClickListener getOnSegmentClickListener() {
59 | return onSegmentClickListener;
60 | }
61 |
62 | public int getSelectedStrokeColor() {
63 | return segmentDecoration.getSelectedStrokeColor();
64 | }
65 |
66 | public int getUnSelectedStrokeColor() {
67 | return segmentDecoration.getUnSelectedStrokeColor();
68 | }
69 |
70 | public int getStrokeWidth() {
71 | return segmentDecoration.getStrokeWidth();
72 | }
73 |
74 | public int getSelectBackgroundColor() {
75 | return segmentDecoration.getSelectBackgroundColor();
76 | }
77 |
78 | public int getUnSelectedBackgroundColor() {
79 | return segmentDecoration.getUnSelectedBackgroundColor();
80 | }
81 |
82 | public int getFocusedBackgroundColor(){
83 | return segmentDecoration.getFocusedBackgroundColor();
84 | }
85 |
86 | public int getSelectionAnimationDuration(){
87 | return segmentDecoration.getSelectionAnimationDuration();
88 | }
89 |
90 | public int getSelectedTextColor() {
91 | return segmentDecoration.getSelectedTextColor();
92 | }
93 |
94 | public int getUnSelectedTextColor() {
95 | return segmentDecoration.getUnSelectedTextColor();
96 | }
97 |
98 | public int getTextSize() {
99 | return segmentDecoration.getTextSize();
100 | }
101 |
102 | public Typeface getTypeFace(){
103 | return segmentDecoration.getTypeface();
104 | }
105 |
106 | public int getTextHorizontalPadding() {
107 | return segmentDecoration.getTextHorizontalPadding();
108 | }
109 |
110 | public int getTextVerticalPadding() {
111 | return segmentDecoration.getTextVerticalPadding();
112 | }
113 |
114 | public int getSegmentVerticalMargin() {
115 | return segmentDecoration.getSegmentVerticalMargin();
116 | }
117 |
118 | public int getSegmentHorizontalMargin() {
119 | return segmentDecoration.getSegmentHorizontalMargin();
120 | }
121 |
122 | public int getTopLeftRadius() {
123 | return segmentDecoration.getTopLeftRadius();
124 | }
125 |
126 | public int getTopRightRadius() {
127 | return segmentDecoration.getTopRightRadius();
128 | }
129 |
130 | public int getBottomRightRadius() {
131 | return segmentDecoration.getBottomRightRadius();
132 | }
133 |
134 | public int getBottomLeftRadius() {
135 | return segmentDecoration.getBottomLeftRadius();
136 | }
137 |
138 | public boolean isRadiusForEverySegment() {
139 | return segmentDecoration.isRadiusForEverySegment();
140 | }
141 |
142 | public int getCurrentSize() {
143 | return currentSize;
144 | }
145 |
146 | public int getColumnCount() {
147 | return columnCount;
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/segmentedcontrolmodule/src/main/java/segmented_control/widget/custom/android/com/segmentedcontrol/item_row_column/SegmentDecoration.java:
--------------------------------------------------------------------------------
1 | package segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column;
2 |
3 | import android.content.Context;
4 | import android.graphics.Color;
5 | import android.graphics.Typeface;
6 | import android.support.annotation.ColorInt;
7 | import android.support.v4.content.ContextCompat;
8 |
9 | /**
10 | * Created by Robert Apikyan on 9/11/2017.
11 | */
12 |
13 | public class SegmentDecoration {
14 | public static final int DEFAULT_FOCUSED_BACKGROUND_ALPHA = 36;
15 | public static final int DEFAULT_SELECTION_ANIMATION_DURATION = 196;
16 |
17 | // segment decoration
18 | // stroke
19 | @ColorInt
20 | public int selectedStrokeColor;
21 | @ColorInt
22 | public int unSelectedStrokeColor;
23 | public int strokeWidth;
24 | // background
25 | @ColorInt
26 | public int selectBackgroundColor;
27 | @ColorInt
28 | public int unSelectedBackgroundColor;
29 | // focused segment background
30 | public int focusedBackgroundColor;
31 | // selection Animation Duration
32 | public int selectionAnimationDuration;
33 | // text
34 | @ColorInt
35 | public int selectedTextColor;
36 | @ColorInt
37 | public int unSelectedTextColor;
38 | public int textSize;
39 | // text padding
40 | public int textHorizontalPadding;
41 | public int textVerticalPadding;
42 |
43 | // segment margins
44 | public int segmentVerticalMargin;
45 | public int segmentHorizontalMargin;
46 |
47 | // segment font type
48 | public Typeface typeface;
49 |
50 | // radius
51 | public int topLeftRadius;
52 | public int topRightRadius;
53 | public int bottomRightRadius;
54 | public int bottomLeftRadius;
55 | public boolean radiusForEverySegment = false; // def. value
56 |
57 | public static SegmentDecoration createDefault(Context context, int accentColor) {
58 | SegmentDecoration sd = new SegmentDecoration();
59 | sd.selectedStrokeColor = accentColor;
60 | sd.unSelectedStrokeColor = accentColor;
61 | sd.selectBackgroundColor = accentColor;
62 | sd.unSelectedBackgroundColor = ContextCompat.getColor(context, android.R.color.transparent);
63 | sd.focusedBackgroundColor = Color.argb(DEFAULT_FOCUSED_BACKGROUND_ALPHA,
64 | Color.red(accentColor),
65 | Color.green(accentColor),
66 | Color.blue(accentColor));
67 | sd.selectionAnimationDuration = DEFAULT_SELECTION_ANIMATION_DURATION;
68 | sd.selectedTextColor = ContextCompat.getColor(context, android.R.color.white);
69 | sd.unSelectedTextColor = accentColor;
70 | sd.strokeWidth = 1;
71 | sd.typeface = null;
72 | return sd;
73 | }
74 |
75 | public int getSelectedStrokeColor() {
76 | return selectedStrokeColor;
77 | }
78 |
79 | public int getUnSelectedStrokeColor() {
80 | return unSelectedStrokeColor;
81 | }
82 |
83 | public int getStrokeWidth() {
84 | return strokeWidth;
85 | }
86 |
87 | public int getSelectBackgroundColor() {
88 | return selectBackgroundColor;
89 | }
90 |
91 | public int getUnSelectedBackgroundColor() {
92 | return unSelectedBackgroundColor;
93 | }
94 |
95 | public int getFocusedBackgroundColor() {
96 | return focusedBackgroundColor;
97 | }
98 |
99 | public int getSelectionAnimationDuration() {
100 | return selectionAnimationDuration;
101 | }
102 |
103 | public int getSelectedTextColor() {
104 | return selectedTextColor;
105 | }
106 |
107 | public int getUnSelectedTextColor() {
108 | return unSelectedTextColor;
109 | }
110 |
111 | public int getTextSize() {
112 | return textSize;
113 | }
114 |
115 | public int getTextHorizontalPadding() {
116 | return textHorizontalPadding;
117 | }
118 |
119 | public int getTextVerticalPadding() {
120 | return textVerticalPadding;
121 | }
122 |
123 | public int getSegmentVerticalMargin() {
124 | return segmentVerticalMargin;
125 | }
126 |
127 | public int getSegmentHorizontalMargin() {
128 | return segmentHorizontalMargin;
129 | }
130 |
131 | public int getTopLeftRadius() {
132 | return topLeftRadius;
133 | }
134 |
135 | public int getTopRightRadius() {
136 | return topRightRadius;
137 | }
138 |
139 | public int getBottomRightRadius() {
140 | return bottomRightRadius;
141 | }
142 |
143 | public int getBottomLeftRadius() {
144 | return bottomLeftRadius;
145 | }
146 |
147 | public boolean isRadiusForEverySegment() {
148 | return radiusForEverySegment;
149 | }
150 |
151 | public Typeface getTypeface() {
152 | return typeface;
153 | }
154 |
155 | ;
156 | }
157 |
--------------------------------------------------------------------------------
/segmentedcontrolmodule/src/main/java/segmented_control/widget/custom/android/com/segmentedcontrol/item_row_column/SegmentViewHolder.java:
--------------------------------------------------------------------------------
1 | package segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column;
2 |
3 | import android.graphics.Typeface;
4 | import android.support.annotation.NonNull;
5 | import android.view.View;
6 |
7 | import section_layout.widget.custom.android.com.sectionlayout.distributive_section_layout.DistributiveSectionLayout;
8 |
9 | /**
10 | * Created by Robert Apikyan on 9/7/2017.
11 | */
12 |
13 | public abstract class SegmentViewHolder extends DistributiveSectionLayout.ViewHolder> {
14 | private SegmentData segmentData;
15 |
16 | private final View.OnClickListener onSectionViewClickListener = new View.OnClickListener() {
17 | @Override
18 | public void onClick(View v) {
19 | if (segmentData != null)
20 | segmentData.getOnSegmentClickListener().onSegmentClick(SegmentViewHolder.this);
21 | }
22 | };
23 |
24 | public SegmentViewHolder(@NonNull View sectionView) {
25 | super(sectionView);
26 | }
27 |
28 | @Override
29 | protected final void onBind(SegmentData segmentData) {
30 | this.segmentData = segmentData;
31 | getSectionView().setOnClickListener(onSectionViewClickListener);
32 | onSegmentBind(segmentData.getSegmentData());
33 | }
34 |
35 | public final void setSelected(boolean isSelected) {
36 | if (segmentData.isSelected() && isSelected) {
37 | segmentData.isSelected = true;
38 | onSegmentSelected(true, true);
39 | } else if (isSelected) {
40 | segmentData.isSelected = true;
41 | onSegmentSelected(true, false);
42 | } else {
43 | segmentData.isSelected = false;
44 | onSegmentSelected(false, false);
45 | }
46 | }
47 |
48 | /**
49 | * Override this method in order to define, performed action, selected, unselected, reselected
50 | *
51 | * @param isSelected, represent selected state
52 | * @param isReselected, represent reselected state
53 | */
54 | public void onSegmentSelected(boolean isSelected, boolean isReselected) {
55 |
56 | }
57 |
58 | public int getAbsolutePosition() {
59 | return segmentData.absolutePosition;
60 | }
61 |
62 | public boolean isSelected() {
63 | return segmentData.isSelected;
64 | }
65 |
66 | public int getRow() {
67 | return segmentData.getRow();
68 | }
69 |
70 | public int getColumn() {
71 | return segmentData.getColumn();
72 | }
73 |
74 | public D getSegmentData() {
75 | return segmentData.getSegmentData();
76 | }
77 |
78 | public int getSelectedStrokeColor() {
79 | return segmentData.getSelectedStrokeColor();
80 | }
81 |
82 | public int getUnSelectedStrokeColor() {
83 | return segmentData.getUnSelectedStrokeColor();
84 | }
85 |
86 | public int getStrokeWidth() {
87 | return segmentData.getStrokeWidth();
88 | }
89 |
90 | public int getSelectBackgroundColor() {
91 | return segmentData.getSelectBackgroundColor();
92 | }
93 |
94 | public int getUnSelectedBackgroundColor() {
95 | return segmentData.getUnSelectedBackgroundColor();
96 | }
97 |
98 | public int getFocusedBackgroundColor(){
99 | return segmentData.getFocusedBackgroundColor();
100 | }
101 |
102 | public int getSelectionAnimationDuration(){
103 | return segmentData.getSelectionAnimationDuration();
104 | }
105 |
106 | public int getSelectedTextColor() {
107 | return segmentData.getSelectedTextColor();
108 | }
109 |
110 | public int getUnSelectedTextColor() {
111 | return segmentData.getUnSelectedTextColor();
112 | }
113 |
114 | public int getTextSize() {
115 | return segmentData.getTextSize();
116 | }
117 |
118 | public Typeface getTypeFace(){return segmentData.getTypeFace();}
119 |
120 | public int getCurrentSize() {
121 | return segmentData.getCurrentSize();
122 | }
123 |
124 | public int getColumnCount() {
125 | return segmentData.getColumnCount();
126 | }
127 |
128 | public int getTextHorizontalPadding() {
129 | return segmentData.getTextHorizontalPadding();
130 | }
131 |
132 | public int getTextVerticalPadding() {
133 | return segmentData.getTextVerticalPadding();
134 | }
135 |
136 | public int getSegmentVerticalMargin() {
137 | return segmentData.getSegmentVerticalMargin();
138 | }
139 |
140 | public int getSegmentHorizontalMargin() {
141 | return segmentData.getSegmentHorizontalMargin();
142 | }
143 |
144 | public int getTopLeftRadius() {
145 | return segmentData.getTopLeftRadius();
146 | }
147 |
148 | public int getTopRightRadius() {
149 | return segmentData.getTopRightRadius();
150 | }
151 |
152 | public int getBottomRightRadius() {
153 | return segmentData.getBottomRightRadius();
154 | }
155 |
156 | public int getBottomLeftRadius() {
157 | return segmentData.getBottomLeftRadius();
158 | }
159 |
160 | public boolean isRadiusForEverySegment() {
161 | return segmentData.isRadiusForEverySegment();
162 | }
163 |
164 | protected abstract void onSegmentBind(D segmentData);
165 | }
166 |
--------------------------------------------------------------------------------
/segmentedcontrolmodule/src/main/java/segmented_control/widget/custom/android/com/segmentedcontrol/listeners/OnSegmentClickListener.java:
--------------------------------------------------------------------------------
1 | package segmented_control.widget.custom.android.com.segmentedcontrol.listeners;
2 |
3 | import segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentViewHolder;
4 |
5 | /**
6 | * Created by Robert Apikyan on 9/7/2017.
7 | */
8 |
9 | public interface OnSegmentClickListener {
10 | /**
11 | * @param segmentViewHolder, the clicked segment view holder instance
12 | */
13 | void onSegmentClick(SegmentViewHolder segmentViewHolder);
14 | }
15 |
--------------------------------------------------------------------------------
/segmentedcontrolmodule/src/main/java/segmented_control/widget/custom/android/com/segmentedcontrol/listeners/OnSegmentSelectRequestListener.java:
--------------------------------------------------------------------------------
1 | package segmented_control.widget.custom.android.com.segmentedcontrol.listeners;
2 |
3 | import segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentViewHolder;
4 |
5 | /**
6 | * Created by Robert Apikyan on 9/12/2017.
7 | */
8 |
9 | public interface OnSegmentSelectRequestListener {
10 | /**
11 | * The event will be triggered before perform segment selection,and after segment click event
12 | *
13 | * @param segmentViewHolder, clicked segment view holder
14 | * @return false segment selection will be ignored, true segment selection will be performed
15 | */
16 | boolean onSegmentSelectRequest(SegmentViewHolder segmentViewHolder);
17 | }
18 |
--------------------------------------------------------------------------------
/segmentedcontrolmodule/src/main/java/segmented_control/widget/custom/android/com/segmentedcontrol/listeners/OnSegmentSelectedListener.java:
--------------------------------------------------------------------------------
1 | package segmented_control.widget.custom.android.com.segmentedcontrol.listeners;
2 |
3 | import segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentViewHolder;
4 |
5 | /**
6 | * Created by Robert Apikyan on 9/7/2017.
7 | */
8 |
9 | public interface OnSegmentSelectedListener {
10 | /**
11 | * The Event will be triggered: if the segment is selected, reselected and unSelected
12 | * 1. Segment is selected for first time: isSelected = true ,isReselected = false
13 | * 2. Segment is reselected: isSelected = true ,isReselected = true
14 | * 3. Segment is unSelected: isSelected = false ,isReselected = false
15 | *
16 | * @param segmentViewHolder event related segmentViewHolder
17 | * @param isSelected, true segment is selected
18 | * @param isReselected, true segment is reselected
19 | */
20 | void onSegmentSelected(SegmentViewHolder segmentViewHolder, boolean isSelected, boolean isReselected);
21 | }
22 |
--------------------------------------------------------------------------------
/segmentedcontrolmodule/src/main/java/segmented_control/widget/custom/android/com/segmentedcontrol/utils/ArgbEvaluator.java:
--------------------------------------------------------------------------------
1 | package segmented_control.widget.custom.android.com.segmentedcontrol.utils;
2 |
3 | import android.animation.TypeEvaluator;
4 | import android.animation.ValueAnimator;
5 |
6 | public class ArgbEvaluator implements TypeEvaluator {
7 | private static final android.animation.ArgbEvaluator sInstance = new android.animation.ArgbEvaluator();
8 |
9 | /**
10 | * Returns an instance of ArgbEvaluator
that may be used in
11 | * {@link ValueAnimator#setEvaluator(TypeEvaluator)}. The same instance may
12 | * be used in multiple Animator
s because it holds no state.
13 | * @return An instance of ArgbEvalutor
.
14 | *
15 | * @hide
16 | */
17 | public static android.animation.ArgbEvaluator getInstance() {
18 | return sInstance;
19 | }
20 |
21 | /**
22 | * This function returns the calculated in-between value for a color
23 | * given integers that represent the start and end values in the four
24 | * bytes of the 32-bit int. Each channel is separately linearly interpolated
25 | * and the resulting calculated values are recombined into the return value.
26 | *
27 | * @param fraction The fraction from the starting to the ending values
28 | * @param startValue A 32-bit int value representing colors in the
29 | * separate bytes of the parameter
30 | * @param endValue A 32-bit int value representing colors in the
31 | * separate bytes of the parameter
32 | * @return A value that is calculated to be the linearly interpolated
33 | * result, derived by separating the start and end values into separate
34 | * color channels and interpolating each one separately, recombining the
35 | * resulting values in the same way.
36 | */
37 | public Object evaluate(float fraction, Object startValue, Object endValue) {
38 | int startInt = (Integer) startValue;
39 | float startA = ((startInt >> 24) & 0xff) / 255.0f;
40 | float startR = ((startInt >> 16) & 0xff) / 255.0f;
41 | float startG = ((startInt >> 8) & 0xff) / 255.0f;
42 | float startB = ( startInt & 0xff) / 255.0f;
43 |
44 | int endInt = (Integer) endValue;
45 | float endA = ((endInt >> 24) & 0xff) / 255.0f;
46 | float endR = ((endInt >> 16) & 0xff) / 255.0f;
47 | float endG = ((endInt >> 8) & 0xff) / 255.0f;
48 | float endB = ( endInt & 0xff) / 255.0f;
49 |
50 | // convert from sRGB to linear
51 | startR = (float) Math.pow(startR, 2.2);
52 | startG = (float) Math.pow(startG, 2.2);
53 | startB = (float) Math.pow(startB, 2.2);
54 |
55 | endR = (float) Math.pow(endR, 2.2);
56 | endG = (float) Math.pow(endG, 2.2);
57 | endB = (float) Math.pow(endB, 2.2);
58 |
59 | // compute the interpolated color in linear space
60 | float a = startA + fraction * (endA - startA);
61 | float r = startR + fraction * (endR - startR);
62 | float g = startG + fraction * (endG - startG);
63 | float b = startB + fraction * (endB - startB);
64 |
65 | // convert back to sRGB in the [0..255] range
66 | a = a * 255.0f;
67 | r = (float) Math.pow(r, 1.0 / 2.2) * 255.0f;
68 | g = (float) Math.pow(g, 1.0 / 2.2) * 255.0f;
69 | b = (float) Math.pow(b, 1.0 / 2.2) * 255.0f;
70 |
71 | return Math.round(a) << 24 | Math.round(r) << 16 | Math.round(g) << 8 | Math.round(b);
72 | }
73 | }
--------------------------------------------------------------------------------
/segmentedcontrolmodule/src/main/java/segmented_control/widget/custom/android/com/segmentedcontrol/utils/Utils.java:
--------------------------------------------------------------------------------
1 | package segmented_control.widget.custom.android.com.segmentedcontrol.utils;
2 |
3 | import android.animation.ObjectAnimator;
4 | import android.animation.ValueAnimator;
5 | import android.graphics.drawable.Drawable;
6 | import android.graphics.drawable.GradientDrawable;
7 | import android.support.annotation.IntRange;
8 | import android.view.View;
9 |
10 | import segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentBackgroundType;
11 | import segmented_control.widget.custom.android.com.segmentedcontrol.item_row_column.SegmentViewHolder;
12 |
13 | /**
14 | * Created by Robert Apikyan on 9/8/2017.
15 | */
16 |
17 | public class Utils {
18 | public static T lazy(T nullable, T nonNull) {
19 | if (nullable == null) {
20 | nullable = nonNull;
21 | }
22 | return nullable;
23 | }
24 |
25 | /**
26 | * Utility method, use to define segment background type
27 | *
28 | * @param absolutePosition, Segment absolute position from {@link SegmentViewHolder#getAbsolutePosition()}
29 | * @param columnCount, from {@link SegmentViewHolder#getColumnCount()}
30 | * @param size, from {@link SegmentViewHolder#getCurrentSize()}
31 | * @return {@link SegmentBackgroundType}
32 | */
33 | @SegmentBackgroundType
34 | public static int defineSegmentBackground(@IntRange(from = 0) int absolutePosition, @IntRange(from = 1) int columnCount, @IntRange(from = 1) int size) {
35 |
36 | // if only one item
37 | if (size == 1) {
38 | return SegmentBackgroundType.SINGLE_BG;
39 | }
40 |
41 | // if one column
42 | if (columnCount == 1) {
43 | // for first
44 | if (absolutePosition == 0) {
45 | return SegmentBackgroundType.TOP_SINGLE_BG;
46 | }
47 |
48 | // for last
49 | if (absolutePosition == size - 1) {
50 | return SegmentBackgroundType.BOTTOM_SINGLE_BG;
51 | }
52 | }
53 |
54 | // if not one column, but one row
55 | if (size <= columnCount) {
56 | if (absolutePosition == 0) {
57 | return SegmentBackgroundType.TOP_LEFT_SINGLE_BG;
58 | }
59 |
60 | if (absolutePosition == size - 1) {
61 | return SegmentBackgroundType.TOP_RIGHT_SINGLE_BG;
62 | }
63 | }
64 |
65 | // if not one column and multi row
66 | if (absolutePosition == 0) {
67 | return SegmentBackgroundType.TOP_LEFT_BG;
68 | }
69 |
70 | if (absolutePosition == columnCount - 1) {
71 | return SegmentBackgroundType.TOP_RIGHT_BG;
72 | }
73 |
74 | int notCompletedRowItemsCount = size % columnCount;
75 |
76 | int completeRowsItemsCount = size - notCompletedRowItemsCount;
77 |
78 | if (notCompletedRowItemsCount == 1 && absolutePosition == completeRowsItemsCount) {
79 | return SegmentBackgroundType.BOTTOM_SINGLE_BG;
80 | }
81 |
82 | if (notCompletedRowItemsCount == 0) {
83 | if (absolutePosition == size - columnCount) {
84 | return SegmentBackgroundType.BOTTOM_LEFT_BG;
85 | }
86 | if (absolutePosition == size - 1) {
87 | return SegmentBackgroundType.BOTTOM_RIGHT_BG;
88 | }
89 | } else if (notCompletedRowItemsCount > 0) {
90 | if (absolutePosition == size - notCompletedRowItemsCount) {
91 | return SegmentBackgroundType.BOTTOM_LEFT_BG;
92 | }
93 | if (absolutePosition == size - 1) {
94 | return SegmentBackgroundType.BOTTOM_RIGHT_BG;
95 | }
96 | }
97 |
98 | return SegmentBackgroundType.MIDDLE_BG;
99 | }
100 |
101 | /**
102 | * Use to define segment corner radius
103 | *
104 | * @param absolutePosition, Segment absolute position from {@link SegmentViewHolder#getAbsolutePosition()}
105 | * @param columnCount, from {@link SegmentViewHolder#getColumnCount()}
106 | * @param size, from {@link SegmentViewHolder#getCurrentSize()}
107 | * @param topLeftRadius, from {@link SegmentViewHolder#getTopLeftRadius()}
108 | * @param topRightRadius, from {@link SegmentViewHolder#getTopRightRadius()} ()}
109 | * @param bottomRightRadius, from {@link SegmentViewHolder#getBottomRightRadius()}
110 | * @param bottomLeftRadius, from {@link SegmentViewHolder#getBottomLeftRadius()}
111 | * @return, float[] corners radius,
112 | */
113 | public static float[] defineRadiusForPosition(@IntRange(from = 0) int absolutePosition, @IntRange(from = 1) int columnCount, @IntRange(from = 1) int size,
114 | int topLeftRadius, int topRightRadius, int bottomRightRadius, int bottomLeftRadius) {
115 | @SegmentBackgroundType
116 | int bgType = defineSegmentBackground(absolutePosition, columnCount, size);
117 |
118 | switch (bgType) {
119 |
120 | case SegmentBackgroundType.BOTTOM_LEFT_BG:
121 | return createRadius(0, 0, 0, bottomLeftRadius);
122 |
123 | case SegmentBackgroundType.BOTTOM_RIGHT_BG:
124 | return createRadius(0, 0, bottomRightRadius, 0);
125 |
126 | case SegmentBackgroundType.BOTTOM_SINGLE_BG:
127 | return createRadius(0, 0, bottomRightRadius, bottomLeftRadius);
128 |
129 | case SegmentBackgroundType.MIDDLE_BG:
130 | return createRadius(0, 0, 0, 0);
131 |
132 | case SegmentBackgroundType.SINGLE_BG:
133 | return createRadius(topLeftRadius, topRightRadius, bottomRightRadius, bottomLeftRadius);
134 |
135 | case SegmentBackgroundType.TOP_LEFT_BG:
136 | return createRadius(topLeftRadius, 0, 0, 0);
137 |
138 | case SegmentBackgroundType.TOP_LEFT_SINGLE_BG:
139 | return createRadius(topLeftRadius, 0, 0, bottomLeftRadius);
140 |
141 | case SegmentBackgroundType.TOP_RIGHT_BG:
142 | return createRadius(0, topRightRadius, 0, 0);
143 |
144 | case SegmentBackgroundType.TOP_RIGHT_SINGLE_BG:
145 | return createRadius(0, topRightRadius, bottomRightRadius, 0);
146 |
147 | case SegmentBackgroundType.TOP_SINGLE_BG:
148 | return createRadius(topLeftRadius, topRightRadius, 0, 0);
149 |
150 | default:
151 | return createRadius(0, 0, 0, 0);
152 | }
153 | }
154 |
155 | public static float[] createRadius(float topLeft, float topRight, float bottomRight, float bottomLeft) {
156 | return new float[]{topLeft, topLeft, topRight, topRight, bottomRight, bottomRight, bottomLeft, bottomLeft};
157 | }
158 |
159 | /**
160 | * @param strokeWidth, stroke width
161 | * @param strokeColor, stroke color
162 | * @param argb, background color
163 | * @param radii, use {@link #defineRadiusForPosition(int, int, int, int, int, int, int)} method to define radii
164 | * @return background drawable
165 | */
166 | public static Drawable getBackground(int strokeWidth, int strokeColor, int argb, float[] radii) {
167 | GradientDrawable drawable = new GradientDrawable();
168 | drawable.setShape(GradientDrawable.RECTANGLE);
169 | drawable.setStroke(strokeWidth, strokeColor);
170 | drawable.setCornerRadii(radii);
171 | drawable.setColor(argb);
172 | return drawable;
173 | }
174 |
175 | public static ValueAnimator createBackgroundAnimation(int argbStart, int argbEnd) {
176 | return ValueAnimator.ofObject(ArgbEvaluator.getInstance(), argbStart, argbEnd);
177 | }
178 |
179 | public static boolean isInBounds(float touchX, float touchY, float viewX, float viewY, float viewW, float viewH) {
180 | return touchX >= viewX && touchX <= viewX + viewW && // in x bounds
181 | touchY >= viewY && touchY <= viewY + viewH;
182 | }
183 | }
184 |
--------------------------------------------------------------------------------
/segmentedcontrolmodule/src/main/res/layout/item_segment_impl.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/segmentedcontrolmodule/src/main/res/values/attr.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/segmentedcontrolmodule/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
--------------------------------------------------------------------------------
/segmentedcontrolmodule/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | SegmentedControl
3 |
4 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':segmentedcontrolmodule'
2 |
--------------------------------------------------------------------------------