1. 程式人生 > >android的Popupwindow根據手勢來貼邊劃出

android的Popupwindow根據手勢來貼邊劃出

剛剛開始學習android,沒事的時候想實現一下Popupwindow依靠手勢來貼邊彈出,在網上東抄西抄終於完成了,程式碼貼上。

/**

*獲取螢幕大小的類

**/

package modle.di.tang.android.Guest;

import android.content.Context;
import android.util.DisplayMetrics;
import android.view.WindowManager;

/**
 * Created by tangdi on 2016/1/11.
 */
public class GestureUtils {

    //獲取螢幕的大小
    public static GuestModelActivity.Screen getScreenPix(Context context) {
        DisplayMetrics dm = new DisplayMetrics();
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        windowManager.getDefaultDisplay().getMetrics(dm);
        return new GuestModelActivity.Screen(dm.widthPixels,dm.heightPixels);
    }
}


/**
*通過手勢來彈出Popuwindow
其實就是繼承了android 的GestureDetector。OnGestureListener這個藉口
但是要注意,在重寫OnTouchEvent(Event e)這個方法的時候,一定要return
GestureDetector .OnTouchEvent()方法,意思就是將OnTouchEvent方法觸控事件託管給了手勢來處理,
1>繼承
GestureDetector.OnGestureListener
2>建立
GestureDetector 實體類
3>註冊
GestureDetector 實體類
4>
將OnTouchEvent事件交給手勢來處理
5>實現
GestureDetector.OnGestureListener
手勢託管就完成了,接下來我就定義了幾個自己的動畫。程式碼在下面
**/
import android.app.ActionBar;
import android.app.Activity;
import android.content.Context;

import android.location.Location;
import android.os.Bundle;
import android.text.Layout;
import android.util.Log;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;


import modle.di.tang.androidmodle.R;

/**
 * Created by tangdi on 2016/1/12.
 */
public class GuestModelActivity extends Activity implements GestureDetector.OnGestureListener{

    private GestureDetector mGestureDetector;

    /**
     * 獲得螢幕尺寸
     */
    private Screen screen;

    private PopupWindow popupWindow;

    private View contentView;


    private int from = 0;

    private static final String TAG = "GuestModelActivity";

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_guest);
       mGestureDetector = new GestureDetector(this, this);
       screen = GestureUtils.getScreenPix(this);
       popupWindowInit();
   }

    private void popupWindowInit(){
        contentView = LayoutInflater.from(this).inflate(R.layout.activity_popup, null);
        popupWindow = new PopupWindow(contentView);
        popupWindow.setBackgroundDrawable(getResources().
                getDrawable(R.color.self_color));
        popupWindow.setOutsideTouchable(true);
        popupWindow.setFocusable(true);

    }


    @Override
    public boolean onTouchEvent(MotionEvent event){

        return mGestureDetector.onTouchEvent(event);
    }

    @Override
    public boolean onDown(MotionEvent e){
        /**
         * 按下手勢
         */
        return false;
    }

    @Override
    public void onShowPress(MotionEvent e){

    }

    @Override
    public boolean onSingleTapUp(MotionEvent e){
        return false;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY){
        /**
         * 拖動手勢
         */
        return false;
    }

    @Override
    public void onLongPress(MotionEvent e){
        /**
         * 長按手勢
         */
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY){
        //手指劃過螢幕的橫向距離

        float x = e2.getX() - e1.getX();
        //手指劃過螢幕的縱向距離
        float y = e2.getY() - e1.getY();

        //取得橫向距離的絕對值
        float x_abs = Math.abs(x);
        //取得縱向距離的絕對值
        float y_abs = Math.abs(y);

        //螢幕1/5的距離
        float x_limit = screen.widthPixels / 5;
        float y_limit = screen.heightPixels / 5;

        //手指在螢幕上橫向滑動
        if(x_abs >= y_abs){
            if(x > x_limit || x < -x_limit){
                if(x > 0){
                    //向右移動
                    from = location.RIGHT.ordinal();
                    initPopuWindow();
                    Log.e(TAG, "Right");
                }else if(x < 0){
                    //向左移動
                    from = location.LEFT.ordinal();
                    initPopuWindow();
                    Log.e(TAG, "Left");
                }
            }
        }
        //橫向滑動
        else {
            if(y > y_limit || y < -y_limit){
                if(y > 0){
                    //向下
                    from = location.TOP.ordinal();
                    initPopuWindow();
                    Log.e(TAG, "Down");

                }else if(y < 0 ){
                    //向上
                    from = location.BOTTOM.ordinal();
                    initPopuWindow();
                    Log.e(TAG, "Up");

                }
            }
        }
        return false;
    }


    /**
     * 螢幕尺寸類
     */
    public static class Screen{

        public int widthPixels;
        public int heightPixels;

        public Screen(){}

        public Screen(int widthPixels,int heightPixels){
            this.widthPixels=widthPixels;
            this.heightPixels=heightPixels;
        }

        @Override
        public String toString() {
            return "("+widthPixels+","+heightPixels+")";
        }

    }

    class popupDosmissListener implements PopupWindow.OnDismissListener{
        @Override
        public void onDismiss(){
            //backgroundAlpha(1f);
        }
    }

    private void backgroundAlpha(float bgAlpha){
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.alpha = bgAlpha;
        getWindow().setAttributes(lp);
    }

    private void initPopuWindow(){
        if(location.LEFT.ordinal() == from || location.RIGHT.ordinal() == from){
            //是否可以不這樣定義寬度
            popupWindow.setWidth(800);
            popupWindow.setHeight(LinearLayout.LayoutParams.MATCH_PARENT);
        }else if(location.BOTTOM.ordinal() == from || location.TOP.ordinal() == from){
            popupWindow.setWidth(LinearLayout.LayoutParams.MATCH_PARENT);
            popupWindow.setHeight(1200);
        }
        if(location.LEFT.ordinal() == from){
            popupWindow.setAnimationStyle(R.style.AnimationRightFade);
        }
        if(location.RIGHT.ordinal() == from){
            popupWindow.setAnimationStyle(R.style.AnimationLeftFade);
        }
        if(location.BOTTOM.ordinal() == from){
            popupWindow.setAnimationStyle(R.style.AnimationBottomFade);
        }
        if(location.TOP.ordinal() == from){
            popupWindow.setAnimationStyle(R.style.AnimationTopFade);
        }

        if(location.LEFT.ordinal() == from){
            popupWindow.showAtLocation(GuestModelActivity.this.findViewById(R.id.layout_main),
                    Gravity.RIGHT, 0, 0);

            Log.e(TAG, "顯示向左的Popuwindow");
        }else if(location.RIGHT.ordinal() == from){
            popupWindow.showAtLocation(GuestModelActivity.this.findViewById(R.id.layout_main),
                    Gravity.LEFT, 0, 0);

            Log.e(TAG, "顯示向右的Popuwindow");
        }else if(location.BOTTOM.ordinal() == from){
            popupWindow.showAtLocation(GuestModelActivity.this.findViewById(R.id.layout_main),
                    Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 0);

            Log.e(TAG, "顯示向下的Popuwindow");
        }else if(location.TOP.ordinal() == from){
            popupWindow.showAtLocation(GuestModelActivity.this.findViewById(R.id.layout_main),
                    Gravity.TOP|Gravity.CENTER_HORIZONTAL, 0, 0);
        }
       //backgroundAlpha(0.5f);
        //popupWindow.setOnDismissListener(new popupDosmissListener());
    }

    private enum location{
        LEFT,
        RIGHT,
        TOP,
        BOTTOM
    }

}


in_bottomtotop.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromYDelta="100%"
        android:toYDelta="0"
        android:duration="300"/>
</set>
in_lefttoright.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="-100%"
        android:toXDelta="0"
        android:duration="300"/>
</set>

in_righttoleft.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="100%"
        android:toXDelta="0"
        android:duration="300"/>
</set>

in_toptobottom.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromYDelta="-100%"
        android:toYDelta="0"
        android:duration="300">
    </translate>

</set>

out_bottomtotop.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromYDelta="0"
        android:toYDelta="-100%"
        android:duration="500"/>
</set>

out_lefttoright.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="0"
        android:toXDelta="100%"
        android:duration="300">
    </translate>
</set>

out_righttoleft.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="0"
        android:toXDelta="-100%"
        android:duration="300">
    </translate>

</set>

out_toptobottom.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromYDelta="0"
        android:toYDelta="100%"
        android:duration="300"/>
</set>


activity_guest.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/layout_main"
    android:background="@drawable/bg_snow_night">

</LinearLayout>
對於translate動畫的瞭解,是根據android手機螢幕的直角座標系來完成的