2014-12-02 73 views
22

最新Facebook的Android應用程序有一個非常漂亮的浮動評論窗口。在那裏,用戶可以忽略窗口向上或向下滑動,使得它非常易於使用。Android的浮動活動與刷卡

我要實現我的應用程序類似的行爲,但我不知道該怎麼做。任何想法或線索如何做到這一點將非常感激。

Facebook的應用程序的截圖
(對不起,從那裏我把截圖Facebook的應用程序是在日本) Swipe up Swipe down

+0

我更新我的幾張截圖的答案;) – 2014-12-04 20:12:12

回答

26

我寫一些代碼匹配該關閉/調整行爲,我不說'不知道是否要走,但我的代碼是基於活動類。我做的第一件事是創建一個活動,並給它Transluscent主題以獲得具有透明背景的活動。

在我的manifest.xml:

<activity 
    android:name=".PopupActivity" 
    android:label="@string/title_activity_popup" 
    <!-- Use Translucent theme to get transparent activity background 
    and NoTitleBar to avoid super old style title bar ;) --> 
    android:theme="@android:style/Theme.Translucent.NoTitleBar"> 
</activity> 

然後,我創建包含一個TextView(相當於Facebook的tchatting部分)和圖(相當於Facebook的一個簡單的佈局文件 「撰寫您的味精」/」發送笑臉」選項​​卡)

我的佈局/ activity_popup.xml:

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/base_popup_layout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:padding="8dp" 
    android:background="@android:color/darker_gray" 
    android:layout_marginBottom="124dp"> 

    <TextView 
     android:text="@string/hello_world" 
     android:layout_width="match_parent" 
     android:layout_height="200dp" 
     android:background="@android:color/black"/> 

    <View 
     android:layout_width="match_parent" 
     android:layout_height="80dp" 
     android:layout_alignParentBottom="true" 
     android:background="@android:color/holo_blue_dark"/> 

</RelativeLayout> 

最後,我在PopupActivity類中處理touch和move事件,我使用onTouchListener,它提供onTouch方法中的回調。

PopupActivity

public class PopupActivity extends Activity implements View.OnTouchListener{ 

    private RelativeLayout baseLayout; 

    private int previousFingerPosition = 0; 
    private int baseLayoutPosition = 0; 
    private int defaultViewHeight; 

    private boolean isClosing = false; 
    private boolean isScrollingUp = false; 
    private boolean isScrollingDown = false; 

    @Override 
    protected void onCreate(Bundle savedInstanceState){ 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_popup); 
     baseLayout = (RelativeLayout) findViewById(R.id.base_popup_layout); 
     baseLayout.setOnTouchListener(this); 
    } 


    public boolean onTouch(View view, MotionEvent event) { 

     // Get finger position on screen 
     final int Y = (int) event.getRawY(); 

     // Switch on motion event type 
     switch (event.getAction() & MotionEvent.ACTION_MASK) { 

      case MotionEvent.ACTION_DOWN: 
       // save default base layout height 
       defaultViewHeight = baseLayout.getHeight(); 

       // Init finger and view position 
       previousFingerPosition = Y; 
       baseLayoutPosition = (int) baseLayout.getY(); 
       break; 

      case MotionEvent.ACTION_UP: 
       // If user was doing a scroll up 
       if(isScrollingUp){ 
        // Reset baselayout position 
        baseLayout.setY(0); 
        // We are not in scrolling up mode anymore 
        isScrollingUp = false; 
       } 

       // If user was doing a scroll down 
       if(isScrollingDown){ 
        // Reset baselayout position 
        baseLayout.setY(0); 
        // Reset base layout size 
        baseLayout.getLayoutParams().height = defaultViewHeight; 
        baseLayout.requestLayout(); 
        // We are not in scrolling down mode anymore 
        isScrollingDown = false; 
       } 
       break; 
      case MotionEvent.ACTION_MOVE: 
       if(!isClosing){ 
        int currentYPosition = (int) baseLayout.getY(); 

        // If we scroll up 
        if(previousFingerPosition >Y){ 
         // First time android rise an event for "up" move 
         if(!isScrollingUp){ 
          isScrollingUp = true; 
         } 

        // Has user scroll down before -> view is smaller than it's default size -> resize it instead of change it position 
        if(baseLayout.getHeight()<defaultViewHeight){ 
         baseLayout.getLayoutParams().height = baseLayout.getHeight() - (Y - previousFingerPosition); 
         baseLayout.requestLayout(); 
        } 
        else { 
         // Has user scroll enough to "auto close" popup ? 
         if ((baseLayoutPosition - currentYPosition) > defaultViewHeight/4) { 
          closeUpAndDismissDialog(currentYPosition); 
          return true; 
         } 

         // 
        } 
        baseLayout.setY(baseLayout.getY() + (Y - previousFingerPosition)); 

       } 
       // If we scroll down 
       else{ 

        // First time android rise an event for "down" move 
        if(!isScrollingDown){ 
         isScrollingDown = true; 
        } 

        // Has user scroll enough to "auto close" popup ? 
        if (Math.abs(baseLayoutPosition - currentYPosition) > defaultViewHeight/2) 
        { 
         closeDownAndDismissDialog(currentYPosition); 
         return true; 
        } 

        // Change base layout size and position (must change position because view anchor is top left corner) 
        baseLayout.setY(baseLayout.getY() + (Y - previousFingerPosition)); 
        baseLayout.getLayoutParams().height = baseLayout.getHeight() - (Y - previousFingerPosition); 
        baseLayout.requestLayout(); 
       } 

       // Update position 
       previousFingerPosition = Y; 
      } 
      break; 
     } 
     return true; 
    } 
} 

有兩個小方法調用時用戶滾動足以關閉彈出窗口(即動畫和完成活動):

public void closeUpAndDismissDialog(int currentPosition){ 
    isClosing = true; 
    ObjectAnimator positionAnimator = ObjectAnimator.ofFloat(baseLayout, "y", currentPosition, -baseLayout.getHeight()); 
    positionAnimator.setDuration(300); 
    positionAnimator.addListener(new Animator.AnimatorListener() 
    { 
     . . . 
     @Override 
     public void onAnimationEnd(Animator animator) 
     { 
      finish(); 
     } 
     . . . 
    }); 
    positionAnimator.start(); 
} 

public void closeDownAndDismissDialog(int currentPosition){ 
    isClosing = true; 
    Display display = getWindowManager().getDefaultDisplay(); 
    Point size = new Point(); 
    display.getSize(size); 
    int screenHeight = size.y; 
    ObjectAnimator positionAnimator = ObjectAnimator.ofFloat(baseLayout, "y", currentPosition, screenHeight+baseLayout.getHeight()); 
    positionAnimator.setDuration(300); 
    positionAnimator.addListener(new Animator.AnimatorListener() 
    { 
     . . . 
     @Override 
     public void onAnimationEnd(Animator animator) 
     { 
      finish(); 
     } 
     . . . 
    }); 
    positionAnimator.start(); 
} 

這一切的代碼你應該是能夠啓動全局匹配Facebook彈出行爲的PopupActivity。這只是一個選秀類和大量的工作仍然做:加上收盤參數的動畫,工作等等......

截圖:

Screenshot of PopupActivity as written above

+0

感謝您詳細的答覆! – 2014-12-10 14:23:39

+2

不錯的答案,但它不工作,如果視圖有滾動屬性 – Shah 2015-02-18 06:49:19

+0

它不適合我。 – 2016-04-25 07:29:51