listview上拉隐藏标题与下拉显示标题
2019獨角獸企業重金招聘Python工程師標準>>>
這個功能非常普遍了,主要是用戶在下拉列表的時候,隱藏標題來擴大用戶瀏覽列表的范圍
本方法的設計思路是在列表上覆蓋標題欄,然后當列表滑到頂部的時候,在列表的頂部設置一個padding控件來占和標題一樣的高度,防止列表頂部被標題覆蓋,當列表往下滑動的時候,通過動畫隱藏標題,只要列表的第一個item不可視,就把padding控件給隱藏掉,這樣達到列表填充整個屏幕的效果
先看布局
<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:animateLayoutChanges="true"tools:context="com.example.showhidetitlelistview.MainActivity" ><Viewandroid:id="@+id/padding"android:layout_width="match_parent"android:layout_height="@dimen/title_height" /><ListViewandroid:id="@+id/listview"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_below="@+id/padding"android:background="#F4F1F1" ></ListView><LinearLayoutandroid:id="@+id/titleLayout"android:layout_width="match_parent"android:layout_height="@dimen/title_height"android:background="@android:color/white"android:orientation="horizontal" ><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:layout_weight="1"android:gravity="center"android:text="標題" /><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:layout_weight="1"android:gravity="center"android:text="標題" /><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:layout_weight="1"android:gravity="center"android:text="標題" /><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:layout_weight="1"android:gravity="center"android:text="標題" /></LinearLayout></RelativeLayout>listview在padding下方,而標題是在屏幕上方,覆蓋所有控件
值得注意的是在根布局中設置的動畫屬性
android:animateLayoutChanges="true"
原因是設置padding控件消失會出現的時候,產生動畫的效果,但是padding本身是透明的,所以我不關心它的效果如何(實際上,系統會給它一個淡入淡出的效果),我關心的是這個動畫是占用一定時間的,列表在調整自身位置的時候,也會產生向上滑動的效果。網上有一些方法是通過設置根布局paddingtop屬性,這個方法在調用的時候,listview會瞬間調整好當前的位置,導致屏幕閃了一下,如果用戶緩緩向下滑動不松手的話,滑動某個位置觸發了setpadding方法,屏幕會一直閃啊坑爹!
?
接著看代碼
/*** 由于標題是覆蓋在列表上面的,需要設置一個padding來防止列表被標題被覆蓋*/public void setPadding() {padding.setVisibility(View.VISIBLE);}/*** 當列表往下滑動的時候,標題隱藏了,為了調整列表的高度使其填充整個屏幕,只需要去除padding控件即可* 之前使用設置跟布局padding的方法,交互不友好,會閃屏,所以采取隱藏padding控件和根布局動畫屬性的方法*/public void reMovePadding() {padding.setVisibility(View.GONE);} /*** 隱藏標題,通過屬性動畫實現,和補間動畫相比,屬性動畫真實改變了控件的位置,補間動畫只是障眼法* 個人比較嫌棄補間動畫*/private boolean isTitleMenuOpen=true;private int titleMenuHeight;public void hideTitle() {if (isTitleMenuOpen) {ObjectAnimator.ofFloat(titleLayout, "translationY", 0.0F,-titleMenuHeight).setDuration(300).start();isTitleMenuOpen = false;}}/*** 顯示標題*/public void showTitle() {if (!isTitleMenuOpen) {ObjectAnimator.ofFloat(titleLayout, "translationY", -titleMenuHeight,0.0F).setDuration(300).start();isTitleMenuOpen = true;}}在這里,細心的人就會發現,為什么我不把設置padding控件和標題動畫放在同一個方法里面呢?
這是因為他們的調用時機是有很大差別的,只有滑動的時候在執行標題動畫,設置padding控件屬性只能是列表第一個item可視的時候設置
不然每次滑動都調整padding,列表會莫名的滑動標題高度的距離,用戶會崩潰的
?
下面是核心代碼:
/*** 列表的滑動監聽,關鍵在于監聽列表是否滑動到頂部,如果是,就把padding控件顯示出來,防止標題覆蓋列表* 其他情況下,隱藏padding,達到列表填充整個屏幕的效果* 千萬要記住,padding的出現和隱藏都會讓列表的位置發生調整,這樣給用戶的體驗很差,所以不要頻繁調用setpadding和removepadding方法*/private boolean isFirstVisiable=true;private OnScrollListener myOnScrollListener=new OnScrollListener() {@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) {// TODO Auto-generated method stub}@Overridepublic void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {// TODO Auto-generated method stubif (firstVisibleItem == 0) {setPadding();showTitle();isFirstVisiable=true;} else {reMovePadding();isFirstVisiable=false;}}}; /*** 判斷滑動方向,如果方向向上并且第一個item不可視,就隱藏標題* 為什么要判斷第一個標題不可視呢,因為第一個標題可視是設置padding控件顯示的關鍵,*/private float y_tmp1, y_tmp2;@Overridepublic boolean onTouch(View v, MotionEvent event) {// 獲取當前坐標float y = event.getY();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:y_tmp1 = y;break;case MotionEvent.ACTION_MOVE:y_tmp2 = y;if (y_tmp1 != 0 && y_tmp2 != 0) {if (y_tmp1 - y_tmp2 > 8&&! isFirstVisiable ) {// 向上滑動隱藏標題和導航欄hideTitle();Log.i("scolling", "向上滑動");}if (y_tmp2 - y_tmp1 > 8) {// 向下滑動顯示標題和導航欄showTitle();Log.i("scolling", "向下滑動");}}break;}return false;}在onCreate方法里面的一些初始化操作
@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mContext = this;initData();padding=findViewById(R.id.padding);titleLayout=findViewById(R.id.titleLayout);titleMenuHeight=getResources().getDimensionPixelSize(R.dimen.title_height);listview = (ListView) findViewById(R.id.listview);listview.addHeaderView(View.inflate(mContext, R.layout.item_blank, null));listview.setAdapter(new Myadapter());listview.setOnTouchListener(this);listview.setOnScrollListener(myOnScrollListener);}以上操作基本實現了本博文題目的功能,但是有個問題,實際項目中,listview的item可能會很大,高度超過100dp的,當第一個item可視的時候,向上滑動,標題隱藏了,padding卻不隱藏起來,因為它只有第一個item不可視的時候才隱藏啊,這就尷尬了。之前的東西就白看了呢!不用灰心!既然只要第一個可視的item不可視,padding就能隱藏起來對吧,那我來個瞞天過海,通過插入一個空白的頭部就好了,并且這個頭部很窄,只有1dp,只要手一滑動,基本就能把這個頭部給劃走,列表自然會填充整個屏幕;同理,當列表向下滑動的時候,只要這個很窄的頭部出現,padding控件就會出現,列表的位置也調整過來了。這是比較取巧的地方!!!
源碼:
http://pan.baidu.com/s/1c2Ntkas
轉載于:https://my.oschina.net/carbenson/blog/725972
總結
以上是生活随笔為你收集整理的listview上拉隐藏标题与下拉显示标题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 源码安装详解
- 下一篇: 用MathType编辑带点星号的流程