CSDN 地址:http://blog.csdn.net/xiangyong_1521/article/details/50957563
scroollview、listview、gridview是我们常用的滚动类型布局,应工作中的一个需求,需要监听这些布局的页面停留状态,以配合更新页面UI,然后通过按钮点击以控制这些页面的滚动;
private class ScrollListener implements OnScrollListener{
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
@Override
public void onScroll(AbsListView view, //报告滚动状态的视图
int firstVisibleItem,//第一个可见item的索引
int visibleItemCount,//可见item的数量
int totalItemCount)//项目列表中的适配器的数量
{
if (firstVisibleItem==0) {
View view2 = gridView.getChildAt(firstVisibleItem);
if (view2!=null) {
Log.i("TAG","view2.getY()"+view2.getY()); //可获取到任何状态下的第一个可见item索引的getY()值
if (view2.getY() == 8) {//在顶部 更新UI
button_up.setBackgroundResource(R.drawable.upb);//向上的键为灰色
button_up.setClickable(false);//且不能按
} else {
button_up.setBackgroundResource(R.drawable.upg);//向上的键为白色
button_up.setClickable(true);//能按
}
}
}else{
button_up.setBackgroundResource(R.drawable.upg);//向上的键为白色
button_up.setClickable(true);//能按
}if ((firstVisibleItem+visibleItemCount)==totalItemCount) {
View view3 = gridView.getChildAt(totalItemCount-1-firstVisibleItem);//scrollview所占的高度
if (view3!=null) {
Log.i("TAG","view3.getY()"+view3.getY());
if (view3.getY() == 246) {//在底部 更新UI
button_down.setBackgroundResource(R.drawable.downb); //向下的键为灰色
button_down.setClickable(false); //且不能按
} else {
button_down.setBackgroundResource(R.drawable.downg); //向下的键为白色
button_down.setClickable(true); //能按
}
}
}else{//在中部 更新UI
button_down.setBackgroundResource(R.drawable.downg); //向下的键为白色
button_down.setClickable(true); //能按
}
}
}
此方法调用OnScrollListener接口来实现Scroll页面的监听,在方法onScroll内,我们可以拿到几个重要的数值,在实际的使用中,可能打印这些数据,以配合功能的实现!
ListView().setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view,
int firstVisibleItem, //第一个可见item的索引
int visibleItemCount, //可见item的数量
int totalItemCount) //项目列表中的适配器的数量
{
if(firstVisibleItem==0){
Log.e("log", "滑到顶部");
}
if(visibleItemCount+firstVisibleItem==totalItemCount){
Log.e("log", "滑到底部");
}
}
});
listview的监听方法更简单明了,也是调用的setOnScrollListener监听,在onScroll方法内直接计算几个数值即可实现监听。
@Override
public void onScrollChanged(ObservableScrollView observableScrollView,
int x, int y, int oldx, int oldy) {
int scrollY=observableScrollView.getScrollY();//顶端以及滑出去的距离
int height=observableScrollView.getHeight();//界面的高度
int scrollViewMeasuredHeight=observableScrollView.getChildAt(0).getMeasuredHeight();//scrollview所占的高度
if(scrollY==0){//在顶端的时候
button_up.setBackgroundResource(R.drawable.upb);//向上的键为灰色
button_up.setClickable(false);//且不能按
}else if((scrollY+height)==scrollViewMeasuredHeight){//当在底部的时候
button_down.setBackgroundResource(R.drawable.downb); //向下的键为灰色
button_down.setClickable(false); //且不能按
}else {//当在中间的时候
button_down.setBackgroundResource(R.drawable.button_down);//向下为白色
button_down.setClickable(true); //可点击
button_up.setClickable(true);//可点击
button_up.setBackgroundResource(R.drawable.button_up); //向上的键为白色
}
}
button_down.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(true){
if(type==1){
includeView2.smoothScrollBy(1000, 470);
}else{
gridView.smoothScrollBy(300, 1000);
}else{
listView.smoothScrollBy(300, 1000);
}
}
}
});
button_up.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(true){
if(type==1){
includeView2.smoothScrollBy(1000, -470);
}else{
gridView.smoothScrollBy(-300, 1000);
}else{
listView.smoothScrollBy(-300, 1000);
}
}
}
});
通过smoothScrollBy,我们可以控制页面的滚动,我们看下在HorizontalScrollView类中的smoothScrollBy,smoothScrollTo的源码:
/**
* Like {@link View#scrollBy}, but scroll smoothly instead of immediately.
*
* @param dx the number of pixels to scroll by on the X axis
* @param dy the number of pixels to scroll by on the Y axis
*/
public final void smoothScrollBy(int dx, int dy) {
if (getChildCount() == 0) {
// Nothing to do.
return;
}
long duration = AnimationUtils.currentAnimationTimeMillis() - mLastScroll;
if (duration > ANIMATED_SCROLL_GAP) {
final int width = getWidth() - mPaddingRight - mPaddingLeft;
final int right = getChildAt(0).getWidth();
final int maxX = Math.max(0, right - width);
final int scrollX = mScrollX;
dx = Math.max(0, Math.min(scrollX + dx, maxX)) - scrollX;
mScroller.startScroll(scrollX, mScrollY, dx, 0);
postInvalidateOnAnimation();
} else {
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
}
scrollBy(dx, dy); //调用View的scrollBy(x.y)方法
}
mLastScroll = AnimationUtils.currentAnimationTimeMillis();
}
/**
* Like {@link #scrollTo}, but scroll smoothly instead of immediately.
*
* @param x the position where to scroll on the X axis
* @param y the position where to scroll on the Y axis
*/
public final void smoothScrollTo(int x, int y) {
smoothScrollBy(x - mScrollX, y - mScrollY);
}
smoothScrollBy(x,y)方法在判断滑动间隔的时间长短后判定是一蹴而就还是慢慢滑向终点,关键方法是调用View的srcoll(x,y)方法,或借助scroller,这里x,y也是相对改变的值。
这样,关于scroollview、listview、gridview是我们常用的滚动和smoothScrollBy的方法就讲完了,如果你有更好的方法或者有疑问的地方,随时欢迎交流!