GVKun编程网logo

Android Animation实战之屏幕底部弹出PopupWindow(android底部弹出页面)

1

最近很多小伙伴都在问AndroidAnimation实战之屏幕底部弹出PopupWindow和android底部弹出页面这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展Androi

最近很多小伙伴都在问Android Animation实战之屏幕底部弹出PopupWindowandroid底部弹出页面这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展Android Activity启动后立即弹出PopupWindow的两个方法、android PopupWindow、android PopupWindow 和 Activity弹出窗口实现方式、Android Popupwindow 拖动等相关知识,下面开始了哦!

本文目录一览:

Android Animation实战之屏幕底部弹出PopupWindow(android底部弹出页面)

Android Animation实战之屏幕底部弹出PopupWindow(android底部弹出页面)

Android动画的一个实战内容,从屏幕底部滑动弹出PopupWindow。 相信这种效果大家在很多APP上都遇到过,比如需要拍照或者从SD卡选择图片,再比如需要分享某些东西时,大多会采用这么一种效果:

那这种效果如何实现呢?
我们仿写一个这种效果的实例吧:

1)我们首先定义一下,弹出窗口的页面布局组件:take_photo_pop.xml

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  android:layout_width="fill_parent" 
  android:layout_height="wrap_content" 
  android:gravity="center_horizontal" 
  android:orientation="vertical"> 
 
  <LinearLayout 
    android:id="@+id/pop_layout" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:background="#ffffff" 
    android:layout_alignParentBottom="true" 
    android:gravity="center_horizontal" 
    android:orientation="vertical"> 
 
    <TextView 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:clickable="false" 
      android:gravity="center" 
      android:text="修改头像" 
      android:textColor="#8a8a8a" 
      android:textSize="15sp" /> 
 
    <View 
      android:layout_width="fill_parent" 
      android:layout_height="0.1dp" 
      android:layout_marginLeft="10dp" 
      android:layout_marginRight="10dp" 
      android:background="#00c7c0" /> 
 
    <Button 
      android:id="@+id/btn_take_photo" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:text="拍照" 
      android:textColor="#0e61aa" 
      android:textSize="18sp" /> 
 
    <Button 
      android:id="@+id/btn_pick_photo" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:text="从相册选择" 
      android:textColor="#0e61aa" 
      android:textSize="18sp" /> 
 
    <Button 
      android:id="@+id/btn_cancel" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:layout_marginBottom="15dip" 
      android:layout_marginTop="15dip" 
      android:text="取消" 
      android:textColor="#0e61aa" 
      android:textSize="18sp" 
      android:text/> 
  </LinearLayout> 
 
</RelativeLayout> 

2)现在定义动画,要知道该Popupwindow出现时是从页面底部向上滑动,消失时是从上向下滑动消失,,所以我们需要定义两个动画文件:
退出动画pop_exit_anim.xml

<?xml version="1.0" encoding="utf-8"?> 
<set xmlns:android="http://schemas.android.com/apk/res/android"> 
  <translate 
    android:duration="200" 
    android:fromYDelta="0" 
    android:toYDelta="50%p" /> 
  <alpha 
    android:duration="200" 
    android:fromAlpha="1.0" 
    android:toAlpha="0.0" /> 
</set> 
显示动画pop_enter_anim.xml
<?xml version="1.0" encoding="utf-8"?> 
<set xmlns:android="http://schemas.android.com/apk/res/android"> 
 
  <translate 
    android:duration="200" 
    android:fromYDelta="100%p" 
    android:toYDelta="0" /> 
  <alpha 
    android:duration="200" 
    android:fromAlpha="0.0" 
    android:toAlpha="1.0" /> 
</set> 

关于这两个动画,此处不再多做解析,读过我之前博文的都应该知道啦,很简单的,若是看不懂?请点击此文上方的链接学习之。
3)自定义弹出框Popupwindow:

import android.content.Context; 
import android.graphics.drawable.ColorDrawable; 
import android.view.LayoutInflater; 
import android.view.MotionEvent; 
import android.view.View; 
import android.widget.Button; 
import android.widget.PopupWindow; 
import android.widget.RelativeLayout; 
 
public class TakePhotoPopWin extends PopupWindow { 
 
  private Context mContext; 
 
  private View view; 
 
  private Button btn_take_photo,btn_pick_photo,btn_cancel; 
 
 
  public TakePhotoPopWin(Context mContext,View.OnClickListener itemsOnClick) { 
 
    this.view = LayoutInflater.from(mContext).inflate(R.layout.take_photo_pop,null); 
 
    btn_take_photo = (Button) view.findViewById(R.id.btn_take_photo); 
    btn_pick_photo = (Button) view.findViewById(R.id.btn_pick_photo); 
    btn_cancel = (Button) view.findViewById(R.id.btn_cancel); 
    // 取消按钮 
    btn_cancel.setonClickListener(new View.OnClickListener() { 
 
      public void onClick(View v) { 
        // 销毁弹出框 
        dismiss(); 
      } 
    }); 
    // 设置按钮监听 
    btn_pick_photo.setonClickListener(itemsOnClick); 
    btn_take_photo.setonClickListener(itemsOnClick); 
 
    // 设置外部可点击 
    this.setoutsidetouchable(true); 
    // mMenuView添加OnTouchListener监听判断获取触屏位置如果在选择框外面则销毁弹出框 
    this.view.setonTouchListener(new View.OnTouchListener() { 
 
      public boolean onTouch(View v,MotionEvent event) { 
 
        int height = view.findViewById(R.id.pop_layout).getTop(); 
 
        int y = (int) event.getY(); 
        if (event.getAction() == MotionEvent.ACTION_UP) { 
          if (y < height) { 
            dismiss(); 
          } 
        } 
        return true; 
      } 
    }); 
 
 
    /* 设置弹出窗口特征 */ 
    // 设置视图 
    this.setContentView(this.view); 
    // 设置弹出窗体的宽和高 
    this.setHeight(RelativeLayout.LayoutParams.MATCH_PARENT); 
    this.setWidth(RelativeLayout.LayoutParams.MATCH_PARENT); 
 
    // 设置弹出窗体可点击 
    this.setFocusable(true); 
 
    // 实例化一个ColorDrawable颜色为半透明 
    ColorDrawable dw = new ColorDrawable(0xb0000000); 
    // 设置弹出窗体的背景 
    this.setBackgroundDrawable(dw); 
 
    // 设置弹出窗体显示时的动画,从底部向上弹出 
    this.setAnimationStyle(R.style.take_photo_anim); 
 
  } 
} 

    定义要弹出的组件TakePhotoPopWin,它继承自PopupWindow,具体如何实现的,我备注信息很详细了。 有一个地方要提醒的是,就是最后要设置弹出窗体的显示动画,this.setAnimationStyle(R.style.take_photo_anim); 这是必不可少的,只有加上了它,才能应用动画效果!
看下take_photo_anim style的定义:

<style name="take_photo_anim" parent="android:Animation"> 
    <item name="android:windowEnteranimation">@anim/pop_enter_anim</item> 
    <item name="android:windowExitAnimation">@anim/pop_exit_anim</item> 
</style> 

就这么几步,一个可以从屏幕底部滑动弹出的组件

public void showPopFormBottom(View view) { 
  TakePhotoPopWin takePhotoPopWin = new TakePhotoPopWin(this,onClickListener); 
  //showAtLocation(View parent,int gravity,int x,int y) 
  takePhotoPopWin.showAtLocation(findViewById(R.id.main_view),Gravity.CENTER,0); 
} 
 
private View.OnClickListener onClickListener = new View.OnClickListener() { 
  @Override 
  public void onClick(View v) { 
 
    switch (v.getId()) { 
      case R.id.btn_take_photo: 
        System.out.println("btn_take_photo"); 
        break; 
      case R.id.btn_pick_photo: 
        System.out.println("btn_pick_photo"); 
        break; 
    } 
  } 
}; 

这下子,效果就和我一开始传的图一致啦!有木有学会了呢!?

拓展:
     玩过APP的大家都知道,在你进入新页面或者注册登录啥的时候,都会弹出一个等待的框框,表示网络请求中,你需要耐心等待下,比如微信的等待请求框效果如下:

    这里面其中也有个地方用到了动画,那就是不停旋转的那个小图标,它其实用的就是旋转动画!
    关于如何实现这么样一个旋转等待框,我以前写过一篇介绍的文章,可查看: 《Android自定义ProgressDialog进度等待框》

Android Activity启动后立即弹出PopupWindow的两个方法

Android Activity启动后立即弹出PopupWindow的两个方法

Activity启动后立即弹出PopupWindow的两个方法

    若在Activity的onCreate()方法中直接写弹出PopupWindow方法会报错,因为activity没有完全启动是不能

    弹出PopupWindow的。

    那我们只需要在activity完全启动后再弹出PopupWindow就行了。


    第一种方法: 利用Activity的 onWindowFocusChanged()方法

@Override
public void onWindowFocusChanged(boolean hasFocus) {
	// TODO Auto-generated method stub
	super.onWindowFocusChanged(hasFocus);
	// 弹出PopupWindow的具体代码
}


    第二种方法: 利用Handler和Runnable

private Handler mHandler = new Handler();

@Override
protected void onCreate(Bundle savedInstanceState) {
	// TODO Auto-generated method stub
	super.onCreate(savedInstanceState);
	setContentView(R.layout.main);
	mHandler.postDelayed(mRunnable, 500);
}
	
private Runnable mRunnable = new Runnable() {
	public void run() {
	// 弹出PopupWindow的具体代码
	}
};


android PopupWindow

PopupWindow window = new PopupWindow(activity);//的到对象

2

window.setBackgroundDrawable(activity.getResources().getDrawable(R.drawable.configlistviewbg));//设置背景      
        //设置PopupWindow显示和隐藏时的动画
        window.setAnimationStyle(R.style.AnimationFade);
        View view=LayoutInflater.from(activity).inflate(joker.housemananger.activity.R.layout.addhouseactivity_popuwindow, null,true);//将popu的布局文件实例出
        long wid=activity.getWindowManager().getDefaultDisplay().getWidth(); //的到屏幕的宽
        long hd=activity.getWindowManager().getDefaultDisplay().getHeight();//得到屏幕的高
        View call=view.findViewById(R.id.addhouse_popuwindow_bt_callphone);//以下设置 布局文件上控件的监听器,因为这个类就继承了OnclickListener接口就直接this了
        call.setOnClickListener(this);
        View mess=view.findViewById(R.id.addhouse_popuwindow_bt_message);
        mess.setOnClickListener(this);
        View cancel=view.findViewById(R.id.addhouse_popuwindow_bt_cancel);
        cancel.setOnClickListener(this);                
        window.setWidth(Integer.parseInt(wid+""));//设置popupWindow高度
        window.setHeight(Integer.parseInt(hd/2+"")-100);//设置高度
        window.setContentView(view);//设置popupwindows的内容   样子
            //设置PopupWindow外部区域是否可触摸
        window.setOutsideTouchable(false);
        window.setFocusable(true); //设置 popupwindows获得焦点,以此来响应 返回键

3


windows.showAsDropDown(View) //显示windows,从上面向下显示
windows.showAsDropDown(View,0,0) //同第一个,加上两个偏移量,横纵轴的偏移
windows.showAtLocation(view, Gravity.BOTTOM, 0, 0); //设置popupwindow出现的位置,参1 设置出现在哪个view内,参2出现的位置,冲对面展开,参3参4 横纵轴的偏移

4

popupwindow.dismiss(); //关闭popupwindows

5 popupwindow 的动画 style 的 item 的 syle 的值

<item name="android:windowEnterAnimation">@anim/anim_down_in</item>
    	<item name="android:windowExitAnimation">@anim/anim_down_out</item>





android PopupWindow 和 Activity弹出窗口实现方式

本人小菜一个。目前只见过两种弹出框的实现方式,第一种是最常见的PopupWindow,第二种也就是Activity的方式是前几天才见识过。感觉很霸气哦。没想到,activity也可以做伪窗口。
先贴上最常见的方法,主要讲activity的方法。
一、弹出PopupWindow


复制代码 代码如下:

/**
* 弹出menu菜单
*/
public void menu_press(){
if(!menu_display){
//获取LayoutInflater实例
inflater = (LayoutInflater)this.getSystemService(LAYOUT_INFLATER_SERVICE);
//这里的main布局是在inflate中加入的哦,以前都是直接this.setContentView()的吧?呵呵
//该方法返回的是一个View的对象,是布局中的根
layout = inflater.inflate(R.layout.main_menu,null);
//下面我们要考虑了,我怎样将我的layout加入到PopupWindow中呢???很简单
menuWindow = new PopupWindow(layout,LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT); //后两个参数是width和height
//menuWindow.showAsDropDown(layout); //设置弹出效果
//menuWindow.showAsDropDown(null,layout.getHeight());
//设置如下四条信息,当点击其他区域使其隐藏,要在show之前配置
menuWindow.setFocusable(true);
menuWindow.setoutsidetouchable(true);
menuWindow.update();
menuWindow.setBackgroundDrawable(new BitmapDrawable());
mClose = (LinearLayout)layout.findViewById(R.id.menu_close);
menuWindow.showAtLocation(this.findViewById(R.id.schoolmain),Gravity.BottOM|Gravity.CENTER_HORIZONTAL,50); //设置layout在PopupWindow中显示的位置
//如何获取我们main中的控件呢?也很简单
mMainbtn = (LinearLayout)layout.findViewById(R.id.menu_main_btn);
mHistorybtn = (LinearLayout) layout.findViewById(R.id.menu_history_btn);
mHelpbtn = (LinearLayout) layout.findViewById(R.id.menu_help_btn);
//下面对每一个Layout进行单击事件的注册吧。。。
//比如单击某个MenuItem的时候,他的背景色改变
//事先准备好一些背景图片或者颜色
mMainbtn.setonClickListener (new View.OnClickListener() {
@Override
public void onClick(View arg0) {
mywebView.loadUrl(URL);
menuWindow.dismiss(); //响应点击事件之后关闭Menu
}
});
mHelpbtn.setonClickListener (new View.OnClickListener() {
@Override
public void onClick(View arg0) {
mywebView.loadUrl(URL);
menuWindow.dismiss(); //响应点击事件
}
});
mHistorybtn.setonClickListener (new View.OnClickListener() {
@Override
public void onClick(View arg0) {
mywebView.loadUrl(URL);
menuWindow.dismiss(); //响应点击事件
}
});
menu_display = true;
}else{
//如果当前已经为显示状态,则隐藏起来
menuWindow.dismiss();
menu_display = false;
}
}
public void back_press(){
if(menu_display){ //如果 Menu已经打开 ,先关闭Menu
menuWindow.dismiss();
menu_display = false;
}
else {
Intent intent = new Intent();
intent.setClass(MainActivity.this,Exit.class);
startActivity(intent);
}
}

这种方法很简单,要注意的是如果要想点击其他地方使其隐藏,要在show设置四条属性如下:
// 使其聚焦
mPopupWindow.setFocusable(true);
// 设置允许在外点击消失
mPopupWindow.setoutsidetouchable(true);
//刷新状态
mPopupWindow.update();
//点back键和其他地方使其消失,设置了这个才能触发Ondismisslistener ,设置其他控件变化等操作
mPopupWindow.setBackgroundDrawable(new BitmapDrawable());
二、Activity做伪弹窗

 

本人感觉这个很先进啊。恕我冒犯,我只这里直接写上牛人的代码。此牛人写的是防微信的demo。做的相当好,我在后面附上CSDN免费下载链接。
先贴上java代码――Exit.java
package cn.buaa.myweixin;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.LinearLayout;
import android.widget.Toast;
public class Exit extends Activity {
private LinearLayout layout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.exit_dialog);
layout=(LinearLayout)findViewById(R.id.exit_layout);
layout.setonClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Todo Auto-generated method stub
Toast.makeText(getApplicationContext(),"提示:点击窗口外部关闭窗口!",
Toast.LENGTH_SHORT).show();
}
});
}
@Override
public boolean onTouchEvent(MotionEvent event){
finish();
return true;
}
public void exitbutton1(View v) {
this.finish();
}
public void exitbutton0(View v) {
this.finish();
MainWeixin.instance.finish();//关闭Main 这个Activity
}
}
附上布局文件:exit_dialog.xml
复制代码 代码如下:

View Code
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/exit_layout"
android:layout_width="280dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical"
android:background="@drawable/confirm_dialog_bg2" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:padding="5dp"
android:textColor="#333"
android:textSize="20sp"
android:text="退出微信" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#333"
android:layout_marginTop="1dp"
android:padding="10dp"
android:textSize="16sp"
android:gravity="center_horizontal"
android:text="退出后,你将收不到新的消\n息.确定要退出?" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="33dp"
android:layout_marginBottom="8dp"
>
<Button
android:id="@+id/exitBtn0"
android:layout_width="110dp"
android:layout_height="wrap_content"
android:text="是"
android:textSize="16sp"
android:textColor="#fff"
android:background="@drawable/btn_style_green"
android:gravity="center"
android:onClick="exitbutton0"
/>
<Button
android:id="@+id/exitBtn1"
android:layout_width="110dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="否"
android:textSize="16sp"
android:textColor="#333"
android:background="@drawable/btn_style_white"
android:gravity="center"
android:onClick="exitbutton1"
/>
</LinearLayout>
</LinearLayout>

分析,弹出exit这个框很简单,本身就是activity,在主界面用startavtivity等方法像普通activity启动。
关键是如何做到点击其他地方退出和如何关闭程序。
、点击其他地方退出,只要监听OnClickListener让所有的点击都退出就行了(除了xml中指定按钮事件之外)。
、退出主程序。只要在出程序中将主程序自己设置成静态对象,在外部调用即可 public static MainWeixin instance=null;
上面的布局和activity并不能将activity的窗体展现在主界面之上,看起来像个弹出框。下面是弹出框的styles配置:
复制代码 代码如下:

<style name="MyDialogStyle">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowFrame">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<item name="android:backgroundDimEnabled">true</item>
</style>

下面我们来分析一下这个布局的含义及重点:
重点1、<item name="android:windowBackground">@android:color/transparent</item>窗口背景色
重点2、<item name="android:windowFrame">@null</item>Dialog的windowFrame框为无
重点4、<item name="android:windowIsFloating">true</item>是否浮现在activity之上
重点5、<item name="android:windowIsTranslucent">true</item>窗口是否半透明――是(与第一条配合使用)
重点6、<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>窗口弹出效果
重点7、<item name="android:backgroundDimEnabled">true</item> 是否允许背景模糊
重点8、<item name="android:windowContentOverlay">@null</item>这个不设置的话,可能会出现边框黑线
以上代码都是牛人们的功劳,我拿来做一分析,给更多需要的朋友。
我在众多牛人的指引下一步步成长,感谢牛人们。

Android Popupwindow 拖动

 

   关于View的拖动你们应该比较了解了,好比对一个控件IamgeView拖动,或者一个视图View拖动,实现方式也很容易,继承OnTouchListener接口,而后重写onTouch方法,在触屏事件进行处理便可。可是Popupwindow如何实现拖动呢,咱们都知道它和普通的View不同,由于它不是继承于View类的,可是它的实现倒是和View密切相关的,由于咱们都知道Android视图的显示都是由View来处理的,因此必定离不开它。从Popupwindow的实现就能够看出来,ide

 

import com.android.internal.R;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.os.Build;
import android.os.IBinder;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnScrollChangedListener;
import android.view.WindowManager;

import java.lang.ref.WeakReference;
  上面是它的导包状况,基本上不是和View相关,就是和绘图相关。所以关于Popupwindow的拖动这一块,也和View有联系。首先看一下它的API,看一看有没有和View移动、变化相关的方法,果真在最后有几个update()方法,以下:

 

  update()方法用来更新Popupwindow的位置和大小的,那么问题就好解决了。看代码:布局

 

package com.example.drag_and_drop_movablepopupwindow;

import android.support.v7.app.ActionBaractivity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.PopupWindow;
import android.widget.TextView;

public class MainActivity extends ActionBaractivity {

	private Button btnopenPopup;

	private int mCurrentX;
	private int mCurrentY;
	
	private PopupWindow mPopup;
	 
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		setContentView(R.layout.activity_main);
		btnopenPopup = (Button) findViewById(R.id.openpopup);
		btnopenPopup.setonClickListener(new Button.OnClickListener() {

			@Override
			public void onClick(View arg0) {
				creatPopubWindow_1();
			}
		});
	}

	/**
	 * 1
	 */
	private void creatPopubWindow_1() {
		LayoutInflater layoutInflater = (LayoutInflater) getBaseContext()
				.getSystemService(LAYOUT_INFLATER_SERVICE);
		View popupView = layoutInflater.inflate(R.layout.popup, null);
		final PopupWindow popupWindow = new PopupWindow(popupView,
				200, 200);

		Button btndismiss = (Button) popupView.findViewById(R.id.dismiss);
		btndismiss.setonClickListener(new Button.OnClickListener() {

			@Override
			public void onClick(View v) {
				popupWindow.dismiss();
			}
		});

		popupWindow.showAsDropDown(btnopenPopup, 50, 50);

		popupView.setonTouchListener(new OnTouchListener() {
			int orgX, orgY;
			int offsetX, offsetY;

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					orgX = (int) event.getX();
					orgY = (int) event.getY();
					break;
				case MotionEvent.ACTION_MOVE:
					offsetX = (int) event.getRawX() - orgX;
					offsetY = (int) event.getRawY() - orgY;
					popupWindow.update(offsetX, offsetY, -1, -1, true);
					break;
				}
				return true;
			}
		});
	}
}

  效果如图:ui

  首先对Popupwindow设置触摸事件,而后在回调方法中进行计算,若是手指拖动了Popupwindow,那么就调用update()方法来更新它的位置。有些同窗可能不太理解参数-1是什么意思,在上面的API中,写明的是宽和高,这里怎么变成-1了呢,看一下Popupwindow源代码就明白了。this

 

 

/**
     * <p>Updates the position and the dimension of the popup window. Width and
     * height can be set to -1 to update location only.  Calling this function
     * also updates the window with the current popup state as
     * described for {@link #update()}.</p>
     *
     * @param x the new x location
     * @param y the new y location
     * @param width the new width, can be -1 to ignore
     * @param height the new height, can be -1 to ignore
     * @param force reposition the window even if the specified position
     *              already seems to correspond to the LayoutParams
     */
    public void update(int x, int y, int width, int height, boolean force) {
        if (width != -1) {
            mLastWidth = width;
            setWidth(width);
        }

        if (height != -1) {
            mLastHeight = height;
            setHeight(height);
        }

        if (!isShowing() || mContentView == null) {
            return;
        }

        WindowManager.LayoutParams p = (WindowManager.LayoutParams) mPopupView.getLayoutParams();

        boolean update = force;

        final int finalWidth = mWidthMode < 0 ? mWidthMode : mLastWidth;
        if (width != -1 && p.width != finalWidth) {
            p.width = mLastWidth = finalWidth;
            update = true;
        }

        final int finalHeight = mHeightMode < 0 ? mHeightMode : mLastHeight;
        if (height != -1 && p.height != finalHeight) {
            p.height = mLastHeight = finalHeight;
            update = true;
        }

        if (p.x != x) {
            p.x = x;
            update = true;
        }

        if (p.y != y) {
            p.y = y;
            update = true;
        }

        final int newAnim = computeAnimationResource();
        if (newAnim != p.windowAnimations) {
            p.windowAnimations = newAnim;
            update = true;
        }

        final int newFlags = computeFlags(p.flags);
        if (newFlags != p.flags) {
            p.flags = newFlags;
            update = true;
        }

        if (update) {
            setLayoutDirectionFromAnchor();
            mWindowManager.updateViewLayout(mPopupView, p);
        }
    }
  前两个if判断已经说得很清楚了,若是参数是-1的话,就不改变Popupwindow的大小了,由于咱们只是移动位置,因此才这样写。那关于Popupwindow的移动最后是怎么实现的呢,能够看出就是调用WindowManager的updateViewLayout()方法,这个方法在WindowManager中并无实现,它是ViewManager接口里面的方法,WindowManager继承了ViewManager。说到ViewManager,它里面定义的方法都很经常使用,看代码:

 

 

/** Interface to let you add and remove child views to an Activity. To get an instance
  * of this class, call {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}.
  */
public interface ViewManager
{
    /**
     * Assign the passed LayoutParams to the passed View and add the view to the window.
     * <p>Throws {@link android.view.WindowManager.BadTokenException} for certain programming
     * errors, such as adding a second view to a window without removing the first view.
     * <p>Throws {@link android.view.WindowManager.InvaliddisplayException} if the window is on a
     * secondary {@link display} and the specified display can't be found
     * (see {@link android.app.Presentation}).
     * @param view The view to be added to this window.
     * @param params The LayoutParams to assign to view.
     */
    public void addView(View view, ViewGroup.LayoutParams params);
    public void updateViewLayout(View view, ViewGroup.LayoutParams params);
    public void removeView(View view);
}
  这下你们应该明了,咱们常常用的addView、removeView方法就是在这里面定义的,那么谁去实现呢?就是Layout控件,好比LinearLayout、RelativeLayout等,因此咱们刚才用的updateViewLayout()方法也是在xml布局文件中的layout定义好的。    

今天关于Android Animation实战之屏幕底部弹出PopupWindowandroid底部弹出页面的讲解已经结束,谢谢您的阅读,如果想了解更多关于Android Activity启动后立即弹出PopupWindow的两个方法、android PopupWindow、android PopupWindow 和 Activity弹出窗口实现方式、Android Popupwindow 拖动的相关知识,请在本站搜索。

本文标签:

上一篇jquery.validate.js 的 remote 后台验证(jquery的validate前端表单验证)

下一篇详解Android中Notification的使用方法(android notificationmanager)