Skip to content

Instantly share code, notes, and snippets.

@alorma
Created June 21, 2014 13:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alorma/e23fb921b46777310381 to your computer and use it in GitHub Desktop.
Save alorma/e23fb921b46777310381 to your computer and use it in GitHub Desktop.
Easy class that shows floating view in right bottom corner of ABsListView
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;
}
}
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