android頁面滑動時,頂部title背景漸變的實現
在淘寶的商品詳情頁,我們會看到頂部的title背景顏色隨著scrollView的上下滑動而漸變,這樣的功能在我們應用中會經常用到,今天就來說一下我實現下這種功能方法,當然方法可能比較笨,看到部落格的大牛,希望能得到你們的指點。
先晒幾張效果圖:
首先先解釋一下基本原理:我們的思路是重寫ScrollView,實現ScrollView的滑動監聽,在ScrollView滑動的過程中,對頂部Title做出相應的處理:
看一下title的佈局檔案:title.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/green" android:orientation="horizontal" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="5dp" android:background="@drawable/background_circle" android:padding="10dp" android:src="@drawable/icon_back" /> <View android:layout_width="0dp" android:layout_height="1dp" android:layout_weight="1" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="5dp" android:background="@drawable/background_circle" android:padding="10dp" android:src="@drawable/icon_shopping_cart" /> </LinearLayout>
title佈局檔案很簡單,顯示兩張圖片,一張是返回,一張是購物車。在這裡我選擇把title作為一個獨立的佈局檔案,因為我們開發過程中,頁面的title經常會非常像,一個title可能會在多個佈局中用到,所以把title單獨作為佈局可以方便管理,也減少很多程式碼量。
下面是頁面佈局檔案:activity_main.xml
<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" > <com.example.gradual_change.view.MyScrollView android:id="@+id/scroller" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ImageView android:layout_width="match_parent" android:layout_height="250dp" android:src="@drawable/image_001" /> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:scaleType="fitXY" android:src="@drawable/image_002" /> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:scaleType="fitXY" android:src="@drawable/image_002" /> </LinearLayout> </com.example.gradual_change.view.MyScrollView> <include layout="@layout/title" /> </RelativeLayout>
activity_main佈局檔案中,MyScrollView是自定義的ScrollView,主要用於ScrollView的滑動時監聽;<include layout="@layout/title" />是開始定義的title佈局檔案引入到activity_main佈局中。為了方便,我的主佈局檔案主要用了三張比較長的圖片充當內容,讀者可以根據需求修改。
下面我們看一下自定義的ScrollView是如何實現的(MyScrollView):
MyScrollView繼承了ScrollView控制元件,主要思路是為MyScrollView綁定了一個監聽,並在onTouchEvent方法中觸發監聽,當檢測到使用者手指滑動時,根據滑動距離做出相應的處理。具體請看程式碼,裡面有詳細的解釋:
public class MyScrollView extends ScrollView {
private OnScrollListener onScrollListener;
/**
* 主要是用在使用者手指離開MyScrollView,MyScrollView還在繼續滑動,我們用來儲存Y的距離,然後做比較
*/
private int lastScrollY;
public ViewPagerScroller(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public ViewPagerScroller(Context context) {
super(context);
}
public ViewPagerScroller(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* 設定滾動介面
* @param onScrollListener
*/
public void setScrolListener(OnScrollListener onScrollListener){
this.onScrollListener = onScrollListener;
}
/**
* 用於使用者手指離開MyScrollView的時候獲取MyScrollView滾動的Y距離,然後回撥給onScroll方法中
*/
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
int scrollY = ViewPagerScroller.this.getScrollY();
if(onScrollListener != null){
onScrollListener.onScroll(scrollY);
}
//此時的距離和記錄下的距離不相等,在隔5毫秒給handler傳送訊息
if(lastScrollY != scrollY){
lastScrollY = scrollY;
handler.sendMessageDelayed(handler.obtainMessage(), 5);
}
}
};
/**
* 重寫onTouchEvent, 當用戶的手在MyScrollView上面的時候,
* 直接將MyScrollView滑動的Y方向距離回撥給onScroll方法中,當用戶擡起手的時候,
* MyScrollView可能還在滑動,所以當用戶擡起手我們隔20毫秒給handler傳送訊息,在handler處理
* MyScrollView滑動的距離
*/
@Override
public boolean onTouchEvent(MotionEvent ev) {
if(onScrollListener != null){
onScrollListener.onScroll(lastScrollY = this.getScrollY());
}
if(ev.getAction() == MotionEvent.ACTION_UP){
handler.sendMessageDelayed(handler.obtainMessage(), 20);
}
return super.onTouchEvent(ev);
}
public interface OnScrollListener{
/**
* 回撥方法, 返回MyScrollView滑動的Y方向距離
* @param scrollY
* 、
*/
public void onScroll(int scrollY);
}
}
做好了上面的工作,我們就可以在Activity中具體應用了。如下,請看MainActivity,改類實現了自定義的MyScrollView中滑動監聽介面OnScrollListener,主要的title改變在onScroll方法中,我們通過監聽MyScrollView滑動,根據滑動y方向的距離來對title做出想用的漸變效果。
MainActivity程式碼如下:
public class MainActivity extends Activity implements OnScrollListener{
private LinearLayout top_bg;
private ImageView back;
private ImageView shopping_cart;
private MyScrollView scroller;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
top_bg = (LinearLayout) findViewById(R.id.top_bg);
back = (ImageView) findViewById(R.id.back);
shopping_cart = (ImageView) findViewById(R.id.shopping_cart);
scroller = (ViewPagerScroller) findViewById(R.id.scroller);
top_bg.getBackground().setAlpha(0);
scroller.setScrolListener(this);
}
@Override
public void onScroll(int scrollY) {
if(scrollY < 100){
top_bg.getBackground().setAlpha(0);
back.getBackground().setAlpha(255);
shopping_cart.getBackground().setAlpha(255);
}else if(scrollY >= 100 && scrollY < 860){
top_bg.getBackground().setAlpha((scrollY-100)/3);
back.getBackground().setAlpha(255 - (scrollY-100)/3);
shopping_cart.getBackground().setAlpha(255 - (scrollY-100)/3);
}else{
top_bg.getBackground().setAlpha(255);
back.getBackground().setAlpha(0);
shopping_cart.getBackground().setAlpha(0);
}
}
}
其實許多類似的功能都可以通過上面的方法實現,比如:
某一控制元件逐漸向上滑動,到最頂端停止向上滑動功能的實現;
ScrollView向上滑動頂部隱藏,向下滑動頂部顯示功能的實現;
總的來數,如果需要實現隨著ScrollView的滑動,介面做出相應修改的類似功能,都可以按上面的方法實現。
需要的讀者可以根據自己的需求作出修改,希望對大家有幫助