listview上拉隱藏標題與下拉顯示標題

這個功能很是廣泛了,主要是用戶在下拉列表的時候,隱藏標題來擴大用戶瀏覽列表的範圍java

本方法的設計思路是在列表上覆蓋標題欄,而後當列表滑到頂部的時候,在列表的頂部設置一個padding控件來佔和標題同樣的高度,防止列表頂部被標題覆蓋,當列表往下滑動的時候,經過動畫隱藏標題,只要列表的第一個item不可視,就把padding控件給隱藏掉,這樣達到列表填充整個屏幕的效果android

先看佈局ide

<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" >

    <View
        android:id="@+id/padding"
        android:layout_width="match_parent"
        android:layout_height="@dimen/title_height" />

    <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/padding"
        android:background="#F4F1F1" >
    </ListView>

    <LinearLayout
        android:id="@+id/titleLayout"
        android:layout_width="match_parent"
        android:layout_height="@dimen/title_height"
        android:background="@android:color/white"
        android:orientation="horizontal" >

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="1"
            android:gravity="center"
            android:text="標題" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="1"
            android:gravity="center"
            android:text="標題" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="1"
            android:gravity="center"
            android:text="標題" />

        <TextView
            android: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"this

緣由是設置padding控件消失會出現的時候,產生動畫的效果,可是padding自己是透明的,因此我不關心它的效果如何(實際上,系統會給它一個淡入淡出的效果),我關心的是這個動畫是佔用必定時間的,列表在調整自身位置的時候,也會產生向上滑動的效果。網上有一些方法是經過設置根佈局paddingtop屬性,這個方法在調用的時候,listview會瞬間調整好當前的位置,致使屏幕閃了一下,若是用戶緩緩向下滑動不鬆手的話,滑動某個位置觸發了setpadding方法,屏幕會一直閃啊坑爹!設計

 

接着看代碼code

/**
	 * 因爲標題是覆蓋在列表上面的,須要設置一個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控件和標題動畫放在同一個方法裏面呢?xml

這是由於他們的調用時機是有很大差異的,只有滑動的時候在執行標題動畫,設置padding控件屬性只能是列表第一個item可視的時候設置rem

否則每次滑動都調整padding,列表會莫名的滑動標題高度的距離,用戶會崩潰的

 

下面是核心代碼:

/**
	 * 列表的滑動監聽,關鍵在於監聽列表是否滑動到頂部,若是是,就把padding控件顯示出來,防止標題覆蓋列表
	 * 其餘狀況下,隱藏padding,達到列表填充整個屏幕的效果
	 * 千萬要記住,padding的出現和隱藏都會讓列表的位置發生調整,這樣給用戶的體驗不好,因此不要頻繁調用setpadding和removepadding方法
	 */

	private boolean isFirstVisiable=true;
	
	private OnScrollListener myOnScrollListener=new OnScrollListener() {
		
		@Override
		public void onScrollStateChanged(AbsListView view, int scrollState) {
			// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onScroll(AbsListView view, int firstVisibleItem,
				int visibleItemCount, int totalItemCount) {
			// TODO Auto-generated method stub
			if (firstVisibleItem == 0) {
				setPadding();
				showTitle();
				isFirstVisiable=true;
			} else {
				reMovePadding();
				isFirstVisiable=false;
			}
		}
	};
/**
	 * 判斷滑動方向,若是方向向上而且第一個item不可視,就隱藏標題
	 * 爲何要判斷第一個標題不可視呢,由於第一個標題可視是設置padding控件顯示的關鍵,
	 */
    private float y_tmp1, y_tmp2;

	@Override
	public 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方法裏面的一些初始化操做

@Override
	protected 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

相關文章
相關標籤/搜索