1. 程式人生 > >根據滑動改變view的大小和位置

根據滑動改變view的大小和位置

需求描述

最近專案中有這樣一個需求,頁面有titlebar和scrollowview兩部分,在titlebar的下邊有一個頭像,隨著scrollowview的滑動,頭像要縮放到固定大小然後停留在titlebar上不動了。

問題分析

首先這個需求並不陌生,類似於懸浮按鈕。但是不同的是有縮放。如果將這個圖片放在scrollview中的話,隨著scrollview的滑動,圖片是從titlebar的下邊走了,被titlebar遮蓋了。所以說我們要把圖片放在和titlebae,scrollview平級的位置上。通過對scrollowview的changelistener的監聽來改變圖片的位置和大小。

程式碼實現

投機取巧,通過改變padding的方式來改變view的位置和大小

scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
            @Override
            public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                if(top <=0){
                    top = rl_userhead.getPaddingTop
(); bottom = rl_userhead.getPaddingBottom(); right = rl_userhead.getPaddingRight(); titleHeight = DensityUtil.dip2px(MainActivity.this,44); small_top = DensityUtil.dip2px(MainActivity.this,9); small_bottom = DensityUtil.dip
2px(MainActivity.this,55); small_right = DensityUtil.dip2px(MainActivity.this,21); } Log.e("輸出y:",String.valueOf(scrollY)); Log.e("輸出:",String.valueOf(scrollY/44.0)); if(scrollY<=0){ rl_userhead.setPadding(rl_userhead.getPaddingLeft(),top,right,bottom); }else if(scrollY>0 && scrollY<titleHeight){ rl_userhead.setPadding(rl_userhead.getPaddingLeft(),(int)(top-scrollY/44*35.0),(int)(right+ scrollY/44*21.0),(int)(bottom+ scrollY/44*55.0)); }else { rl_userhead.setPadding(rl_userhead.getPaddingLeft(),small_top,small_right,small_bottom); } } });

首先需要分析預設情況下的位置,和最後需要固定的位置
下面的程式碼就是計算出預設情況下的padding和最後固定位置的padding

if(top <=0){
    top = rl_userhead.getPaddingTop();
    bottom = rl_userhead.getPaddingBottom();
    right = rl_userhead.getPaddingRight();
    titleHeight = DensityUtil.dip2px(MainActivity.this,44);
    small_top = DensityUtil.dip2px(MainActivity.this,9);
    small_bottom = DensityUtil.dip2px(MainActivity.this,55);
    small_right = DensityUtil.dip2px(MainActivity.this,21);
}

下邊的程式碼是根據滑動的方向和距離來改變padding值

if(scrollY<=0){
                    rl_userhead.setPadding(rl_userhead.getPaddingLeft(),top,right,bottom);
                }else if(scrollY>0 && scrollY<titleHeight){
                    rl_userhead.setPadding(rl_userhead.getPaddingLeft(),(int)(top-scrollY/44*35.0),(int)(right+ scrollY/44*21.0),(int)(bottom+ scrollY/44*55.0));
                }else {
                    rl_userhead.setPadding(rl_userhead.getPaddingLeft(),small_top,small_right,small_bottom);
                }
            }

ok,到了這裡基本上算是完成了,執行看一下效果,比較滿意。但是還有缺憾,感覺不是很流暢,有點卡頓。打印出來scrollY的值發現跨度比較大,還是int型別的。這樣的話在計算的 過程中肯定要丟精度的。接下來就來優化一下。

優化效果

我們用onTouch來實現

scrollView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                if(motionEvent.getAction() == MotionEvent.ACTION_UP){
                    isInTouch = false;
                }
                if(motionEvent.getAction() == MotionEvent.ACTION_DOWN || motionEvent.getAction() == MotionEvent.ACTION_MOVE){
                    isInTouch = true;
                }

                if(top <=0){
                    top = rl_userhead.getPaddingTop();
                    bottom = rl_userhead.getPaddingBottom();
                    right = rl_userhead.getPaddingRight();
                    titleHeight = DensityUtil.dip2px(MainActivity.this,44);
                    small_top = DensityUtil.dip2px(MainActivity.this,9);
                    small_bottom = DensityUtil.dip2px(MainActivity.this,55);
                    small_right = DensityUtil.dip2px(MainActivity.this,21);
                    //XgoLog.e("上下:"+top+"..."+bottom);
                }
                //XgoLog.e("上下:"+top+"..."+bottom);
                double y = scrollView.getScrollY();
                double s = y/44.0;

                Log.e("輸出y:",String.valueOf(y));
                if(y<=0){
                    rl_userhead.setPadding(rl_userhead.getPaddingLeft(),top,right,bottom);
                }else if(y>0 && y<titleHeight){
                    rl_userhead.setPadding(rl_userhead.getPaddingLeft(),(int)(top-s*35.0),(int)(right+ s*21.0),(int)(bottom+ s*55.0));
                }else {
                    rl_userhead.setPadding(rl_userhead.getPaddingLeft(),small_top,small_right,small_bottom);
                }

                return false;

            }
        });

程式碼不再解釋了,執行效果非常流暢。但是又出現了另一個問題,快速滑動的時候可能不那麼精確。我們先來想一下,onTouch是觸控的監聽,當快速滑動的時候我們手指離開了螢幕,但是還在滑動,那手指離開了肯定就不會再執行onTouch了,自然圖片也就不會動了。
前邊也說了,雖然ontouch不再執行了,但是scrollow還在滑動呢,所以scrollChangeListener還在執行。我們的優化解決方案就是首先用onTouch來改變,當手指離開後用scrollChangeListener來接手改變view的位置。直接上程式碼

scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
            @Override
            public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {

                if(!isInTouch){
                    if(scrollY<=0){
                        rl_userhead.setPadding(rl_userhead.getPaddingLeft(),top,right,bottom);
                    }else if(scrollY>0 && scrollY<titleHeight){
                        rl_userhead.setPadding(rl_userhead.getPaddingLeft(),(int)(top-scrollY/44*35.0),(int)(right+ scrollY/44*21.0),(int)(bottom+ scrollY/44*55.0));
                    }else {
                        rl_userhead.setPadding(rl_userhead.getPaddingLeft(),small_top,small_right,small_bottom);
                    }
                }


            }
        });

        scrollView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                if(motionEvent.getAction() == MotionEvent.ACTION_UP){
                    isInTouch = false;
                }
                if(motionEvent.getAction() == MotionEvent.ACTION_DOWN || motionEvent.getAction() == MotionEvent.ACTION_MOVE){
                    isInTouch = true;
                }

                if(top <=0){
                    top = rl_userhead.getPaddingTop();
                    bottom = rl_userhead.getPaddingBottom();
                    right = rl_userhead.getPaddingRight();
                    titleHeight = DensityUtil.dip2px(MainActivity.this,44);
                    small_top = DensityUtil.dip2px(MainActivity.this,9);
                    small_bottom = DensityUtil.dip2px(MainActivity.this,55);
                    small_right = DensityUtil.dip2px(MainActivity.this,21);
                    //XgoLog.e("上下:"+top+"..."+bottom);
                }
                //XgoLog.e("上下:"+top+"..."+bottom);
                double y = scrollView.getScrollY();
                double s = y/44.0;

                Log.e("輸出y:",String.valueOf(y));
                if(y<=0){
                    rl_userhead.setPadding(rl_userhead.getPaddingLeft(),top,right,bottom);
                }else if(y>0 && y<titleHeight){
                    rl_userhead.setPadding(rl_userhead.getPaddingLeft(),(int)(top-s*35.0),(int)(right+ s*21.0),(int)(bottom+ s*55.0));
                }else {
                    rl_userhead.setPadding(rl_userhead.getPaddingLeft(),small_top,small_right,small_bottom);
                }

                return false;

            }
        });

兩個配合使用,效果完美。
完工!

相關推薦

根據滑動改變view大小位置

需求描述 最近專案中有這樣一個需求,頁面有titlebar和scrollowview兩部分,在titlebar的下邊有一個頭像,隨著scrollowview的滑動,頭像要縮放到固定大小然後停留在titlebar上不動了。 問題分析 首先這個需求並不陌生,類

IOS-筆記5 (swiftOC,View大小位置

Objective-c和swift: NSString----->Stirng         NSArray------->Array<AnyObject>      NSDictionary------>Dictionary<NSOb

C++ MFC 改變控制元件大小位置

用CWnd類的函式MoveWindow()或SetWindowPos()可以改變控制元件的大小和位置。 void MoveWindow(int x,int y,int nWidth,int nHeight); void MoveWindow(LPCRECT lpRect);

subplot 設置不一樣的圖片大小位置

sin exp sub posit tla brush wid 設置 http t=[0:0.1:25]; y1=exp(-t/3); y3=sin(2*t+3); y2=log(t+1); subplot(2,2,1) plot(t,y1,‘linewidth‘,2)

電子合同印章大小位置調整

公司最近正在開發關於使用第三方電子合同的功能,我們用的是一個叫契~約~鎖~的第三方平臺。 平臺對接人員的態度非常好,官網公佈出來的對接文件和提供的 java sdk 都非常實用,使用簡單。 目前遇到一個問題,通過pdf檔案生成的電子合同,需要根據滑鼠點選位置完成蓋章動作時,發現該章的

關於background-image調整大小位置的方法筆記

遇到background-image的問題有點多,直接上網搜資料自己整理一下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Titl

Qt-QComboBox改變顯示方式位置

setView 設定combobox的顯示視窗,並且設定tableview的選中項為當前顯示項 ui->comboBox->setModel(model); QTableView *tableView = new QTableView; tableView-&

Android AlertDialog大小位置的設定,取得內部控制元件例項

初始化AlertDialog AlertDialog.Builder builder=new AlertDialog.Builder(MainActivity.this); builder.setView(R.layout.dialog_item01); AlertDialog dialog=bui

如何使用set來設定按鈕的大小位置,以及一些屬性

b1 = new Button("go on"); //宣告一個按鍵 Frame f = new Frame("bu"); f.setLayout(null); f.setSize(300

如何實現控制元件隨對話方塊大小變化而自動調整大小位置

1. 處理對話方塊的WM_SIZE,然後用MoveWindow或者SetWindowPos來把對話方塊上面的控制元件重新調整新位置和大小。  2. 基本的做法就是響應WM_SIZE訊息,並按照視窗大小比例來調整控制元件的位置和大小,控制元件的大小最好設定成視窗的百分之幾,這

mfc怎麼動態載入時間以及改變字型大小顏色。

第一次寫  留著備份 以後可能還會用到 動態載入時間 1.在OnInitDialog() 初始化函式中加入 SetTimer(1,1000,NULL); 2.增加訊息函式 OnTimer(UINT nIDEvent)  增加以下函式 CTime

VC對話方塊大小位置設定

軟體開發中,我們通常需要設定對話方塊到我們需要的大小,並且希望能在我們希望的位置顯示,那麼就需要設定對話方塊的大小和位置了。 步驟: 1.新建對話方塊 新建對話方塊應用程式,為了方便對比,我們還另外新

如何自定義PickerView 以及改變字型大小字型顏色

首先,我們要向系統給我們的PickerView一樣,定義它的代理方法和資料來源方法。 #import <UIKit/UIKit.h> @classMyPickerView; //資料來源方法 @protocol UIMyPickerDataSou

iconfont的使用,阿里向量相簿的引用,配置,改變圖示大小圖示顏色

怎麼使用iconfont首先找到自己想要的圖示,新增到購物車如果你只要一個圖示的話,或者確保之後這個專案不需要其他的圖示的話,可以直接選擇下載程式碼,但是你有多個圖示的話,最好選擇新增至專案無論是新增專案還是直接下載程式碼,下載之後會有一個download.zip包,解壓之後

window中location物件改變瀏覽器URL位置

window.location可以簡寫為location 1.開啟一個新的url,並在瀏覽器的歷史中生成一條記錄: location.assign('http://www.baidu.com/'

修改系統TabBar高度、文字大小位置

1、修改tabbar高度 重寫- (void)viewWillLayoutSubviews方法 //改變tabbar高度 - (void)viewWillLayoutSubviews{ CGRect tabFrame = self.tabBar.

自定義dialog的大小位置

 Dialog dialog = new Dialog(this);              // setContentView可以設定為一個View也可以簡單地指定資源ID       // LayoutInflater       // li=(LayoutInfla

Android 在程式碼中設定imageview的大小位置(滿足單方向的放大縮小任意位置的移動)

       許久以前,在我還是初中的時候,有過一個當網路小說家的夢想,誰知到如今,卻成一個程式設計師。享受生活,享受現在,做一個寫部落格的程式設計師,也算是了卻當初的半個夢想。                                                

DialogFragment如何設定大小位置

getDialog().getWindow().setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM); WindowManager.LayoutParams lp = getDialog().getWi

J2EE-JSplitPane分隔條箭頭大小位置調整

轉自:http://361324767.blog.163.com/blog/static/114902525201092882159166/ 1、調整箭頭大小的最快捷辦法      在UI中設定SplitPane.oneTouchButtonSize的值,API中預設的值