多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > 滑動ListView自動隱藏頁面頭部和底部元素的例子

滑動ListView自動隱藏頁面頭部和底部元素的例子

來源:程序員人生   發布時間:2014-12-10 08:57:02 閱讀次數:3621次

完全工程代碼在這:https://github.com/NashLegend/Auto-Hide-ListView


現在很多軟件都有這類滑動列表的時候自動隱藏頁面頭部和底部元素的功能,比如Google+。在剛剛進入Activity的時候,頁面是1個列表,底部有1個view,頭部1個view,當列表向上滑動的時候,隱藏頭尾元素,以顯示更多內容,當列表向下滑動的時候,再將頭尾元素拉出來。比如Google+。


剛剛進入時是這個模樣:

wKiom1SARtexnCChAAepuJpccas204.jpg 

再把列表身上1拉,頭尾隱藏,成了這個模樣:

 wKiom1SARrrB7NHyAAgAx3R1fg4391.jpg  


再往下拉,就會再變回第1張圖的模樣。


這個例籽實現的就是這個功能


這個例子里面,MainActivity的布局以下,ToolBar是頂部元素,Button為底部元素。

<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" tools:context=".MainActivity"> <ListView android:id="@+id/list_view" android:layout_width="match_parent" android:layout_height="match_parent" android:headerDividersEnabled="false" /> <android.support.v7.widget.Toolbar android:id="@+id/action_bar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@android:color/holo_blue_light" /> <Button android:id="@+id/footer" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:text="@string/ScrollDown" /> </RelativeLayout>

public class MainActivity extends ActionBarActivity { ListView listView; Toolbar toolbar; View header; View footer; int touchSlop = 10; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); touchSlop = (int) (ViewConfiguration.get(MainActivity.this).getScaledTouchSlop() * 0.9);//轉動過量少距離后才開始計算是不是隱藏/顯示頭尾元素。這里用了默許touchslop的0.9倍。 listView = (ListView) findViewById(R.id.list_view); footer = findViewById(R.id.footer); toolbar = (Toolbar) findViewById(R.id.action_bar); // 下面這句將這個ToolBar設置為ActionBar,在這個例子里面,這句其實用不著,但是如果用了這句,就得把Theme設置為NoActionBar了,無關這里要說的,具體見上面的鏈接中的Style setSupportActionBar(toolbar); //為這個ListView填充元素。 String[] str = new String[64]; for (int i = 0; i < str.length; i++) { str[i] = "Android " + i; } //R.layout.simple_layout是1個TextView,詳見上面的鏈接…… ArrayAdapter<String> adapter = new ArrayAdapter<>(MainActivity.this, R.layout.simple_layout, str); listView.setAdapter(adapter); //為ListView添加1個Header,這個Header與ToolBar1樣高。這樣我們可以正確的看到列表中的第1個元素而不被遮住。 header = new View(MainActivity.this); header.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) getResources().getDimension(R.dimen.abc_action_bar_default_height_material))); header.setBackgroundColor(Color.parseColor("#00000000")); listView.addHeaderView(header); //為ListView設置觸摸事件和轉動事件,這是核心 listView.setOnTouchListener(onTouchListener); listView.setOnScrollListener(onScrollListener); footer.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //為button設置點擊事件,點擊1次轉動10個item listView.smoothScrollByOffset(10); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } AnimatorSet backAnimatorSet;//這是顯示頭尾元素使用的動畫 private void animateBack() { //先清除其他動畫 if (hideAnimatorSet != null && hideAnimatorSet.isRunning()) { hideAnimatorSet.cancel(); } if (backAnimatorSet != null && backAnimatorSet.isRunning()) { //如果這個動畫已在運行了,就不管它 } else { backAnimatorSet = new AnimatorSet(); //下面兩句是將頭尾元素放回初始位置。 ObjectAnimator headerAnimator = ObjectAnimator.ofFloat(toolbar, "translationY", toolbar.getTranslationY(), 0f); ObjectAnimator footerAnimator = ObjectAnimator.ofFloat(footer, "translationY", footer.getTranslationY(), 0f); ArrayList<Animator> animators = new ArrayList<>(); animators.add(headerAnimator); animators.add(footerAnimator); backAnimatorSet.setDuration(300); backAnimatorSet.playTogether(animators); backAnimatorSet.start(); } } AnimatorSet hideAnimatorSet;//這是隱藏頭尾元素使用的動畫 private void animateHide() { //先清除其他動畫 if (backAnimatorSet != null && backAnimatorSet.isRunning()) { backAnimatorSet.cancel(); } if (hideAnimatorSet != null && hideAnimatorSet.isRunning()) { //如果這個動畫已在運行了,就不管它 } else { hideAnimatorSet = new AnimatorSet(); ObjectAnimator headerAnimator = ObjectAnimator.ofFloat(toolbar, "translationY", toolbar.getTranslationY(), -toolbar.getHeight());//將ToolBar隱藏到上面 ObjectAnimator footerAnimator = ObjectAnimator.ofFloat(footer, "translationY", footer.getTranslationY(), footer.getHeight());//將Button隱藏到下面 ArrayList<Animator> animators = new ArrayList<>(); animators.add(headerAnimator); animators.add(footerAnimator); hideAnimatorSet.setDuration(200); hideAnimatorSet.playTogether(animators); hideAnimatorSet.start(); } } View.OnTouchListener onTouchListener = new View.OnTouchListener() { float lastY = 0f; float currentY = 0f; //下面兩個表示滑動的方向,大于0表示向下滑動,小于0表示向上滑動,等于0表示未滑動 int lastDirection = 0; int currentDirection = 0; @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: lastY = event.getY(); currentY = event.getY(); currentDirection = 0; lastDirection = 0; break; case MotionEvent.ACTION_MOVE: if (listView.getFirstVisiblePosition() > 0) { //只有在listView.getFirstVisiblePosition()>0的時候才判斷是不是進行顯隱動畫。由于listView.getFirstVisiblePosition()==0時, //ToolBar――也就是頭部元素必須是可見的,如果這時候候隱藏了起來,那末占位置用了headerview就被用戶發現了 //但是當用戶將列表向下拉露出列表的headerview的時候,應當要讓頭尾元素再次出現才對――這個判斷寫在了后面onScrollListener里面…… float tmpCurrentY = event.getY(); if (Math.abs(tmpCurrentY - lastY) > touchSlop) {//滑動距離大于touchslop時才進行判斷 currentY = tmpCurrentY; currentDirection = (int) (currentY - lastY); if (lastDirection != currentDirection) { //如果與上次方向不同,則履行顯/隱動畫 if (currentDirection < 0) { animateHide(); } else { animateBack(); } } } } break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: //手指抬起的時候要把currentDirection設置為0,這樣下次不管向哪拉,都與當前的不同(其實在ACTION_DOWN里寫了以后這里就用不著了……) currentDirection = 0; lastDirection = 0; break; } return false; } }; AbsListView.OnScrollListener onScrollListener = new AbsListView.OnScrollListener() { //這個Listener實際上是用來對付當用戶的手離開列表后列表依然在滑動的情況,也就是SCROLL_STATE_FLING int lastPosition = 0;//上次轉動到的第1個可見元素在listview里的位置――firstVisibleItem int state = SCROLL_STATE_IDLE; @Override public void onScrollStateChanged(AbsListView view, int scrollState) { //記錄當前列表狀態 state = scrollState; } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (firstVisibleItem == 0) { animateBack(); } if (firstVisibleItem > 0) { if (firstVisibleItem > lastPosition && state == SCROLL_STATE_FLING) { //如果上次的位置小于當前位置,那末隱藏頭尾元素 animateHide(); } //================================ if (firstVisibleItem < lastPosition && state == SCROLL_STATE_FLING) { //如果上次的位置大于當前位置,那末顯示頭尾元素,其實本例中,這個if沒用 //如果是滑動ListView觸發的,那末,animateBack()肯定已履行過了,所以沒有必要 //如果是點擊按鈕啥的觸發轉動,那末根據設計原則,按鈕肯定是頭尾元素之1,所以也不需要animateBack() //所以這個if塊是不需要的 animateBack(); } //這里沒有判斷(firstVisibleItem == lastPosition && state == SCROLL_STATE_FLING)的情況, //但是如果列表中的單個item如果很長的話還是要判斷的,只不過代碼又要多幾行 //但是可以取巧1下,在觸發滑動的時候拖動履行1下animateHide()或animateBack()――本例中的話就寫在那個點擊事件里就能夠了) //BTW,如果列表的滑動純是靠手滑動列表,而沒有類似于點擊1個按鈕滾到某個位置的話,只要第1個if就夠了… } lastPosition = firstVisibleItem; } }; }


生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 性欧美极品xxxx欧美一区二区 | 91精品国产综合久久久久久 | 亚洲黄色在线观看 | 欧美另类视频一区二区三区 | 欧美黑人乱大交 | 国产中文字幕第一页 | 天天综合天天做天天综合 | 国产永久免费视频 | 国产欧美日韩精品高清二区综合区 | 最近的中文字幕视频大全高清 | 欧美另类69xxxxx性欧 | 国产免费一级高清淫日本片 | 国产欧美精品三区 | 亚洲天堂久久精品 | 老司机午夜精品视频 | 一级在线 | 欧洲 | 久久伊 | 久久毛片免费看 | 国产日韩一区二区三区 | 亚洲激情小视频 | 337p欧洲日本大胆艺术 | 大片免费在线观看网址 | 午夜视频国语 | 午夜免费影院 | 国产精品国产三级国产无毒 | 欧美一级做 | 欧美性xxxx巨大黑人猛 | 99精品国产美女福到在线不卡 | 国产一区二区在线观看免费 | 午夜视频啪啪 | 国产精品人成人免费国产 | 在线久 | 国产日产欧产精品精品推荐在线 | 性久久久久久久久 | 欧美极品xxxxⅹ另类 | 欧美操片在线观看 | 密桃av| 国产精品一区二区久久精品 | 蜜芽一区二区国产精品 | 精品日韩欧美一区二区三区在线播放 | 综合图 |