編輯:Android開發實例
我之前寫了一篇關於美團網,大眾點評的購買框效果的文章http://www.fengfly.com/plus/view-214540-1.html ,我自己感覺效果並不是很好,如果快速滑動界面,顯示懸浮框的時候會出現一卡的現象,有些朋友說有時候會出現兩個布局的情況,特別是對ScrollView滾動的Y值得監聽,我還使用了Handler來獲取,還有朋友給我介紹了Scrolling Tricks這個東西,我下載試了下,確實美團網,大眾點評的購買框用的是這種效果,但是Scrolling Tricks只能在API11以上使用,這個有點小悲劇,然後我做了下修改,並將實現思路分享給大家,實現起來很簡單
首先還是要先對ScrollView進行滾動監聽,直接在onScrollChanged()方法中就能獲取滾動的Y值,之前那篇文章使用了Handler,走彎路了,直接看代碼吧
- package com.example.meituandemo;
- import android.content.Context;
- import android.util.AttributeSet;
- import android.widget.ScrollView;
- /**
- *
- * @author xiaanming
- *
- */
- public class MyScrollView extends ScrollView {
- private OnScrollListener onScrollListener;
- public MyScrollView(Context context) {
- this(context, null);
- }
- public MyScrollView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
- public MyScrollView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
- /**
- * 設置滾動接口
- * @param onScrollListener
- */
- public void setOnScrollListener(OnScrollListener onScrollListener) {
- this.onScrollListener = onScrollListener;
- }
- @Override
- public int computeVerticalScrollRange() {
- return super.computeVerticalScrollRange();
- }
- @Override
- protected void onScrollChanged(int l, int t, int oldl, int oldt) {
- super.onScrollChanged(l, t, oldl, oldt);
- if(onScrollListener != null){
- onScrollListener.onScroll(t);
- }
- }
- /**
- *
- * 滾動的回調接口
- *
- * @author xiaanming
- *
- */
- public interface OnScrollListener{
- /**
- * 回調方法, 返回MyScrollView滑動的Y方向距離
- * @param scrollY
- * 、
- */
- public void onScroll(int scrollY);
- }
- }
接下來看看主界面的布局文件
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/parent_layout"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
- <ImageView
- android:id="@+id/imageView1"
- android:layout_width="match_parent"
- android:layout_height="45dip"
- android:scaleType="centerCrop"
- android:src="@drawable/navigation_bar" />
- <com.example.meituandemo.MyScrollView
- android:id="@+id/scrollView"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" >
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content" >
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical" >
- <ImageView
- android:id="@+id/iamge"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/pic"
- android:scaleType="centerCrop" />
- <include
- android:id="@+id/buy"
- layout="@layout/buy_layout" />
- <ImageView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/one"
- android:scaleType="centerCrop" />
- <ImageView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/one"
- android:scaleType="centerCrop" />
- <ImageView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/one"
- android:scaleType="centerCrop" />
- </LinearLayout>
- <include
- android:id="@+id/top_buy_layout"
- layout="@layout/buy_layout" />
- </FrameLayout>
- </com.example.meituandemo.MyScrollView>
- </LinearLayout>
下面是布局的效果圖
從主界面的布局你可以看出,我們在上面放置了一個購買的布局,可能你會想,先讓上面的布局隱藏起來,等下面的布局滑動上來就將其顯示出來,如果這樣子就跟我之前寫的那篇文章差不多,效果不是很棒,所以這篇修改版的肯定不是這樣子的,我們還是先看主界面的代碼吧
- package com.example.meituandemo;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.ViewTreeObserver.OnGlobalLayoutListener;
- import android.widget.LinearLayout;
- import com.example.meituandemo.MyScrollView.OnScrollListener;
- /**
- *
- * @author xiaanming
- *
- */
- public class MainActivity extends Activity implements OnScrollListener{
- /**
- * 自定義的MyScrollView
- */
- private MyScrollView myScrollView;
- /**
- * 在MyScrollView裡面的購買布局
- */
- private LinearLayout mBuyLayout;
- /**
- * 位於頂部的購買布局
- */
- private LinearLayout mTopBuyLayout;
- @SuppressWarnings("deprecation")
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- myScrollView = (MyScrollView) findViewById(R.id.scrollView);
- mBuyLayout = (LinearLayout) findViewById(R.id.buy);
- mTopBuyLayout = (LinearLayout) findViewById(R.id.top_buy_layout);
- myScrollView.setOnScrollListener(this);
- //當布局的狀態或者控件的可見性發生改變回調的接口
- findViewById(R.id.parent_layout).getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- //這一步很重要,使得上面的購買布局和下面的購買布局重合
- onScroll(myScrollView.getScrollY());
- }
- });
- }
- @Override
- public void onScroll(int scrollY) {
- int mBuyLayout2ParentTop = Math.max(scrollY, mBuyLayout.getTop());
- mTopBuyLayout.layout(0, mBuyLayout2ParentTop, mTopBuyLayout.getWidth(), mBuyLayout2ParentTop + mTopBuyLayout.getHeight());
- }
- }
界面就短短的幾行代碼,可能看完這些代碼你還是沒有明白到底是怎麼做到的,沒關系,我給大家說說,其實我們是讓上面的購買布局和下面的購買布局重合起來了,layout()這個方法是確定View的大小和位置的,然後將其繪制出來,裡面的四個參數分別是View的四個點的坐標,他的坐標不是相對屏幕的原點,而且相對於他的父布局來說的,
我們在主頁面最外層的ViewGroup添加了布局狀態改變的監聽器,當繪制完了屏幕會回調到方法onGlobalLayout()中,我們在onGlobalLayout()方法中手動調用了下onScroll()方法,剛開始myScrollView.getScrollY()等於0,所以說當scrollY小於mBuyLayout.getTop()的時候,上面的購買布局的上邊緣到myScrollView的上邊緣的距離等於mBuyLayout.getTop()(即下面布局的上邊緣到myScrollView的上邊緣)所以剛開始上面的購買布局和下面的購買布局重合了。
當myScrollView向上滾動,而上面購買布局的上邊緣始終要和myScrollView的上邊緣保持mBuyLayout.getTop()這個距離,所以上面的購買布局也跟著向上滾動,當scrollY大於mBuyLayout.getTop()的時候,表示購買布局上邊緣滑動到了導航欄布局,所以此時購買布局的上邊緣與myScrollView的上邊緣始終要保持scrollY這個距離,所以購買布局才會一直在導航欄下面,就好像粘住了一樣,不知道你了解了沒有?好了,不過根據這種思路你也可以剛開始使用一個懸浮框來覆蓋在下面的購買布局上面,然後onScroll()方法中更新懸浮框的位置,不過懸浮框的x,y不是相對於父布局的,這點要注意下,這樣子也能實現效果,不過相對於此,要復雜的多,所以我們遇到類似的功能直接使用這種就行了,簡潔明了,好了,你是不迫不及待的想看下效果,那我們接下來就運行下程序吧
運行程序你會發現,無論我們怎麼滑動,都不會出現之前那篇文章的那些情況,很流暢吧,這跟美團,大眾點評的效果完全一致,好了,修改版的講解就到這裡結束了
源碼下載
轉自:http://blog. csdn. net/xiaanming/article/details/17761431
Android提供了許多方法來控制播放的音頻/視頻文件和流。其中該方法是通過一類稱為MediaPlayer。Android是提供MediaPlayer類訪問內置的媒體播放
在java中可有兩種方式實現多線程,一種是繼承Thread類,一種是實現Runnable接口;Thread類是在java.lang包中定義的。一個類只要繼承了Th
做個網站的安卓客戶端,用戶安裝到自己手機上,如果我出了新版本怎麼辦呢?要有版本更新功能。 本來版本檢測最好可以自動進行。但如果每次開啟程序,都要先檢測一輪,是一種
引言 應用程序組件有一個生命周期——一開始Android實例化他們響應意圖,直到結束實例被銷毀。在這期間,他們有時候處於激活狀態,有時候處於非激活狀 態;對於活