android自定义ListView实现底部View自动隐藏和消失的功能
程序员文章站
2022-10-14 14:35:29
有这样一个listview,要求在屏幕底部有一个筛选排序的浮动框:
1、手指下拉隐藏,上滑显示 ;
2、如果没做任何操作,2s之后,要自动显示;
3、滑动到最底部,始...
有这样一个listview,要求在屏幕底部有一个筛选排序的浮动框:
1、手指下拉隐藏,上滑显示 ;
2、如果没做任何操作,2s之后,要自动显示;
3、滑动到最底部,始终显示。
首先看其效果图:
实现上述效果,其实现原理如下:
1、在屏幕顶部固定一个bottomview,xml布局最好使用relativelayout(底部的bottomview并不是 listview的footview,这个是和footview独立的,想想为什么?)
2、然后自定义listview控件,监听ontouchevent事件,主要是监听手指下滑和上滑事件,同时实现onscrolllistener,监听是否滑动到最底部和最顶部
3、 listview监听事件中,控制bottomview的显示和隐藏,所以listview提供一个接口,设置底部bootomview的内容,然后获之后,就可以对bottomview进行控制,同时加上动画效果。
接下来看是如何的具体实现这种效果:
1。底部bottomview的内容如下,这个xml文件的内容是自定义的,根据各项目的内容需求来定义的,我例子中bottom_view.xml:
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/button_layout" android:layout_width="fill_parent" android:layout_height="50dp" android:background="#cbcbcb" android:gravity="center_vertical" android:orientation="horizontal" > <button android:layout_height="40dp" android:layout_width="wrap_content" android:layout_weight="1" android:text="价格" /> <button android:layout_height="40dp" android:layout_width="wrap_content" android:layout_weight="1" android:text="好评" /> <button android:layout_height="40dp" android:layout_width="wrap_content" android:layout_weight="1" android:text="筛选" /> </linearlayout>
2、main.xml如下
<?xml version="1.0" encoding="utf-8"?> <relativelayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <com.example.bottomfloatlistview.bottomfloatlistview android:id="@+id/listview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:fadingedge="none" /> <include android:id="@+id/bottombar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignparentbottom="true" layout="@layout/bottom_view" > </include> </relativelayout>
3、自定义listview控件bottomfloatlistview
package com.example.bottomfloatlistview; import android.content.context; import android.os.handler; import android.util.attributeset; import android.util.log; import android.view.motionevent; import android.view.view; import android.view.viewgroup; import android.view.animation.animation; import android.view.animation.overshootinterpolator; import android.view.animation.translateanimation; import android.widget.*; import android.widget.abslistview.onscrolllistener; /** * 底部view自动隐藏和消失listview(其他listview可以继承该类,如ctripbottomrefreshlistview类等) **/ public class bottomfloatlistview extends listview implements onscrolllistener { public view mbottombar; private int mcurrentscrollstate; private boolean bismoved = false; private boolean bisdown = false; private int mdeltay; private float mmotiony; private int oldfirstvisibleitem = 0; private handler mhandler = new handler(); private static final string tag = "bottomfloatlistview"; public bottomfloatlistview(context context) { this(context, null); super.setonscrolllistener(this); } public bottomfloatlistview(context context, attributeset attrs) { this(context, attrs, 0); super.setonscrolllistener(this); } public bottomfloatlistview(context context, attributeset attrs, int defstyle) { super(context, attrs, defstyle); super.setonscrolllistener(this); } @override public void setadapter(listadapter adapter) { super.setadapter(adapter); } @override public void onscroll(abslistview view, int firstvisibleitem, int visibleitemcount, int totalitemcount) { showbottomviewonbottom(visibleitemcount, totalitemcount, firstvisibleitem); } @override public void onscrollstatechanged(abslistview view, int scrollstate) { hidebottomviewonscrollstatechanged(view, scrollstate); } @override public boolean ontouchevent(motionevent ev) { float y = ev.gety(); float x = ev.getx(); log.d("floatlistview", "ontouchevent" + "" + x + "" + y); int action = ev.getaction() & motionevent.action_mask; switch (action) { case motionevent.action_down: action_down(y); break; case motionevent.action_move: mdeltay = (int) (y - mmotiony); bismoved = true; //移动的时候,要移除掉显示bottomview的消息 mhandler.removecallbacks(showbottombarrunnable); //补齐action_down事件,因为有的时候,action_down 事件没有执行 action_down(y); break; case motionevent.action_up: bismoved = false; bisdown = false; if (!bismoved && !bisdown) { // 如果屏幕上什么没做,则过2s之后要显示bottomview mhandler.postdelayed(showbottombarrunnable, 2000); } if (mdeltay < 0) { //下滑影藏 hidebottombar(); } else { //上滑显示 showbottombar(); } bismoved = false; break; } return super.ontouchevent(ev); } private void action_down(float y){ mmotiony = y; bisdown = true; log.d(tag, "action down execed"); mhandler.removecallbacks(showbottombarrunnable); } /** * 滑动到顶部时,要隐藏bottomview * @param view * @param scrollstate */ private void hidebottomviewonscrollstatechanged(abslistview view, int scrollstate) { mcurrentscrollstate = scrollstate; if(view!=null){ if (view.getfirstvisibleposition() == 0 && scrollstate == scroll_state_idle) { hidebottombar(); log.d(tag, "hide bottom view"); } } } /** * 显示底部浮动栏 */ public void showbottombar() { if (mbottombar != null && mbottombar.getvisibility() == view.gone) { mbottombar.setvisibility(view.invisible); animation translateanimation = new translateanimation(mbottombar.getleft(), mbottombar.getleft(),30, 0); translateanimation.setduration(300); translateanimation.setinterpolator(new overshootinterpolator(0.6f)); mbottombar.startanimation(translateanimation); translateanimation.setanimationlistener(new animation.animationlistener() { @override public void onanimationstart(animation animation) { } @override public void onanimationrepeat(animation animation) { } @override public void onanimationend(animation animation) { mbottombar.setvisibility(view.visible); } }); } } /** * 隐藏浮动底部栏 */ private void hidebottombar() { if (mbottombar != null && mbottombar.getvisibility() == view.visible) { animation translateanimation = new translateanimation(mbottombar.getleft(), mbottombar.getleft(), 0, 30); translateanimation.setduration(300); translateanimation.setinterpolator(new overshootinterpolator(0.6f)); mbottombar.startanimation(translateanimation); translateanimation.setanimationlistener(new animation.animationlistener() { @override public void onanimationstart(animation animation) { } @override public void onanimationrepeat(animation animation) { } @override public void onanimationend(animation animation) { mbottombar.setvisibility(view.gone); } }); } } /** * 滑动到底部时直接显示bottomview * @param visibleitemcount * @param totalitemcount * @param firstvisibleitem */ private void showbottomviewonbottom(int visibleitemcount, int totalitemcount, int firstvisibleitem) { log.d(tag, "visible bottem item count:" + "firstvisibleitem:" + firstvisibleitem + "oldfirstvisibleitem:" + oldfirstvisibleitem + mbottombar); if(getlastvisibleposition() == totalitemcount -1 && mcurrentscrollstate != scroll_state_idle){ showbottombar(); } } private runnable showbottombarrunnable = new runnable() { @override public void run() { showbottombar(); } }; /** * 将需要隐藏显示的view传入 * * @param bottombar */ public void setbottombar(viewgroup bottombar) { this.mbottombar = bottombar; } }
4、主界面测试的activity,mainactivity代码如下
public class mainactivity extends activity { private bottomfloatlistview mbottomfloatlistview; @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); mbottomfloatlistview = (bottomfloatlistview)findviewbyid(r.id.listview) ; mbottomfloatlistview.setadapter(new arrayadapter<string>(this, android.r.layout.simple_expandable_list_item_1,getdata())); viewgroup bottomview = (viewgroup)findviewbyid(r.id.bottombar) ; mbottomfloatlistview.setbottombar(bottomview); } private list<string> getdata(){ list<string> data = new arraylist<string>(); for(int i = 0; i <100; i++) { data.add("测试数据" + i); } return data; } }
viewgroup bottomview = (viewgroup)findviewbyid(r.id.bottombar) ; mbottomfloatlistview.setbottombar(bottomview);
将底部的bottomview传入到listview中,就可以让listview具有底部view自动隐藏和消失的功能。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
下一篇: rsync 故障排查整理