package zendesk.belvedere; import android.animation.ValueAnimator; import android.content.Context; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.RestrictTo; import android.support.v4.content.ContextCompat; import android.support.v4.view.ViewCompat; import android.util.AttributeSet; import android.view.Gravity; import android.view.View; import android.widget.FrameLayout; import android.widget.ImageView; import zendesk.belvedere.ui.R; /** * For internal use only. */ @RestrictTo(RestrictTo.Scope.LIBRARY) public class SelectableView extends FrameLayout implements View.OnClickListener { private final static long ANIMATION_DURATION = 75L; private final static float SELECTED_SCALE = .9F; private final static float SELECTED_ALPHA = .8F; private SelectionListener selectionListener; private View child; private View checkbox; private String descSelected, descUnselected; public SelectableView(@NonNull Context context) { super(context); init(); } public SelectableView(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } public SelectableView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { setClickable(true); setFocusable(true); setOnClickListener(this); final int colorPrimary = Utils.getThemeColor(getContext(), R.attr.colorPrimary); checkbox = getCheckBox(colorPrimary); addView(checkbox); } public void setContentDescriptionStrings(String selected, String unselected) { descSelected = selected; descUnselected = unselected; setContentDesc(isSelected()); } @Override public void onClick(final View view) { final boolean selected = !isSelected(); final boolean changeSelection; if (selectionListener != null) { changeSelection = selectionListener.onSelectionChanged(selected); } else { changeSelection = true; } if (changeSelection) { setSelected(selected); final ValueAnimator scaleAnimator; final ValueAnimator alphaAnimator; if (selected) { scaleAnimator = ValueAnimator.ofFloat(1F, SELECTED_SCALE); alphaAnimator = ValueAnimator.ofFloat(1F, SELECTED_ALPHA); } else { scaleAnimator = ValueAnimator.ofFloat(SELECTED_SCALE, 1F); alphaAnimator = ValueAnimator.ofFloat(SELECTED_ALPHA, 1F); } scaleAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { scale((float) valueAnimator.getAnimatedValue()); } }); alphaAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { alpha((float) valueAnimator.getAnimatedValue()); } }); alphaAnimator.setDuration(ANIMATION_DURATION); scaleAnimator.setDuration(ANIMATION_DURATION); scaleAnimator.start(); alphaAnimator.start(); } } @Override public void setSelected(boolean selected) { super.setSelected(selected); if(selected) { scale(SELECTED_SCALE); alpha(SELECTED_ALPHA); checkbox(true); setContentDesc(true); } else { scale(1.0F); alpha(1.0F); checkbox(false); setContentDesc(false); } } public void setSelectionListener(SelectionListener selectionListener) { this.selectionListener = selectionListener; } private ImageView getCheckBox(int colorPrimary) { final FrameLayout.LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); params.gravity = Gravity.CENTER; final ImageView imageView = new ImageView(getContext()); imageView.setId(R.id.belvedere_selectable_view_checkbox); imageView.setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.belvedere_ic_check_circle)); ViewCompat.setBackground(imageView, ContextCompat.getDrawable(getContext(), R.drawable.belvedere_ic_check_bg)); imageView.setLayoutParams(params); imageView.setVisibility(View.GONE); Utils.internalSetTint(imageView, colorPrimary); return imageView; } private void checkbox(boolean visible) { if(visible) { checkbox.setVisibility(View.VISIBLE); checkbox.bringToFront(); ViewCompat.setElevation(checkbox, ViewCompat.getElevation(child) + 1); } else { checkbox.setVisibility(View.GONE); } } private void scale(float value) { getChild().setScaleX(value); getChild().setScaleY(value); } private void alpha(float value) { getChild().setAlpha(value); } private View getChild() { if(child != null) { return child; } if(getChildCount() != 2) { throw new RuntimeException("More then one child added to SelectableView"); } for(int i = 0; i < getChildCount(); i++) { final View c = getChildAt(i); if(c.getId() != R.id.belvedere_selectable_view_checkbox) { child = c; break; } } return child; } private void setContentDesc(boolean selected) { if (selected) { setContentDescription(descSelected); } else { setContentDescription(descUnselected); } } interface SelectionListener { boolean onSelectionChanged(boolean selected); } }