Android进阶篇之ListView、GridView以及ScrollView实现按钮控制滚动
来源:互联网 发布:java se深入浅出 编辑:程序博客网 时间:2024/06/05 07:17
这次还是一样,因为项目需要,需要对滚动视图需要手动控制,也就是点击上下左右按钮,能让滚动控件触发对应的操作
在android中,滚动View最基本的有三种,分别是:ListView、GridView和ScrollView
先看效果图:1、ListView的效果图,右下角放置滚动控制按钮
2、GridView的效果图
3、ScrollView 的效果图就不上传了,因为都差不多。
是不是看完效果图觉得弱爆了,那就对了,因为现在的功能就是实现了上下滚动,如果对上面那两个按钮加上下拉加载和上拉刷新呢?甚至还可以控制当在最顶部时只显示“下”的Button,还可以做当整个滚动视图没有超过一屏时的监听
废话不多说,现在来上代码。
第一步:
编写布局文件-->>>>文件名为common_item_menu_scorll_btns.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/common_menu_scroll_up" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/common_menu_scroll_up_selector"/> <Button android:id="@+id/common_menu_scroll_down" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/common_menu_scroll_down_selector"/></LinearLayout>
第二步:
编写自定义视图,因为ListView和GridView都是继承AbsListView,所以可以把需要控制的类型由三个变成两个
/** * 如果需要加载更多的滚动视图就需要设置OnAddMoreDataListener * @author yejihuang */public class ScrollBtnView extends LinearLayout implements OnClickListener{private Context mContext ;private ScrollView scroll ;private AbsListView mAbsListView ;public int selectIndex ; private boolean isListBottom ;public boolean isListTop ;private int type ;private Hodler hodler ;private OnScrollBtnListener onScrollBtnListener ;private OnOpratorScrollBtnListener onOpratorScrollBtnListener ;/** * 如果不需要加载更多功能请使用ScrollBtnView(Context context, Object obj) * 需要请使用ScrollBtnView(Context context, Object obj, OnOpratorScrollBtnListener onOpratorScrollBtnListener) * @param context 上下文对象 * @param obj 需要被控制滚动的对象,在这里只写了三种,ScrollView,ListView,GridView */public ScrollBtnView(Context context, Object obj) {super(context);mContext = context ;initData() ;initView() ;getObject(obj) ;}/** * 如果不需要加载更多功能请使用ScrollBtnView(Context context, Object obj) * 需要请使用ScrollBtnView(Context context, Object obj, OnOpratorScrollBtnListener onOpratorScrollBtnListener) * @param context 上下文对象 * @param obj 需要被控制滚动的对象,在这里只写了三种,ScrollView,ListView,GridView */public ScrollBtnView(Context context, Object obj, OnOpratorScrollBtnListener onOpratorScrollBtnListener) {super(context);mContext = context ;initData() ;initView() ;getObject(obj) ;this.onOpratorScrollBtnListener = onOpratorScrollBtnListener ;}private void initView() {View view = LayoutInflater.from(mContext).inflate(R.layout.common_item_menu_scorll_btns, this, true) ;view.setVisibility(View.GONE) ;hodler = new Hodler() ;hodler.view = view ;hodler.upBtn = (Button) view.findViewById(R.id.common_menu_scroll_up) ;hodler.downBtn = (Button) view.findViewById(R.id.common_menu_scroll_down) ;hodler.upBtn.setOnClickListener(this) ;hodler.downBtn.setOnClickListener(this) ;if (isListTop)hodler.upBtn.setVisibility(View.GONE) ;}private void initData() {this.selectIndex = 0 ;isListTop = true ;}/** * 根据传入的对象判断是哪一种滚动,然后强制转换 * @param obj */private void getObject(Object obj) {if (obj instanceof ScrollView) {this.type = ScrollBtnConstant.TYPE_SCROLL ;this.scroll = (ScrollView) obj ;this.scroll.setOnTouchListener(new OnTouchListener() {private int lastY = 0;private int touchEventId = -9983761;Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);View scroller = (View) msg.obj;if (msg.what == touchEventId) {if (lastY == scroller.getScrollY()) {//停止了,此处你的操作业务refreshCtrlScrollBtn();} else {handler.sendMessageDelayed(handler.obtainMessage(touchEventId, scroller), 1);lastY = scroller.getScrollY();}}}};@Overridepublic boolean onTouch(View v, MotionEvent event) {int eventAction = event.getAction();int y = (int) event.getRawY();switch (eventAction) {case MotionEvent.ACTION_UP:handler.sendMessageDelayed(handler.obtainMessage(touchEventId, v), 5);break;default:break;}return false;}});hodler.view.setVisibility(View.VISIBLE) ;} else if (obj instanceof AbsListView) {this.type = ScrollBtnConstant.TYPE_LIST ;this.mAbsListView = (AbsListView) obj ;MainHandler.post2Main(new Runnable() {@Overridepublic void run() {mAbsListView.setOnScrollListener(new OnScrollListener() {@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) {if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {selectIndex = mAbsListView.getFirstVisiblePosition() ;refreshCtrlScrollBtn() ;}if(onScrollBtnListener != null){onScrollBtnListener.onScrollStateChanged(view, scrollState) ;}}@Overridepublic void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {if(totalItemCount <= visibleItemCount){hodler.view.setVisibility(View.GONE) ;} else {hodler.view.setVisibility(View.VISIBLE) ;}if(onScrollBtnListener != null){onScrollBtnListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);}}}) ;}}, 1500) ;}}public void setOnOpratorScrollBtnListener(OnOpratorScrollBtnListener onOpratorScrollBtnListener) {this.onOpratorScrollBtnListener = onOpratorScrollBtnListener;}/** * 拦截触摸事件,以免触摸到地图层 */@Overridepublic boolean onTouchEvent(MotionEvent arg0) {return true;}@Overridepublic void onClick(View v) {int direct ;if (v.getId() == R.id.common_menu_scroll_up)direct = ScrollBtnConstant.UP ;elsedirect = ScrollBtnConstant.DOWN ;//执行上下滚动事件switch (direct) {case ScrollBtnConstant.UP:switch (type) {case ScrollBtnConstant.TYPE_SCROLL:scroll.smoothScrollBy(0, ScrollBtnConstant.DEFAULT_DISTANCE_UP) ;break;case ScrollBtnConstant.TYPE_LIST:if (selectIndex > 0) {selectIndex = mAbsListView.getFirstVisiblePosition() ;selectIndex -- ;}mAbsListView.smoothScrollToPosition(selectIndex);break;}break;case ScrollBtnConstant.DOWN:switch (type) {case ScrollBtnConstant.TYPE_SCROLL:scroll.smoothScrollBy(0, ScrollBtnConstant.DEFAULT_DISTANCE_DOWN) ;break;case ScrollBtnConstant.TYPE_LIST:if (selectIndex < mAbsListView.getCount() - 1) {selectIndex = mAbsListView.getLastVisiblePosition() ;selectIndex ++ ;isListBottom = false ;} else {isListBottom = true ;}if (!isListBottom) { // 如果是滑动到了最底部,点击向下继续滚动mAbsListView.smoothScrollToPosition(selectIndex);} else { //如果已经到最底部,再点击向下,就刷新数据if (!NullUtils.isNull(onOpratorScrollBtnListener) && onOpratorScrollBtnListener.doLoadMore()) {selectIndex ++ ;//一定是放在刷新之后mAbsListView.smoothScrollToPosition(selectIndex);}}break;}break;default:break;}refreshCtrlScrollBtn();}public void refreshCtrlScrollBtn() {//执行up按钮隐藏和出现的逻辑switch (type) {case ScrollBtnConstant.TYPE_SCROLL:if (scroll.getScrollY() == 0) {isListTop = true ;hodler.upBtn.setVisibility(View.GONE) ;} else {isListTop = false ;hodler.upBtn.setVisibility(View.VISIBLE) ;}break;case ScrollBtnConstant.TYPE_LIST:int top = mAbsListView.getChildAt(0).getTop() ;int distance = mAbsListView.getChildAt(0).getHeight() / 2 ;if (selectIndex <= 0) {if (top > (-1) * distance) { //对滚动距离小于item高度的一半的时候,弹回顶部,当滚动距离大于一半切没有超出下一个item就自动滚动到下一个itemisListTop = true ;mAbsListView.setSelection(0) ;hodler.upBtn.setVisibility(View.GONE) ;} else {isListTop = false ;mAbsListView.setSelection(1) ;hodler.upBtn.setVisibility(View.VISIBLE) ;}} else {isListTop = false ;hodler.upBtn.setVisibility(View.VISIBLE) ;}break;}}/** * 添加一个加载更多刷新函数的接口 * @author yejihuang * */public interface OnOpratorScrollBtnListener {/** * 加载更多 * @return */public boolean doLoadMore () ;}/** * 这个接口是把对传入的滚动控件,所触发的滚动监听分发出去 * @author yejihuang * */public interface OnScrollBtnListener {public void onScrollStateChanged(AbsListView view, int scrollState) ;public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) ;}public void setOnScrollBtnListener(OnScrollBtnListener onScrollBtnListener) {this.onScrollBtnListener = onScrollBtnListener;}class Hodler {View view ;Button upBtn ;Button downBtn ;}class ScrollBtnConstant {/** * 默认点击一次滚动的距离 */public static final int DEFAULT_DISTANCE_DOWN = 200 ;public static final int DEFAULT_DISTANCE_UP = -200 ;public static final int DOWN = 1 ;public static final int UP = 2 ;public static final int TYPE_SCROLL = 1 ;public static final int TYPE_LIST = 2 ;}}
代码中NullUtils.isNull()只是一个判断对象是否是NULL的静态函数,如果使用直接换成Object != null就可以了
第三步:
滚动控制的按钮视图写好了,现在就是直接添加到自己想要的地方就可以,先看看在listview布局文件中怎么添加,加一个LinearLayout布局容器来装那个滚动控制视图,
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/LinearLayout01" android:layout_width="fill_parent" android:layout_height="fill_parent" > <ListView android:id="@+id/MyListView" android:divider="@drawable/sslist_driver" android:dividerHeight="1dip" android:layout_width="wrap_content" android:layout_height="wrap_content" > </ListView> <LinearLayout android:id="@+id/scroll_btns" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_alignParentRight="true" android:layout_alignParentBottom="true"> </LinearLayout></RelativeLayout>
然后在Java代码中动态添加
LinearLayout linear = (LinearLayout) findViewById(R.id.scroll_btns) ;linear.addView(new ScrollBtnView(this, list)) ;此处的list是指你想要控制的listview的对象
如果想控制GridView那就把list改成GridView 的实例对象就可以了,简单吧!
现在来说说当滚动到了最底部,继续点击向下就加载更多数据。
只要实现onOpratorScrollBtnListener监听器就可以了
可以从代码中看出有两种方式,多加一行setOnOpratorScrollBtnListener代码和实现带onOpratorScrollBtnListener的构造函数就可以了
有什么问题,欢迎小伙伴们参与讨论!
- Android进阶篇之ListView、GridView以及ScrollView实现按钮控制滚动
- android之ScrollView里嵌套ListView,gridview,scrollview
- ScrollView嵌套listview以及gridview
- Android实现 ScrollView + ListView无滚动条滚动
- Android实现 ScrollView + ListView无滚动条滚动
- Android实现 ScrollView + ListView无滚动条滚动
- Android实现 ScrollView + ListView无滚动条滚动
- Android实现 ScrollView + ListView无滚动条滚动
- ScrollView嵌套Gridview或者listview滚动问题
- android listview,GridView 和 ScrollView
- ScrollView嵌套ListView,GridView,ViewPager,以及这些控件自动滚动到底部问题的解决
- ScrollView嵌套ListView,GridView,ViewPager,以及这些控件自动滚动到底部问题的解决
- ScrollView嵌套ListView,GridView,ViewPager,以及这些控件自动滚动到底部问题的解决
- ScrollView嵌套ListView,GridView,ViewPager,以及这些控件自动滚动到底部问题的解决
- ScrollView嵌套ListView,GridView,ViewPager,以及这些控件自动滚动到底部问题的解决
- ScrollView嵌套ListView,GridView,ViewPager,以及这些控件自动滚动到底部问题的解决
- ScrollView嵌套ListView,GridView,ViewPager,以及这些控件自动滚动到底部问题的解决
- 【Android进阶】ScrollView内嵌套ListView时禁止ListView的滚动
- 关于mybatis的batch模式性能测试及结论
- Leetcode Oj Reverse Integer
- 2014年打字67月份开始,本博客账号被人非法盗用,发大量博文,本人在此慎重承诺
- shell命令find删除修改后带尾巴的重复的文件
- gcc的依赖安装顺序
- Android进阶篇之ListView、GridView以及ScrollView实现按钮控制滚动
- MessageBox函数在VC6与VS2010中的调用
- android notify() notifyAll()的区别
- Android联系人Contacts详解
- SRTP with SIP
- 获取view的高和宽
- POJ 2632 Crashing Robots(模拟)
- 数据结构---单链表
- 马云凭啥在达沃斯大出风头 ?