在有些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>
Listview 回到顶部的活动代码
是从网上找到的代码,作者为:zihao
- /**
- * 主界面
- *
- * @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;
- }
- }
- }
在上面的代码中,对listview 设置 setOnScrollListener 监听;当有一点滑动(也可以提供一个值)或者是到达底部的时候就出现回到顶部的按钮。
scrollview的代码
有很多知识点:
- scrollview的滑动停止监听。
- scrollview回到顶部,或者底部的方法。
- scrollview到达顶部或者底部的判断方法。
上面的参考连接也都写在注释里面了。
- 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.youkuaiyun.com/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.youkuaiyun.com/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;
- }
- }
- }