下面列出了android.widget.ListView#getHeight ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public boolean canTargetScrollVertically(int direction) {
ListView target = this.mTarget;
int itemCount = target.getCount();
if (itemCount == 0) {
return false;
}
int childCount = target.getChildCount();
int firstPosition = target.getFirstVisiblePosition();
int lastPosition = firstPosition + childCount;
if (direction > 0) {
if (lastPosition >= itemCount && target.getChildAt(childCount - 1).getBottom() <= target.getHeight()) {
return false;
}
} else if (direction >= 0) {
return false;
} else {
if (firstPosition <= 0 && target.getChildAt(0).getTop() >= 0) {
return false;
}
}
return true;
}
/**
* 判断 ListView 是否已经滚动到底部
*
* @param listView 需要被判断的 ListView
* @return
*/
public static boolean isListViewAlreadyAtBottom(ListView listView) {
if (listView.getAdapter() == null || listView.getHeight() == 0) {
return false;
}
if (listView.getLastVisiblePosition() == listView.getAdapter().getCount() - 1) {
View lastItemView = listView.getChildAt(listView.getChildCount() - 1);
if (lastItemView != null && lastItemView.getBottom() == listView.getHeight()) {
return true;
}
}
return false;
}
/**
* 判断 ListView 是否已经滚动到底部
*
* @param listView 需要被判断的 ListView
* @return
*/
public static boolean isListViewAlreadyAtBottom(ListView listView) {
if (listView.getAdapter() == null || listView.getHeight() == 0) {
return false;
}
if (listView.getLastVisiblePosition() == listView.getAdapter().getCount() - 1) {
View lastItemView = listView.getChildAt(listView.getChildCount() - 1);
if (lastItemView != null && lastItemView.getBottom() == listView.getHeight()) {
return true;
}
}
return false;
}
private boolean hasHitBottom() {
if (mMainView instanceof ScrollView) {
ScrollView scrollView = (ScrollView) mMainView;
View view = scrollView.getChildAt(scrollView.getChildCount() - 1);
int diff = (view.getBottom() - (scrollView.getHeight() + scrollView.getScrollY()));// Calculate the scrolldiff
return diff == 0;
} else if (mMainView instanceof ListView) {
ListView listView = (ListView) mMainView;
if (listView.getAdapter() != null) {
if (listView.getAdapter().getCount() > 0) {
return listView.getLastVisiblePosition() == listView.getAdapter().getCount() - 1 &&
listView.getChildAt(listView.getChildCount() - 1).getBottom() <= listView.getHeight();
}
}
} else if (mMainView instanceof RecyclerView) {
RecyclerView recyclerView = (RecyclerView) mMainView;
if (recyclerView.getAdapter() != null && recyclerView.getLayoutManager() != null) {
RecyclerView.Adapter adapter = recyclerView.getAdapter();
if (adapter.getItemCount() > 0) {
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if (layoutManager instanceof LinearLayoutManager) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
return linearLayoutManager.findLastCompletelyVisibleItemPosition() == adapter.getItemCount() - 1;
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;
int[] checks = staggeredGridLayoutManager.findLastCompletelyVisibleItemPositions(null);
for (int check : checks) {
if (check == adapter.getItemCount() - 1)
return true;
}
}
}
}
}
return false;
}
boolean handlePostForDoubleClick(final View view) {
final PostViewHolder holder = ListViewUtils.getViewHolder(view, PostViewHolder.class);
if (holder != null) {
if (holder.comment.getVisibility() != View.VISIBLE || holder.comment.isSelectionEnabled()) {
return false;
}
long t = System.currentTimeMillis();
long timeout = holder.comment.getPreferredDoubleTapTimeout();
if (t - holder.lastCommentClick > timeout) {
holder.lastCommentClick = t;
} else {
final ListView listView = (ListView) view.getParent();
final int position = listView.getPositionForView(view);
holder.comment.startSelection();
int padding = holder.comment.getSelectionPadding();
if (padding > 0) {
final int listHeight = listView.getHeight() - listView.getPaddingTop() -
listView.getPaddingBottom();
listView.post(() -> {
int end = holder.comment.getSelectionEnd();
if (end >= 0) {
Layout layout = holder.comment.getLayout();
int line = layout.getLineForOffset(end);
int count = layout.getLineCount();
if (count - line <= 4) {
listView.setSelectionFromTop(position, listHeight - view.getHeight());
}
}
});
}
}
return true;
} else {
return false;
}
}
public void apply(final ListView listView) {
if (listView.getHeight() == 0) {
listView.post(() -> listView.setSelectionFromTop(position, y));
} else {
listView.setSelectionFromTop(position, y);
}
}
@Override
public boolean canTargetScrollVertically(int direction) {
final ListView target = mTarget;
final int itemCount = target.getCount();
if (itemCount == 0) {
return false;
}
final int childCount = target.getChildCount();
final int firstPosition = target.getFirstVisiblePosition();
final int lastPosition = firstPosition + childCount;
if (direction > 0) {
// Are we already showing the entire last item?
if (lastPosition >= itemCount) {
final View lastView = target.getChildAt(childCount - 1);
if (lastView.getBottom() <= target.getHeight()) {
return false;
}
}
} else if (direction < 0) {
// Are we already showing the entire first item?
if (firstPosition <= 0) {
final View firstView = target.getChildAt(0);
if (firstView.getTop() >= 0) {
return false;
}
}
} else {
// The behavior for direction 0 is undefined and we can return
// whatever we want.
return false;
}
return true;
}
@Override
public boolean canTargetScrollVertically(int direction) {
final ListView target = mTarget;
final int itemCount = target.getCount();
final int childCount = target.getChildCount();
final int firstPosition = target.getFirstVisiblePosition();
final int lastPosition = firstPosition + childCount;
if (direction > 0) {
// Are we already showing the entire last item?
if (lastPosition >= itemCount) {
final View lastView = target.getChildAt(childCount - 1);
if (lastView.getBottom() <= target.getHeight()) {
return false;
}
}
} else if (direction < 0) {
// Are we already showing the entire first item?
if (firstPosition <= 0) {
final View firstView = target.getChildAt(0);
if (firstView.getTop() >= 0) {
return false;
}
}
} else {
// The behavior for direction 0 is undefined and we can return
// whatever we want.
return false;
}
return true;
}
@Override
public boolean canTargetScrollVertically(int direction) {
final ListView target = mTarget;
final int itemCount = target.getCount();
final int childCount = target.getChildCount();
final int firstPosition = target.getFirstVisiblePosition();
final int lastPosition = firstPosition + childCount;
if (direction > 0) {
// Are we already showing the entire last item?
if (lastPosition >= itemCount) {
final View lastView = target.getChildAt(childCount - 1);
if (lastView.getBottom() <= target.getHeight()) {
return false;
}
}
} else if (direction < 0) {
// Are we already showing the entire first item?
if (firstPosition <= 0) {
final View firstView = target.getChildAt(0);
if (firstView.getTop() >= 0) {
return false;
}
}
} else {
// The behavior for direction 0 is undefined and we can return
// whatever we want.
return false;
}
return true;
}
@Override
public boolean canTargetScrollVertically(int direction) {
final ListView target = mTarget;
final int itemCount = target.getCount();
final int childCount = target.getChildCount();
final int firstPosition = target.getFirstVisiblePosition();
final int lastPosition = firstPosition + childCount;
if (direction > 0) {
// Are we already showing the entire last item?
if (lastPosition >= itemCount) {
final View lastView = target.getChildAt(childCount - 1);
if (lastView.getBottom() <= target.getHeight()) {
return false;
}
}
} else if (direction < 0) {
// Are we already showing the entire first item?
if (firstPosition <= 0) {
final View firstView = target.getChildAt(0);
if (firstView.getTop() >= 0) {
return false;
}
}
} else {
// The behavior for direction 0 is undefined and we can return
// whatever we want.
return false;
}
return true;
}
/**
* Gets all the touch events and updates dragging related logic. Note that if this app menu
* is initiated by software UI control, then the control should set onTouchListener and forward
* all the events to this method because the initial UI control that processed ACTION_DOWN will
* continue to get all the subsequent events.
*
* @param event Touch event to be processed.
* @param button Button that received the touch event.
* @return Whether the event is handled.
*/
boolean handleDragging(MotionEvent event, View button) {
if (!mAppMenu.isShowing() || !mDragScrolling.isRunning()) return false;
// We will only use the screen space coordinate (rawX, rawY) to reduce confusion.
// This code works across many different controls, so using local coordinates will be
// a disaster.
final float rawX = event.getRawX();
final float rawY = event.getRawY();
final int roundedRawX = Math.round(rawX);
final int roundedRawY = Math.round(rawY);
final int eventActionMasked = event.getActionMasked();
final long timeSinceDown = event.getEventTime() - event.getDownTime();
final ListView listView = mAppMenu.getPopup().getListView();
mLastTouchX = rawX;
mLastTouchY = rawY;
mMenuButtonScreenCenterY = getScreenVisibleRect(button).centerY();
if (eventActionMasked == MotionEvent.ACTION_CANCEL) {
mAppMenu.dismiss();
return true;
} else if (eventActionMasked == MotionEvent.ACTION_UP) {
nativeRecordAppMenuTouchDuration(timeSinceDown);
}
mIsSingleTapCanceled |= timeSinceDown > mTapTimeout;
mIsSingleTapCanceled |= !pointInView(button, event.getX(), event.getY(), mScaledTouchSlop);
if (!mIsSingleTapCanceled && eventActionMasked == MotionEvent.ACTION_UP) {
RecordUserAction.record("MobileUsingMenuBySwButtonTap");
finishDragging();
}
// After this line, drag scrolling is happening.
if (!mDragScrolling.isRunning()) return false;
boolean didPerformClick = false;
int itemAction = ITEM_ACTION_CLEAR_HIGHLIGHT_ALL;
switch (eventActionMasked) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
itemAction = ITEM_ACTION_HIGHLIGHT;
break;
case MotionEvent.ACTION_UP:
itemAction = ITEM_ACTION_PERFORM;
break;
default:
break;
}
didPerformClick = menuItemAction(roundedRawX, roundedRawY, itemAction);
if (eventActionMasked == MotionEvent.ACTION_UP && !didPerformClick) {
RecordUserAction.record("MobileUsingMenuBySwButtonDragging");
mAppMenu.dismiss();
} else if (eventActionMasked == MotionEvent.ACTION_MOVE) {
// Auto scrolling on the top or the bottom of the listView.
if (listView.getHeight() > 0) {
float autoScrollAreaRatio = Math.min(AUTO_SCROLL_AREA_MAX_RATIO,
mItemRowHeight * 1.2f / listView.getHeight());
float normalizedY =
(rawY - getScreenVisibleRect(listView).top) / listView.getHeight();
if (normalizedY < autoScrollAreaRatio) {
// Top
mDragScrollingVelocity = (normalizedY / autoScrollAreaRatio - 1.0f)
* mAutoScrollFullVelocity;
} else if (normalizedY > 1.0f - autoScrollAreaRatio) {
// Bottom
mDragScrollingVelocity = ((normalizedY - 1.0f) / autoScrollAreaRatio + 1.0f)
* mAutoScrollFullVelocity;
} else {
// Middle or not scrollable.
mDragScrollingVelocity = 0.0f;
}
}
}
return true;
}
/**
* Gets all the touch events and updates dragging related logic. Note that if this app menu
* is initiated by software UI control, then the control should set onTouchListener and forward
* all the events to this method because the initial UI control that processed ACTION_DOWN will
* continue to get all the subsequent events.
*
* @param event Touch event to be processed.
* @param button Button that received the touch event.
* @return Whether the event is handled.
*/
boolean handleDragging(MotionEvent event, View button) {
if (!mAppMenu.isShowing() || !mDragScrolling.isRunning()) return false;
// We will only use the screen space coordinate (rawX, rawY) to reduce confusion.
// This code works across many different controls, so using local coordinates will be
// a disaster.
final float rawX = event.getRawX();
final float rawY = event.getRawY();
final int roundedRawX = Math.round(rawX);
final int roundedRawY = Math.round(rawY);
final int eventActionMasked = event.getActionMasked();
final long timeSinceDown = event.getEventTime() - event.getDownTime();
final ListView listView = mAppMenu.getPopup().getListView();
mLastTouchX = rawX;
mLastTouchY = rawY;
mMenuButtonScreenCenterY = getScreenVisibleRect(button).centerY();
if (eventActionMasked == MotionEvent.ACTION_CANCEL) {
mAppMenu.dismiss();
return true;
} else if (eventActionMasked == MotionEvent.ACTION_UP) {
nativeRecordAppMenuTouchDuration(timeSinceDown);
}
mIsSingleTapCanceled |= timeSinceDown > mTapTimeout;
mIsSingleTapCanceled |= !pointInView(button, event.getX(), event.getY(), mScaledTouchSlop);
if (!mIsSingleTapCanceled && eventActionMasked == MotionEvent.ACTION_UP) {
RecordUserAction.record("MobileUsingMenuBySwButtonTap");
finishDragging();
}
// After this line, drag scrolling is happening.
if (!mDragScrolling.isRunning()) return false;
boolean didPerformClick = false;
int itemAction = ITEM_ACTION_CLEAR_HIGHLIGHT_ALL;
switch (eventActionMasked) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
itemAction = ITEM_ACTION_HIGHLIGHT;
break;
case MotionEvent.ACTION_UP:
itemAction = ITEM_ACTION_PERFORM;
break;
default:
break;
}
didPerformClick = menuItemAction(roundedRawX, roundedRawY, itemAction);
if (eventActionMasked == MotionEvent.ACTION_UP && !didPerformClick) {
RecordUserAction.record("MobileUsingMenuBySwButtonDragging");
mAppMenu.dismiss();
} else if (eventActionMasked == MotionEvent.ACTION_MOVE) {
// Auto scrolling on the top or the bottom of the listView.
if (listView.getHeight() > 0) {
float autoScrollAreaRatio = Math.min(AUTO_SCROLL_AREA_MAX_RATIO,
mItemRowHeight * 1.2f / listView.getHeight());
float normalizedY =
(rawY - getScreenVisibleRect(listView).top) / listView.getHeight();
if (normalizedY < autoScrollAreaRatio) {
// Top
mDragScrollingVelocity = (normalizedY / autoScrollAreaRatio - 1.0f)
* mAutoScrollFullVelocity;
} else if (normalizedY > 1.0f - autoScrollAreaRatio) {
// Bottom
mDragScrollingVelocity = ((normalizedY - 1.0f) / autoScrollAreaRatio + 1.0f)
* mAutoScrollFullVelocity;
} else {
// Middle or not scrollable.
mDragScrollingVelocity = 0.0f;
}
}
}
return true;
}
/**
* Gets all the touch events and updates dragging related logic. Note that if this app menu
* is initiated by software UI control, then the control should set onTouchListener and forward
* all the events to this method because the initial UI control that processed ACTION_DOWN will
* continue to get all the subsequent events.
*
* @param event Touch event to be processed.
* @param button Button that received the touch event.
* @return Whether the event is handled.
*/
boolean handleDragging(MotionEvent event, View button) {
if (!mAppMenu.isShowing() || !mDragScrolling.isRunning()) return false;
// We will only use the screen space coordinate (rawX, rawY) to reduce confusion.
// This code works across many different controls, so using local coordinates will be
// a disaster.
final float rawX = event.getRawX();
final float rawY = event.getRawY();
final int roundedRawX = Math.round(rawX);
final int roundedRawY = Math.round(rawY);
final int eventActionMasked = event.getActionMasked();
final long timeSinceDown = event.getEventTime() - event.getDownTime();
final ListView listView = mAppMenu.getPopup().getListView();
mLastTouchX = rawX;
mLastTouchY = rawY;
mMenuButtonScreenCenterY = getScreenVisibleRect(button).centerY();
if (eventActionMasked == MotionEvent.ACTION_CANCEL) {
mAppMenu.dismiss();
return true;
} else if (eventActionMasked == MotionEvent.ACTION_UP) {
nativeRecordAppMenuTouchDuration(timeSinceDown);
}
mIsSingleTapCanceled |= timeSinceDown > mTapTimeout;
mIsSingleTapCanceled |= !pointInView(button, event.getX(), event.getY(), mScaledTouchSlop);
if (!mIsSingleTapCanceled && eventActionMasked == MotionEvent.ACTION_UP) {
RecordUserAction.record("MobileUsingMenuBySwButtonTap");
finishDragging();
}
// After this line, drag scrolling is happening.
if (!mDragScrolling.isRunning()) return false;
boolean didPerformClick = false;
int itemAction = ITEM_ACTION_CLEAR_HIGHLIGHT_ALL;
switch (eventActionMasked) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
itemAction = ITEM_ACTION_HIGHLIGHT;
break;
case MotionEvent.ACTION_UP:
itemAction = ITEM_ACTION_PERFORM;
break;
default:
break;
}
didPerformClick = menuItemAction(roundedRawX, roundedRawY, itemAction);
if (eventActionMasked == MotionEvent.ACTION_UP && !didPerformClick) {
RecordUserAction.record("MobileUsingMenuBySwButtonDragging");
mAppMenu.dismiss();
} else if (eventActionMasked == MotionEvent.ACTION_MOVE) {
// Auto scrolling on the top or the bottom of the listView.
if (listView.getHeight() > 0) {
float autoScrollAreaRatio = Math.min(AUTO_SCROLL_AREA_MAX_RATIO,
mItemRowHeight * 1.2f / listView.getHeight());
float normalizedY =
(rawY - getScreenVisibleRect(listView).top) / listView.getHeight();
if (normalizedY < autoScrollAreaRatio) {
// Top
mDragScrollingVelocity = (normalizedY / autoScrollAreaRatio - 1.0f)
* mAutoScrollFullVelocity;
} else if (normalizedY > 1.0f - autoScrollAreaRatio) {
// Bottom
mDragScrollingVelocity = ((normalizedY - 1.0f) / autoScrollAreaRatio + 1.0f)
* mAutoScrollFullVelocity;
} else {
// Middle or not scrollable.
mDragScrollingVelocity = 0.0f;
}
}
}
return true;
}