package im.zico.wingtwitter.ui.view;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.AbsListView;
import com.tjerkw.slideexpandable.library.ActionSlideExpandableListView;
/**
* Created by tinyao on 12/18/14.
*/
public class TweetListView extends ActionSlideExpandableListView {
private static final String TAG = "TweetListView";
public TweetListView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public TweetListView(Context context) {
super(context);
init();
}
public TweetListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
this.setOnScrollListener(scrollListener);
}
private int mLastFirstVisibleItem;
private int mLastChildY;
private ScrollDetectCallback mCallback;
public void setScrollCallback(ScrollDetectCallback callback) {
mCallback = callback;
}
private OnScrollListener scrollListener = new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (mCallback != null) {
if (firstVisibleItem != 0 && mLastFirstVisibleItem == firstVisibleItem && view.getChildAt(0) != null) {
int scrollY = mLastChildY - view.getChildAt(0).getTop();
if (scrollY > 20) {
mCallback.onScrollDown();
} else if (scrollY < -20) {
mCallback.onScrollUp();
}
}
if (view.getChildAt(0) != null) {
mLastChildY = view.getChildAt(0).getTop();
}
mLastFirstVisibleItem = firstVisibleItem;
if (firstVisibleItem + visibleItemCount >= totalItemCount
&& totalItemCount != 0
&& totalItemCount != TweetListView.this.getHeaderViewsCount() + TweetListView.this.getFooterViewsCount()
&& getAdapter().getCount() > 0) {
mCallback.onScrollFooter();
}
}
}
};
public interface ScrollDetectCallback {
public void onScrollDown();
public void onScrollUp();
public void onScrollFooter();
}
private boolean mBlockLayoutChildren;
public void setBlockLayoutChildren(boolean block) {
mBlockLayoutChildren = block;
}
@Override
protected void layoutChildren() {
if (!mBlockLayoutChildren) {
super.layoutChildren();
}
}
// private void init() {
// mChildrenHeights = new SparseIntArray();
// super.setOnScrollListener(mScrollListener);
// }
// private OnScrollListener mOriginalScrollListener;
//
// private OnScrollListener mScrollListener = new OnScrollListener() {
// @Override
// public void onScrollStateChanged(AbsListView view, int scrollState) {
// if (mOriginalScrollListener != null) {
// mOriginalScrollListener.onScrollStateChanged(view, scrollState);
// }
// }
//
// @Override
// public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
// if (mOriginalScrollListener != null) {
// mOriginalScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
// }
//
// onScrollChanged();
// }
// };
// @Override
// public void setScrollViewCallbacks(ObservableScrollViewCallbacks listener) {
// mCallbacks = listener;
// }
// @Override
// public void scrollVerticallyTo(int y) {
// View firstVisibleChild = getChildAt(0);
// if (firstVisibleChild != null) {
// int baseHeight = firstVisibleChild.getHeight();
// int position = y / baseHeight;
// setSelection(position);
// }
// }
//
// @Override
// public int getCurrentScrollY() {
// return mScrollY;
// }
// @Override
// public boolean onTouchEvent(MotionEvent ev) {
// if (mCallbacks != null) {
// switch (ev.getActionMasked()) {
// case MotionEvent.ACTION_DOWN:
// LogUtils.v(TAG, "onTouchEvent: ACTION_DOWN");
// mFirstScroll = mDragging = true;
// mCallbacks.onDownMotionEvent();
// break;
// case MotionEvent.ACTION_UP:
// case MotionEvent.ACTION_CANCEL:
// LogUtils.v(TAG, "onTouchEvent: ACTION_UP|ACTION_CANCEL");
// mDragging = false;
// mCallbacks.onUpOrCancelMotionEvent(mScrollState);
// break;
// }
// }
// return super.onTouchEvent(ev);
// }
// private void onScrollChanged() {
//
// if (mCallbacks != null) {
// if (getChildCount() > 0) {
// int firstVisiblePosition = getFirstVisiblePosition();
// for (int i = getFirstVisiblePosition(), j = 0; i <= getLastVisiblePosition(); i++, j++) {
// if (mChildrenHeights.indexOfKey(i) < 0 || getChildAt(j).getHeight() != mChildrenHeights.get(i)) {
// mChildrenHeights.put(i, getChildAt(j).getHeight());
// }
// }
//
// View firstVisibleChild = getChildAt(0);
// if (firstVisibleChild != null) {
// if (mPrevFirstVisiblePosition < firstVisiblePosition) {
// // scroll down
// int skippedChildrenHeight = 0;
// if (firstVisiblePosition - mPrevFirstVisiblePosition != 1) {
// LogUtils.v(TAG, "Skipped some children while scrolling down: " + (firstVisiblePosition - mPrevFirstVisiblePosition));
// for (int i = firstVisiblePosition - 1; i > mPrevFirstVisiblePosition; i--) {
// if (0 < mChildrenHeights.indexOfKey(i)) {
// skippedChildrenHeight += mChildrenHeights.get(i);
// LogUtils.v(TAG, "Calculate skipped child height at " + i + ": " + mChildrenHeights.get(i));
// } else {
// LogUtils.v(TAG, "Could not calculate skipped child height at " + i);
// // Approximate each item's height to the first visible child.
// // It may be incorrect, but without this, scrollY will be broken
// // when scrolling from the bottom.
// skippedChildrenHeight += firstVisibleChild.getHeight();
// }
// }
// }
// mPrevScrolledChildrenHeight += mPrevFirstVisibleChildHeight + skippedChildrenHeight;
// mPrevFirstVisibleChildHeight = firstVisibleChild.getHeight();
// } else if (firstVisiblePosition < mPrevFirstVisiblePosition) {
// // scroll up
// int skippedChildrenHeight = 0;
// if (mPrevFirstVisiblePosition - firstVisiblePosition != 1) {
// LogUtils.v(TAG, "Skipped some children while scrolling up: " + (mPrevFirstVisiblePosition - firstVisiblePosition));
// for (int i = mPrevFirstVisiblePosition - 1; i > firstVisiblePosition; i--) {
// if (0 < mChildrenHeights.indexOfKey(i)) {
// skippedChildrenHeight += mChildrenHeights.get(i);
// LogUtils.v(TAG, "Calculate skipped child height at " + i + ": " + mChildrenHeights.get(i));
// } else {
// LogUtils.v(TAG, "Could not calculate skipped child height at " + i);
// // Approximate each item's height to the first visible child.
// // It may be incorrect, but without this, scrollY will be broken
// // when scrolling from the bottom.
// skippedChildrenHeight += firstVisibleChild.getHeight();
// }
// }
// }
// mPrevScrolledChildrenHeight -= firstVisibleChild.getHeight() + skippedChildrenHeight;
// mPrevFirstVisibleChildHeight = firstVisibleChild.getHeight();
// } else if (firstVisiblePosition == 0) {
// mPrevFirstVisibleChildHeight = firstVisibleChild.getHeight();
// }
// if (mPrevFirstVisibleChildHeight < 0) {
// mPrevFirstVisibleChildHeight = 0;
// }
// mScrollY = mPrevScrolledChildrenHeight - firstVisibleChild.getTop();
// mPrevFirstVisiblePosition = firstVisiblePosition;
//
// LogUtils.v(TAG, "first: " + firstVisiblePosition + " scrollY: " + mScrollY + " first height: " + firstVisibleChild.getHeight() + " first top: " + firstVisibleChild.getTop());
// mCallbacks.onScrollChanged(mScrollY, mFirstScroll, mDragging);
// if (mFirstScroll) {
// mFirstScroll = false;
// }
//
// if (mPrevScrollY < mScrollY) {
// //down
// mScrollState = ScrollState.UP;
// } else if (mScrollY < mPrevScrollY) {
// //up
// mScrollState = ScrollState.DOWN;
// } else {
// mScrollState = ScrollState.STOP;
// }
// mPrevScrollY = mScrollY;
//
// } else {
// LogUtils.v(TAG, "first: " + firstVisiblePosition);
// }
// }
// }
// }
//
// @Override
// public void onRestoreInstanceState(Parcelable state) {
// SavedState ss = (SavedState) state;
// mPrevFirstVisiblePosition = ss.prevFirstVisiblePosition;
// mPrevFirstVisibleChildHeight = ss.prevFirstVisibleChildHeight;
// mPrevScrolledChildrenHeight = ss.prevScrolledChildrenHeight;
// mPrevScrollY = ss.prevScrollY;
// mScrollY = ss.scrollY;
// mChildrenHeights = ss.childrenHeights;
// super.onRestoreInstanceState(ss.getSuperState());
// }
//
// @Override
// public Parcelable onSaveInstanceState() {
// Parcelable superState = super.onSaveInstanceState();
// SavedState ss = new SavedState(superState);
// ss.prevFirstVisiblePosition = mPrevFirstVisiblePosition;
// ss.prevFirstVisibleChildHeight = mPrevFirstVisibleChildHeight;
// ss.prevScrolledChildrenHeight = mPrevScrolledChildrenHeight;
// ss.prevScrollY = mPrevScrollY;
// ss.scrollY = mScrollY;
// ss.childrenHeights = mChildrenHeights;
// return ss;
// }
//
// static class SavedState extends BaseSavedState {
// int prevFirstVisiblePosition;
// int prevFirstVisibleChildHeight = -1;
// int prevScrolledChildrenHeight;
// int prevScrollY;
// int scrollY;
// SparseIntArray childrenHeights;
//
// SavedState(Parcelable superState) {
// super(superState);
// }
//
// private SavedState(Parcel in) {
// super(in);
// prevFirstVisiblePosition = in.readInt();
// prevFirstVisibleChildHeight = in.readInt();
// prevScrolledChildrenHeight = in.readInt();
// prevScrollY = in.readInt();
// scrollY = in.readInt();
// childrenHeights = new SparseIntArray();
// final int numOfChildren = in.readInt();
// if (0 < numOfChildren) {
// for (int i = 0; i < numOfChildren; i++) {
// final int key = in.readInt();
// final int value = in.readInt();
// childrenHeights.put(key, value);
// }
// }
// }
//
// @Override
// public void writeToParcel(Parcel out, int flags) {
// super.writeToParcel(out, flags);
// out.writeInt(prevFirstVisiblePosition);
// out.writeInt(prevFirstVisibleChildHeight);
// out.writeInt(prevScrolledChildrenHeight);
// out.writeInt(prevScrollY);
// out.writeInt(scrollY);
// final int numOfChildren = childrenHeights == null ? 0 : childrenHeights.size();
// out.writeInt(numOfChildren);
// if (0 < numOfChildren) {
// for (int i = 0; i < numOfChildren; i++) {
// out.writeInt(childrenHeights.keyAt(i));
// out.writeInt(childrenHeights.valueAt(i));
// }
// }
// }
//
// public static final Parcelable.Creator<SavedState> CREATOR
// = new Parcelable.Creator<SavedState>() {
// @Override
// public SavedState createFromParcel(Parcel in) {
// return new SavedState(in);
// }
//
// @Override
// public SavedState[] newArray(int size) {
// return new SavedState[size];
// }
// };
// }
}