Created
June 21, 2014 13:24
-
-
Save alorma/e23fb921b46777310381 to your computer and use it in GitHub Desktop.
Easy class that shows floating view in right bottom corner of ABsListView
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 android.widget; | |
import android.os.CountDownTimer; | |
import android.view.View; | |
/** | |
* Created by a557114 on 20/06/2014. | |
*/ | |
public class DirectionalScrollListener implements AbsListView.OnScrollListener { | |
private int oldTop; | |
private int oldFirstVisibleItem; | |
private OnDetectScrollListener onDetectScrollListener; | |
private AbsListView.OnScrollListener handlerScroll; | |
private long countdownStop; | |
private boolean enabled; | |
public DirectionalScrollListener(OnDetectScrollListener onDetectScrollListener) { | |
this.onDetectScrollListener = onDetectScrollListener; | |
this.countdownStop = -1; | |
} | |
public DirectionalScrollListener(OnCancelableDetectScrollListener onDetectScrollListener, AbsListView.OnScrollListener handlerScroll, long countdownStop) { | |
this.onDetectScrollListener = onDetectScrollListener; | |
this.handlerScroll = handlerScroll; | |
this.countdownStop = countdownStop; | |
} | |
@Override | |
public void onScrollStateChanged(AbsListView view, int scrollState) { | |
if (handlerScroll != null) { | |
handlerScroll.onScrollStateChanged(view, scrollState); | |
} | |
enabled = scrollState == SCROLL_STATE_TOUCH_SCROLL; | |
if (scrollState == SCROLL_STATE_IDLE && countdownStop > -1) { | |
new CountDownTimer(countdownStop, 10) { | |
@Override | |
public void onTick(long millisUntilFinished) { | |
} | |
@Override | |
public void onFinish() { | |
if (onDetectScrollListener != null && onDetectScrollListener instanceof OnCancelableDetectScrollListener) { | |
((OnCancelableDetectScrollListener) onDetectScrollListener).onScrollStop(); | |
} | |
} | |
}.start(); | |
} | |
} | |
@Override | |
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { | |
if (handlerScroll != null) { | |
handlerScroll.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount); | |
} | |
if (onDetectScrollListener != null) { | |
onDetectedListScroll(view, firstVisibleItem); | |
} | |
} | |
private void onDetectedListScroll(AbsListView absListView, int firstVisibleItem) { | |
if (enabled) { | |
View view = absListView.getChildAt(0); | |
int top = (view == null) ? 0 : view.getTop(); | |
if (firstVisibleItem == oldFirstVisibleItem) { | |
if (top > oldTop) { | |
up(); | |
} else if (top < oldTop) { | |
down(); | |
} | |
} else { | |
if (firstVisibleItem < oldFirstVisibleItem) { | |
up(); | |
} else { | |
down(); | |
} | |
} | |
oldTop = top; | |
oldFirstVisibleItem = firstVisibleItem; | |
} | |
} | |
private void up() { | |
if (onDetectScrollListener != null) { | |
onDetectScrollListener.onUpScrolling(); | |
} | |
if (handlerScroll != null && handlerScroll instanceof OnDetectScrollListener) { | |
((OnDetectScrollListener) handlerScroll).onUpScrolling(); | |
} | |
} | |
private void down() { | |
if (onDetectScrollListener != null) { | |
onDetectScrollListener.onDownScrolling(); | |
} | |
if (handlerScroll != null && handlerScroll instanceof OnDetectScrollListener) { | |
((OnDetectScrollListener) handlerScroll).onDownScrolling(); | |
} | |
} | |
public interface OnDetectScrollListener { | |
void onUpScrolling(); | |
void onDownScrolling(); | |
} | |
public interface OnCancelableDetectScrollListener extends OnDetectScrollListener { | |
void onScrollStop(); | |
} | |
public OnDetectScrollListener getOnDetectScrollListener() { | |
return onDetectScrollListener; | |
} | |
public void setOnDetectScrollListener(OnDetectScrollListener onDetectScrollListener) { | |
this.onDetectScrollListener = onDetectScrollListener; | |
} | |
public AbsListView.OnScrollListener getHandlerScroll() { | |
return handlerScroll; | |
} | |
public void setHandlerScroll(AbsListView.OnScrollListener handlerScroll) { | |
this.handlerScroll = handlerScroll; | |
} | |
public long getCountdownStop() { | |
return countdownStop; | |
} | |
public void setCountdownStop(long countdownStop) { | |
this.countdownStop = countdownStop; | |
} | |
} | |
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 android.widget; | |
import android.animation.Animator; | |
import android.animation.ObjectAnimator; | |
import android.animation.PropertyValuesHolder; | |
import android.animation.ValueAnimator; | |
import android.content.Context; | |
import android.util.AttributeSet; | |
import android.view.View; | |
import android.view.ViewGroup; | |
/** | |
* Created by a557114 on 20/06/2014. | |
*/ | |
public class GoatLayout extends FrameLayout implements DirectionalScrollListener.OnCancelableDetectScrollListener { | |
private View floatView; | |
private ObjectAnimator upAnimation; | |
private ObjectAnimator downAnimation; | |
private float fraction = 1.0f; | |
private FLOAT_STATE float_state; | |
private int marginRight; | |
private int marginBottom; | |
private float density; | |
private long timeShowOnStop; | |
private AbsListView.OnScrollListener handlerScroll; | |
private DirectionalScrollListener directionalScrollListener; | |
public GoatLayout(Context context) { | |
super(context); | |
init(); | |
} | |
public GoatLayout(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
init(); | |
} | |
public GoatLayout(Context context, AttributeSet attrs, int defStyle) { | |
super(context, attrs, defStyle); | |
init(); | |
} | |
private void init() { | |
density = getResources().getDisplayMetrics().density; | |
marginRight = 10; | |
marginBottom = 10; | |
timeShowOnStop = 400; | |
} | |
public void setFloatView(View floatView) { | |
this.floatView = floatView; | |
if (floatView.getLayoutParams() == null) { | |
int squareSize = (int) (50 * density); | |
LayoutParams layoutParams = new LayoutParams(squareSize, squareSize); | |
floatView.setLayoutParams(layoutParams); | |
} | |
float_state = FLOAT_STATE.VISIBLE; | |
addView(floatView); | |
postInvalidate(); | |
} | |
@Override | |
public void addView(View child, ViewGroup.LayoutParams params) { | |
super.addView(child, params); | |
if (child instanceof AbsListView) { | |
directionalScrollListener = new DirectionalScrollListener(this, handlerScroll, timeShowOnStop); | |
((AbsListView) child).setOnScrollListener(directionalScrollListener); | |
} | |
} | |
@Override | |
protected void onLayout(boolean changed, int left, int top, int right, int bottom) { | |
super.onLayout(changed, left, top, right, bottom); | |
marginRight = (int) (marginRight * density); | |
marginBottom = (int) (marginBottom * density); | |
if (floatView != null) { | |
floatView.layout(right - marginRight - floatView.getMeasuredWidth(), | |
bottom - marginRight - floatView.getMeasuredHeight(), | |
right - marginRight, | |
bottom - marginRight); | |
} | |
} | |
@Override | |
public void onUpScrolling() { | |
if (float_state == FLOAT_STATE.INVISIBLE) { | |
getUpAnimation().start(); | |
} | |
} | |
@Override | |
public void onDownScrolling() { | |
if (float_state == FLOAT_STATE.VISIBLE) { | |
getDownAnimation().start(); | |
} | |
} | |
@Override | |
public void onScrollStop() { | |
if (float_state == FLOAT_STATE.INVISIBLE) { | |
getDownAnimation().cancel(); | |
getUpAnimation().start(); | |
} | |
} | |
private ObjectAnimator getUpAnimation() { | |
if (upAnimation == null) { | |
float initial = getBottom() + floatView.getMeasuredHeight() * fraction; | |
float end = getBottom() - marginRight - floatView.getMeasuredHeight(); | |
PropertyValuesHolder pvhF = PropertyValuesHolder.ofFloat(Y, initial, end); | |
upAnimation = ObjectAnimator.ofPropertyValuesHolder(floatView, pvhF); | |
upAnimation.setDuration(600); | |
upAnimation.setRepeatCount(0); | |
} | |
FloatAnimatorListener floatAnimatorListener = new FloatAnimatorListener(FLOAT_STATE.VISIBLE); | |
upAnimation.addUpdateListener(floatAnimatorListener); | |
upAnimation.addListener(floatAnimatorListener); | |
return upAnimation; | |
} | |
private ObjectAnimator getDownAnimation() { | |
if (downAnimation == null) { | |
float initial = floatView.getY() * fraction; | |
float end = getBottom() + floatView.getMeasuredHeight(); | |
PropertyValuesHolder pvhF = PropertyValuesHolder.ofFloat(Y, initial, end); | |
downAnimation = ObjectAnimator.ofPropertyValuesHolder(floatView, pvhF); | |
downAnimation.setDuration(600); | |
downAnimation.setRepeatCount(0); | |
} | |
FloatAnimatorListener floatAnimatorListener = new FloatAnimatorListener(FLOAT_STATE.INVISIBLE); | |
downAnimation.addUpdateListener(floatAnimatorListener); | |
downAnimation.addListener(floatAnimatorListener); | |
return downAnimation; | |
} | |
private enum FLOAT_STATE { | |
VISIBLE, | |
INVISIBLE, | |
RUNING; | |
} | |
private class FloatAnimatorListener implements Animator.AnimatorListener, ValueAnimator.AnimatorUpdateListener { | |
private FLOAT_STATE stateEnd; | |
public FloatAnimatorListener(FLOAT_STATE stateEnd) { | |
this.stateEnd = stateEnd; | |
} | |
@Override | |
public void onAnimationStart(Animator animation) { | |
float_state = FLOAT_STATE.RUNING; | |
} | |
@Override | |
public void onAnimationEnd(Animator animation) { | |
float_state = stateEnd; | |
} | |
@Override | |
public void onAnimationCancel(Animator animation) { | |
} | |
@Override | |
public void onAnimationRepeat(Animator animation) { | |
} | |
@Override | |
public void onAnimationUpdate(ValueAnimator animation) { | |
fraction = animation.getAnimatedFraction(); | |
} | |
} | |
public void setUpAnimation(ObjectAnimator upAnimation) { | |
this.upAnimation = upAnimation; | |
} | |
public void setDownAnimation(ObjectAnimator downAnimation) { | |
this.downAnimation = downAnimation; | |
} | |
public int getMarginRight() { | |
return marginRight; | |
} | |
public void setMarginRight(int marginRight) { | |
this.marginRight = marginRight; | |
} | |
public int getMarginBottom() { | |
return marginBottom; | |
} | |
public void setMarginBottom(int marginBottom) { | |
this.marginBottom = marginBottom; | |
} | |
public long getTimeShowOnStop() { | |
return timeShowOnStop; | |
} | |
public void setTimeShowOnStop(long timeShowOnStop) { | |
this.timeShowOnStop = timeShowOnStop; | |
directionalScrollListener.setCountdownStop(timeShowOnStop); | |
} | |
public AbsListView.OnScrollListener getHandlerScroll() { | |
return handlerScroll; | |
} | |
public void setHandlerScroll(AbsListView.OnScrollListener handerScroll) { | |
this.handlerScroll = handerScroll; | |
directionalScrollListener.setHandlerScroll(handlerScroll); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment