Created
February 2, 2017 19:04
-
-
Save mduisenov/7235a15072d4c6023ab51232f68845d6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.vk.dialogsample.widget.expandable; | |
import android.animation.Animator; | |
import android.animation.ObjectAnimator; | |
import android.animation.TimeInterpolator; | |
import android.animation.ValueAnimator; | |
import android.annotation.TargetApi; | |
import android.content.Context; | |
import android.graphics.Canvas; | |
import android.graphics.Color; | |
import android.graphics.Paint; | |
import android.graphics.drawable.Drawable; | |
import android.util.AttributeSet; | |
import android.util.Log; | |
import android.view.MotionEvent; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.view.animation.AccelerateDecelerateInterpolator; | |
import com.vk.dialogsample.R; | |
public class ExpandableBarLayout extends ViewGroup { | |
private static final int ANIMATION_DURATION = 400; | |
private static final int SCRIM_MAX_OPACITY = 102; | |
private View mBackgroundView; | |
private View mExpandButton; | |
private View mExpandPanel; | |
private VoidFloat mListener; | |
private VoidFBool mOpenListener; | |
private boolean mOpened; | |
private TimeInterpolator mInterpolator = new AccelerateDecelerateInterpolator(); | |
public ExpandableBarLayout(Context paramContext) { | |
super(paramContext); | |
setWillNotDraw(false); | |
this.mScrimPaint.setColor(Color.BLACK); | |
this.mScrimPaint.setAlpha(SCRIM_MAX_OPACITY); | |
} | |
public ExpandableBarLayout(Context paramContext, AttributeSet paramAttributeSet) { | |
super(paramContext, paramAttributeSet); | |
setWillNotDraw(false); | |
this.mScrimPaint.setColor(Color.BLACK); | |
this.mScrimPaint.setAlpha(SCRIM_MAX_OPACITY); | |
} | |
public ExpandableBarLayout(Context paramContext, AttributeSet paramAttributeSet, int paramInt) { | |
super(paramContext, paramAttributeSet, paramInt); | |
setWillNotDraw(false); | |
this.mScrimPaint.setColor(Color.BLACK); | |
this.mScrimPaint.setAlpha(SCRIM_MAX_OPACITY); | |
} | |
@TargetApi(21) | |
public ExpandableBarLayout(Context paramContext, AttributeSet paramAttributeSet, int paramInt1, int paramInt2) { | |
super(paramContext, paramAttributeSet, paramInt1, paramInt2); | |
setWillNotDraw(false); | |
this.mScrimPaint.setColor(Color.BLACK); | |
this.mScrimPaint.setAlpha(SCRIM_MAX_OPACITY); | |
} | |
private final Paint mScrimPaint = new Paint(); | |
private Drawable mShadow = getResources().getDrawable(R.drawable.bg_search_expand_shadow); | |
@Override | |
protected void onFinishInflate() { | |
super.onFinishInflate(); | |
Log.d("ExpandableBarLayout", "onFinishInflate()"); | |
this.mBackgroundView = getChildAt(0); | |
this.mExpandButton = getChildAt(1); | |
this.mExpandPanel = getChildAt(2); | |
if (this.mExpandPanel != null) { | |
this.mExpandButton.setOnClickListener(new OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
toggle(); | |
} | |
}); | |
// this.mExpandButton.setOnClickListener(ExpandableBarLayout..Lambda.1.lambdaFactory$(this)) | |
} | |
} | |
public boolean hasOverlappingRendering() { | |
return false; | |
} | |
public boolean hasTransientState() { | |
return false; | |
} | |
@Override | |
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | |
super.onMeasure(widthMeasureSpec, heightMeasureSpec); | |
Log.d("ExpandableBarLayout", "onMeasure()"); | |
int childMeasureWidth = MeasureSpec.makeMeasureSpec(getMeasuredWidth() - getPaddingLeft() - getPaddingRight(), MeasureSpec.EXACTLY); | |
int height = getMeasuredHeight() - getPaddingTop() - getPaddingBottom(); | |
if (this.mExpandButton.getLayoutParams().height >= 0) { | |
this.mExpandButton.measure(childMeasureWidth, MeasureSpec.makeMeasureSpec(this.mExpandButton.getLayoutParams().height, MeasureSpec.EXACTLY)); | |
} else { | |
this.mExpandButton.measure(childMeasureWidth, MeasureSpec.makeMeasureSpec(this.mExpandButton.getLayoutParams().height, MeasureSpec.AT_MOST)); | |
} | |
height -= this.mExpandButton.getMeasuredHeight(); | |
if (this.mExpandPanel != null) { | |
this.mExpandPanel.measure(childMeasureWidth, MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST)); | |
} | |
this.mBackgroundView.measure(childMeasureWidth, MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); | |
} | |
@Override | |
protected void onLayout(boolean changed, | |
int l, int t, int r, int b) { | |
Log.d("ExpandableBarLayout", "onLayout()"); | |
int left = getPaddingLeft(); | |
int top = getPaddingTop(); | |
int buttonBottom = mExpandButton == null ? 0 : mExpandButton.getMeasuredHeight(); | |
if (mBackgroundView != null) { | |
mBackgroundView.layout(left, buttonBottom, (mBackgroundView.getMeasuredWidth() + left), (mBackgroundView.getMeasuredHeight() + buttonBottom)); | |
} | |
if ((mExpandPanel != null) && (mExpandPanel.getVisibility() == VISIBLE)) { | |
mExpandPanel.layout(left, buttonBottom, (mExpandPanel.getMeasuredWidth() + left), (mExpandPanel.getMeasuredHeight() + buttonBottom)); | |
} | |
if (mExpandButton != null) { | |
mExpandButton.layout(left, top, (mExpandButton.getMeasuredWidth() + left), buttonBottom); | |
} | |
} | |
@Override | |
protected void dispatchDraw(Canvas paramCanvas) { | |
super.dispatchDraw(paramCanvas); | |
Log.d("ExpandableBarLayout", "dispatchDraw()"); | |
if ((mOpened) && (mExpandPanel != null)) { | |
int bottom = (int) ((float) mExpandPanel.getBottom() + mExpandPanel.getTranslationY()); | |
paramCanvas.drawRect(0.0f, (float) bottom, (float) getRight(), (float) getBottom(), mScrimPaint); | |
if (mShadow != null) { | |
mShadow.setBounds(0, bottom, getWidth(), (mShadow.getIntrinsicHeight() + bottom)); | |
mShadow.draw(paramCanvas); | |
} | |
return; | |
} | |
if (mShadow != null) { | |
mShadow.setBounds(0, mExpandButton.getBottom(), getWidth(), (mExpandButton.getBottom() + mShadow.getIntrinsicHeight())); | |
mShadow.draw(paramCanvas); | |
} | |
} | |
@Override | |
public boolean dispatchTouchEvent(MotionEvent paramMotionEvent) { | |
Log.d("ExpandableBarLayout", "dispatchTouchEvent()"); | |
if ((mOpened) && (mExpandPanel != null)) { | |
int bottom = (int) ((float) mExpandPanel.getBottom() + mExpandPanel.getTranslationY()); | |
if (paramMotionEvent.getY() > (float) bottom) { | |
if ((paramMotionEvent.getAction() == MotionEvent.ACTION_UP) || (paramMotionEvent.getAction() == MotionEvent.ACTION_CANCEL)) { | |
closePanel(); | |
return true; | |
} | |
} | |
} | |
return super.dispatchTouchEvent(paramMotionEvent); | |
} | |
@Override | |
protected boolean drawChild(Canvas paramCanvas, View paramView, long paramLong) { | |
Log.d("ExpandableBarLayout", "drawChild()"); | |
if ((mOpened) && (paramView == mBackgroundView) && (mExpandPanel != null)) { | |
int count = paramCanvas.save(); | |
paramCanvas.clipRect(0.0f, ((float) mExpandPanel.getBottom() + mExpandPanel.getTranslationY()), (float) getWidth(), (float) getHeight()); | |
boolean result = super.drawChild(paramCanvas, paramView, paramLong); | |
paramCanvas.restoreToCount(count); | |
return result; | |
} | |
if (paramView == mExpandPanel) { | |
int count = paramCanvas.save(); | |
paramCanvas.clipRect(0.0F, mExpandButton.getBottom(), getWidth(), getBottom()); | |
boolean result = super.drawChild(paramCanvas, paramView, paramLong); | |
paramCanvas.restoreToCount(count); | |
return result; | |
} | |
return super.drawChild(paramCanvas, paramView, paramLong); | |
} | |
public void openPanel() { | |
if (this.mExpandPanel == null) { | |
return; | |
} | |
ObjectAnimator localObjectAnimator = ObjectAnimator.ofFloat(this.mExpandPanel, "translationY", -this.mExpandPanel.getMeasuredHeight(), 0.0F); | |
localObjectAnimator.setDuration(ANIMATION_DURATION); | |
localObjectAnimator.setInterpolator(this.mInterpolator); | |
localObjectAnimator.addListener(new Animator.AnimatorListener() { | |
@Override | |
public void onAnimationStart(Animator paramAnonymousAnimator) { | |
// ExpandableBarLayout.access$002(ExpandableBarLayout.this, true); | |
mOpenListener.f(true); | |
ExpandableBarLayout.this.mExpandPanel.setVisibility(VISIBLE); | |
if (ExpandableBarLayout.this.mOpenListener != null) { | |
ExpandableBarLayout.this.mOpenListener.f(ExpandableBarLayout.this.mOpened); | |
} | |
} | |
@Override | |
public void onAnimationCancel(Animator paramAnonymousAnimator) { | |
} | |
@Override | |
public void onAnimationEnd(Animator paramAnonymousAnimator) { | |
} | |
@Override | |
public void onAnimationRepeat(Animator paramAnonymousAnimator) { | |
} | |
}); | |
localObjectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { | |
@Override | |
public void onAnimationUpdate(ValueAnimator animation) { | |
mListener.f(animation.getAnimatedFraction()); | |
mOpened = true; | |
} | |
}); | |
// localObjectAnimator.addUpdateListener(ExpandableBarLayout..Lambda .2.lambdaFactory$(this)) | |
localObjectAnimator.start(); | |
} | |
public void closePanel() { | |
if (this.mExpandPanel == null) { | |
return; | |
} | |
ObjectAnimator animator = ObjectAnimator.ofFloat(this.mExpandPanel, "translationY", 0.0F, -this.mExpandPanel.getMeasuredHeight()); | |
animator.setDuration(ANIMATION_DURATION); | |
animator.setInterpolator(this.mInterpolator); | |
animator.addListener(new Animator.AnimatorListener() { | |
@Override | |
public void onAnimationCancel(Animator paramAnonymousAnimator) { | |
// ExpandableBarLayout.access$002(ExpandableBarLayout.this, false); | |
mOpenListener.f(false); | |
ExpandableBarLayout.this.mExpandPanel.setVisibility(GONE); | |
if (ExpandableBarLayout.this.mOpenListener != null) { | |
ExpandableBarLayout.this.mOpenListener.f(ExpandableBarLayout.this.mOpened); | |
} | |
} | |
@Override | |
public void onAnimationEnd(Animator paramAnonymousAnimator) { | |
// ExpandableBarLayout.access$002(ExpandableBarLayout.this, false); | |
ExpandableBarLayout.this.mExpandPanel.setVisibility(GONE); | |
if (ExpandableBarLayout.this.mOpenListener != null) { | |
ExpandableBarLayout.this.mOpenListener.f(ExpandableBarLayout.this.mOpened); | |
} | |
} | |
@Override | |
public void onAnimationRepeat(Animator paramAnonymousAnimator) { | |
} | |
@Override | |
public void onAnimationStart(Animator paramAnonymousAnimator) { | |
} | |
}); | |
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { | |
@Override | |
public void onAnimationUpdate(ValueAnimator animation) { | |
mListener.f(-animation.getAnimatedFraction()); | |
mOpened = false; | |
} | |
}); | |
// localObjectAnimator.addUpdateListener(ExpandableBarLayout..Lambda .3.lambdaFactory$(this)) | |
animator.start(); | |
} | |
public void setOpenListener(VoidFBool paramVoidFBool) { | |
this.mOpenListener = paramVoidFBool; | |
} | |
public void setProgressListener(VoidFloat paramVoidFloat) { | |
this.mListener = paramVoidFloat; | |
} | |
public void toggle() { | |
if (this.mOpened) { | |
closePanel(); | |
return; | |
} | |
openPanel(); | |
} | |
public boolean isOpened() { | |
return this.mOpened; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment