首页 > 系统 > Android > 正文

android自定义ListView实现底部View自动隐藏和消失的功能

2019-12-12 03:17:21
字体:
来源:转载
供稿:网友

有这样一个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自动隐藏和消失的功能。 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表