ListView,ScrollView,RecyclerView上下スライドリスニング
6591 ワード
プロジェクトではListViewまたはScrolViewまたはRecyclerViewのスクロールをリスニングする必要があります.以下、対応する実装について説明します.
一:Listview上下スライドリスニング
AbsListViewを実現する.OnScrollListenerインタフェースonScroll(AbsListView,int firstVisibleItem,int visibleItemCount,int totalItemCount)実装(firstItemと前回との差の比較を判断することにより)
以下、インタフェースパッケージ処理
ここでは、2つの状況処理に分けられます.
1,firstItem差分値を2回比較して判断する場合,この場合は比較的容易に考えられるが,もう1つのケース2がある.
2,スライド距離が小さい(またはitemViewの高さが大きい)場合はItemViewが1つであると判断して比較処理する必要がある
二:ScrollViewスクロール上下スクロールリスニング
ScrollViewはListViewのようなリスナーを提供していませんが、どのように実現しますか?答えは、ScrollView再onScrollChangedメソッドの判断を継承し、リスニングコールバックを提供することです.
具体的な実装:
すなわち、ScollViewを使用する場合、ObservableScrollViewを使用して置き換えるとよい.ここで注意しなければならないのは、onScrollChangedメソッドはScrollView独自の定義ではなく、SrollViewはFrameLayoutを継承する
FrameLayoutはView Groupを継承し、View Group、FrameLayoutではなくViewベースクラスに由来し、ソースコードは以下のように説明されています.
つまり、SrollBy()が呼び出された場合、またはScrollTo()が呼び出された場合、ScrollView内部が呼び出された場合、このメソッドを書き換えることで実現できるすべての方法
次のインプリメンテーションは、リスニングインプリメンテーションです.
三:RecyclerViewがスクロール方向の判断を実現
システムは対応するインタフェースを提供するため、比較的簡単である.OnScrollListener,スクロールdx,dyが与えられた
次のようになります.
なお、mScrollThresholdの大きさはここで4 dpに設定し、具体的な環境に応じて調整することができる.
転載先:https://www.cnblogs.com/happyxiaoyu02/p/6150740.html
一:Listview上下スライドリスニング
AbsListViewを実現する.OnScrollListenerインタフェースonScroll(AbsListView,int firstVisibleItem,int visibleItemCount,int totalItemCount)実装(firstItemと前回との差の比較を判断することにより)
以下、インタフェースパッケージ処理
abstract class AbsListViewScrollDetector implements AbsListView.OnScrollListener {
private int mLastScrollY;
private int mPreviousFirstVisibleItem;
private AbsListView mListView;
private int mScrollThreshold;
abstract void onScrollUp();
abstract void onScrollDown();
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if(totalItemCount == 0) return;
if (isSameRow(firstVisibleItem)) {
int newScrollY = getTopItemScrollY();
boolean isSignificantDelta = Math.abs(mLastScrollY - newScrollY) > mScrollThreshold;
if (isSignificantDelta) {
if (mLastScrollY > newScrollY) {
onScrollUp();
} else {
onScrollDown();
}
}
mLastScrollY = newScrollY;
} else {
if (firstVisibleItem > mPreviousFirstVisibleItem) {
onScrollUp();
} else {
onScrollDown();
}
mLastScrollY = getTopItemScrollY();
mPreviousFirstVisibleItem = firstVisibleItem;
}
}
public void setScrollThreshold(int scrollThreshold) {
mScrollThreshold = scrollThreshold;
}
public void setListView(AbsListView listView) {
mListView = listView;
}
private boolean isSameRow(int firstVisibleItem) {
return firstVisibleItem == mPreviousFirstVisibleItem;
}
private int getTopItemScrollY() {
if (mListView == null || mListView.getChildAt(0) == null) return 0;
View topChild = mListView.getChildAt(0);
return topChild.getTop();
}
}
ここでは、2つの状況処理に分けられます.
1,firstItem差分値を2回比較して判断する場合,この場合は比較的容易に考えられるが,もう1つのケース2がある.
2,スライド距離が小さい(またはitemViewの高さが大きい)場合はItemViewが1つであると判断して比較処理する必要がある
二:ScrollViewスクロール上下スクロールリスニング
ScrollViewはListViewのようなリスナーを提供していませんが、どのように実現しますか?答えは、ScrollView再onScrollChangedメソッドの判断を継承し、リスニングコールバックを提供することです.
具体的な実装:
public class ObservableScrollView extends ScrollView {
public interface OnScrollChangedListener {
void onScrollChanged(ScrollView who, int l, int t, int oldl, int oldt);
}
private OnScrollChangedListener mOnScrollChangedListener;
public ObservableScrollView(Context context) {
super(context);
}
public ObservableScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ObservableScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (mOnScrollChangedListener != null) {
mOnScrollChangedListener.onScrollChanged(this, l, t, oldl, oldt);
}
}
public void setOnScrollChangedListener(OnScrollChangedListener listener) {
mOnScrollChangedListener = listener;
}
}
すなわち、ScollViewを使用する場合、ObservableScrollViewを使用して置き換えるとよい.ここで注意しなければならないのは、onScrollChangedメソッドはScrollView独自の定義ではなく、SrollViewはFrameLayoutを継承する
FrameLayoutはView Groupを継承し、View Group、FrameLayoutではなくViewベースクラスに由来し、ソースコードは以下のように説明されています.
/**
* This is called in response to an internal scroll in this view (i.e., the
* view scrolled its own contents). This is typically as a result of
* {@link #scrollBy(int, int)} or {@link #scrollTo(int, int)} having been
* called.
*
* @param l Current horizontal scroll origin.
* @param t Current vertical scroll origin.
* @param oldl Previous horizontal scroll origin.
* @param oldt Previous vertical scroll origin.
*/
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
if (AccessibilityManager.getInstance(mContext).isEnabled()) {
postSendViewScrolledAccessibilityEventCallback();
}
mBackgroundSizeChanged = true;
final AttachInfo ai = mAttachInfo;
if (ai != null) {
ai.mViewScrollChanged = true;
}
if (mListenerInfo != null && mListenerInfo.mOnScrollChangeListener != null) {
mListenerInfo.mOnScrollChangeListener.onScrollChange(this, l, t, oldl, oldt);
}
}
つまり、SrollBy()が呼び出された場合、またはScrollTo()が呼び出された場合、ScrollView内部が呼び出された場合、このメソッドを書き換えることで実現できるすべての方法
次のインプリメンテーションは、リスニングインプリメンテーションです.
abstract class ScrollViewScrollDetector implements ObservableScrollView.OnScrollChangedListener {
private int mLastScrollY;
private int mScrollThreshold;
abstract void onScrollUp();
abstract void onScrollDown();
@Override
public void onScrollChanged(ScrollView who, int l, int t, int oldl, int oldt) {
boolean isSignificantDelta = Math.abs(t - mLastScrollY) > mScrollThreshold;
if (isSignificantDelta) {
if (t > mLastScrollY) {
onScrollUp();
} else {
onScrollDown();
}
}
mLastScrollY = t;
}
public void setScrollThreshold(int scrollThreshold) {
mScrollThreshold = scrollThreshold;
}
}
三:RecyclerViewがスクロール方向の判断を実現
システムは対応するインタフェースを提供するため、比較的簡単である.OnScrollListener,スクロールdx,dyが与えられた
次のようになります.
abstract class RecyclerViewScrollDetector extends RecyclerView.OnScrollListener {
private int mScrollThreshold;
abstract void onScrollUp();
abstract void onScrollDown();
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
boolean isSignificantDelta = Math.abs(dy) > mScrollThreshold;
if (isSignificantDelta) {
if (dy > 0) {
onScrollUp();
} else {
onScrollDown();
}
}
}
public void setScrollThreshold(int scrollThreshold) {
mScrollThreshold = scrollThreshold;
}
}
なお、mScrollThresholdの大きさはここで4 dpに設定し、具体的な環境に応じて調整することができる.
転載先:https://www.cnblogs.com/happyxiaoyu02/p/6150740.html