android的Popupwindow根據手勢來貼邊劃出
阿新 • • 發佈:2018-12-30
剛剛開始學習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手機螢幕的直角座標系來完成的