在有些listview上面和ScrollView上,当滑动到底部的时候,在右下角会出现一个回到顶部的按钮,提供更好的用户体验。
效果图如下:
先说布局,可以用帧布局Framelayout,也可以用相对布局relativelayout.看下listview的布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/white" > <ListView android:id="@+id/my_listView" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" /> <Button android:id="@+id/top_btn" android:layout_width="50dp" android:layout_height="50dp" android:visibility="gone" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_marginBottom="6dp" android:layout_marginRight="6dp" android:background="@drawable/top_btn_bg" android:gravity="center" android:text="顶" /> </RelativeLayout>
/** * 主界面 * * @author zihao * @details 因为有些手机是有虚拟按键的(在计算屏幕分辨率的时候,有些可以去除掉虚拟区域的区域->如三星,有些不行->如MX3),为了计算的准确性, * 各位可以设置Activity为Theme * .NoTitleBar.Fullscreen填满屏幕(解决类似MX3这种在计算过程中把虚拟键盘算入屏幕高度的)。 */ public class ListActivity extends Activity implements OnClickListener { private ListView listView;// List数据列表 private Button toTopBtn;// 返回顶部的按钮 private MyAdapter adapter; private boolean scrollFlag = false;// 标记是否滑动 private int lastVisibleItemPosition = 0;// 标记上次滑动位置 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list); initView(); } /** * 初始化视图 */ private void initView() { listView = (ListView) findViewById(R.id.my_listView); toTopBtn = (Button) findViewById(R.id.top_btn); adapter = new MyAdapter(this, getTitleDatas()); listView.setAdapter(adapter); toTopBtn.setOnClickListener(this); listView.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { // TODO Auto-generated method stub switch (scrollState) { // 当不滚动时 case OnScrollListener.SCROLL_STATE_IDLE:// 是当屏幕停止滚动时 scrollFlag = false; // 判断滚动到底部 if (listView.getLastVisiblePosition() == (listView .getCount() - 1)) { toTopBtn.setVisibility(View.VISIBLE); } // 判断滚动到顶部 if (listView.getFirstVisiblePosition() == 0) { toTopBtn.setVisibility(View.GONE); } break; case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:// 滚动时 scrollFlag = true; break; case OnScrollListener.SCROLL_STATE_FLING:// 是当用户由于之前划动屏幕并抬起手指,屏幕产生惯性滑动时 scrollFlag = false; break; } } /** * firstVisibleItem:当前能看见的第一个列表项ID(从0开始) * visibleItemCount:当前能看见的列表项个数(小半个也算) totalItemCount:列表项共数 */ @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { // 当开始滑动且ListView底部的Y轴点超出屏幕最大范围时,显示或隐藏顶部按钮 if (scrollFlag && ScreenUtil.getScreenViewBottomHeight(listView) >= ScreenUtil .getScreenHeight(ListActivity.this)) { if (firstVisibleItem > lastVisibleItemPosition) {// 上滑 toTopBtn.setVisibility(View.VISIBLE); } else if (firstVisibleItem < lastVisibleItemPosition) {// 下滑 toTopBtn.setVisibility(View.GONE); } else { return; } lastVisibleItemPosition = firstVisibleItem; } } }); } /** * 获取标题数据列表 * * @return */ private List<String> getTitleDatas() { List<String> titleArray = new ArrayList<String>(); for (int i = 0; i < 30; i++) { titleArray.add("这是第" + i + "个item"); } return titleArray; } /** * 滚动ListView到指定位置 * * @param pos */ private void setListViewPos(int pos) { if (android.os.Build.VERSION.SDK_INT >= 8) { listView.smoothScrollToPosition(pos); } else { listView.setSelection(pos); } } @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.top_btn:// 点击按钮返回到ListView的第一项 setListViewPos(0); break; } } }
有很多知识点:
上面的参考连接也都写在注释里面了。
public class ScrollViewActivity extends Activity implements OnClickListener { private ScrollView scrollView;// scrollView数据列表 private Button toTopBtn;// 返回顶部的按钮 private int scrollY = 0;// 标记上次滑动位置 private View contentView; private final String TAG="test"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_scroll); initView(); } /** * 初始化视图 */ private void initView() { scrollView = (ScrollView) findViewById(R.id.my_scrollView); if (contentView == null) { contentView = scrollView.getChildAt(0); } toTopBtn = (Button) findViewById(R.id.top_btn); toTopBtn.setOnClickListener(this); //http://blog.csdn.net/jiangwei0910410003/article/details/17024287 /******************** 监听ScrollView滑动停止 *****************************/ scrollView.setOnTouchListener(new OnTouchListener() { private int lastY = 0; private int touchEventId = -9983761; Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); View scroller = (View) msg.obj; if (msg.what == touchEventId) { if (lastY == scroller.getScrollY()) { handleStop(scroller); } else { handler.sendMessageDelayed(handler.obtainMessage( touchEventId, scroller), 5); lastY = scroller.getScrollY(); } } } }; public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { handler.sendMessageDelayed( handler.obtainMessage(touchEventId, v), 5); } return false; } /** * ScrollView 停止 * * @param view */ private void handleStop(Object view) { Log.i(TAG,"handleStop"); ScrollView scroller = (ScrollView) view; scrollY = scroller.getScrollY(); doOnBorderListener(); } }); /***********************************************************/ } /** * ScrollView 的顶部,底部判断: * http://www.trinea.cn/android/on-bottom-load-more-scrollview-impl/ * * 其中getChildAt表示得到ScrollView的child View, 因为ScrollView只允许一个child * view,所以contentView.getMeasuredHeight()表示得到子View的高度, * getScrollY()表示得到y轴的滚动距离,getHeight()为scrollView的高度。 * 当getScrollY()达到最大时加上scrollView的高度就的就等于它内容的高度了啊~ * * @param pos */ private void doOnBorderListener() { Log.i(TAG,ScreenUtil.getScreenViewBottomHeight(scrollView) + " " + scrollView.getScrollY()+" "+ ScreenUtil .getScreenHeight(ScrollViewActivity.this)); // 底部判断 if (contentView != null && contentView.getMeasuredHeight() <= scrollView.getScrollY() + scrollView.getHeight()) { toTopBtn.setVisibility(View.VISIBLE); Log.i(TAG,"bottom"); } // 顶部判断 else if (scrollView.getScrollY() == 0) { Log.i(TAG,"top"); } else if (scrollView.getScrollY() > 30) { toTopBtn.setVisibility(View.VISIBLE); Log.i(TAG,"test"); } } /** * 下面我们看一下这个函数: scrollView.fullScroll(ScrollView.FOCUS_DOWN);滚动到底部 * scrollView.fullScroll(ScrollView.FOCUS_UP);滚动到顶部 * * * 需要注意的是,该方法不能直接被调用 因为Android很多函数都是基于消息队列来同步,所以需要一部操作, * addView完之后,不等于马上就会显示,而是在队列中等待处理,虽然很快, 但是如果立即调用fullScroll, * view可能还没有显示出来,所以会失败 应该通过handler在新线程中更新 * * http://blog.csdn.net/t12x3456/article/details/12799825 * http://www.tuicool.com/articles/zayIjq */ @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.top_btn : scrollView.post(new Runnable() { @Override public void run() { scrollView.fullScroll(ScrollView.FOCUS_UP); } }); toTopBtn.setVisibility(View.GONE); break; } } }
很多细节都注释在代码里面了,参考链接也已经加上。大家下载下代码执行一下看看。
代码http://download.csdn.net/detail/jjdhshdahhdd/9059757版权声明:本文为博主原创文章,欢迎转载,请表明出处。
Android listview ,ScrollView 回到顶部的按钮
原文地址:http://blog.csdn.net/jjdhshdahhdd/article/details/48065229