PopWindow完全解析
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PopWindow完全解析相关的知识,希望对你有一定的参考价值。
参考技术A 1、含义Popwindow就是android上自定义的一个弹出窗口,是在当前activity的顶部的,可以在任意的位置显示,在显示的时候会阻塞UI线程。
2、构造
Popwindow可以直接通过构造方法获取
new PopupWindow(View contentView,intwidth,intheight,booleanfocusable)
构造方法有很多,但是要确保contentview ,width,hight的设置,否则Popwindow不会显示任何内容
这些参数也都可以单独进行设置,比如 popwindow.setContentView(contentView);
3、解析
popwindow的难点就在于这几个参数的设置,一般容易使人迷惑。
popupWindow1.setFocusable(true);//获取焦点
popupWindow1.setOutsideTouchable(true);//获取外部触摸事件
popupWindow1.setTouchable(true);//能够响应触摸事件
popupWindow1.setBackgroundDrawable(newColorDrawable(0x8f000000));//设置背景
关于背景的设置
popupWindow1.setFocusable(true);//获取焦点
popupWindow1.setOutsideTouchable(true);//获取外部触摸事件
popupWindow1.setTouchable(true);//能够响应触摸事件
//popupWindow1.setBackgroundDrawable(new ColorDrawable(0x8f000000));//设置背景
一般情况,如果前面几个设置都设置为true,而且果设置了背景的话,那么你按back键和点击弹窗外的区域能使弹窗消失,如果不设置背景的话,则不会有这样的效果,即使你设置了popupWindow.setOutsideTouchable(true)。
那么这是为什么呢?别人这里已经有完整的解答,就不再赘述了。
详情见: http://www.cnblogs.com/mengdd/p/3569127.html
关于touchable的设置
首先,我们要明确一点,点击到弹窗上的touch事件是首先传递到弹窗上的,如果你设置了touchable为true,那么当前弹窗则会消耗掉touch事件,当前的activity则不会再收到touch事件,反之则会收到事件。
关于focusable的设置
foucsable设置为true,弹窗在弹出后就获取到了焦点,焦点的获取,就告诉设备,外部按键事件向哪里传递。如果弹窗获取到了焦点,此时点击外部按键,按键事件是直接传递给弹窗的。需要注意的是设置focusable为true,并不代表这个控件就获取到了焦点,而是表示可以获取焦点。
popupWindow1.setFocusable(false);//获取焦点
popupWindow1.setOutsideTouchable(true);//获取外部触摸事件
popupWindow1.setTouchable(true);//能够响应触摸事件
popupWindow1.setBackgroundDrawable(newColorDrawable(0x8f000000));//设置背景
这也就解释了,按照上述设置,当你按back键的时候,并不是想象中的popwindow消失,因为弹窗并没有获取到焦点,按键事件直接传递到当前activity了。
popupWindow1.setFocusable(true);//获取焦点
popupWindow1.setOutsideTouchable(true);//获取外部触摸事件,设置false也是一样的效果
popupWindow1.setTouchable(true);//能够响应触摸事件
// popupWindow1.setBackgroundDrawable(new ColorDrawable(0x8f000000));//设置背景
当focusable为true后,感觉弹窗影响的区域是整个屏幕(猜测),这么猜测是有根据的,因为这时候点击弹窗内和弹窗外感觉是一样的,弹窗的contentview都会收到同样的事件序列,所以这时候,你就会发现setOutsideTouchalbe并没有什么用。此时,如果touchable为true,一般情况下,无论点击的是弹窗内还是外,当前的activity是收不到任何touch事件的,这也印证了我的猜测。
popupWindow1.setFocusable(true);//获取焦点
popupWindow1.setOutsideTouchable(true);//获取外部触摸事件
popupWindow1.setTouchable(false);//能够响应触摸事件
popupWindow1.setBackgroundDrawable(new ColorDrawable(0x8f000000));//设置背景
当你如上述设置的话,点击弹窗外和点击弹窗内都会使得弹窗消失,因为弹窗内外都是一样的效果,而弹窗又没有消耗事件的话(setTouchable为false),事件首先传递到弹窗,类型是MotionEvent.ACTION_OUTSIDE,此时如果没有设置背景的话,事件将会传递到activity中。如果setTouchable为true的话,那么传递到弹窗的事件类型就是普通类型,而且怎么都不会传递到activity中去。
popupWindow1.setFocusable(true);//获取焦点
popupWindow1.setOutsideTouchable(false);//获取外部触摸事件
popupWindow1.setTouchable(false);//能够响应触摸事件
popupWindow1.setBackgroundDrawable(newColorDrawable(0x8f000000));//设置背景
当然,如果你如上述那样设置,那么弹窗是不会收到任何touch事件的,因为系统判断你都设置false了,就是说不需要了,因此就不会发touch事件给这个弹窗
popupWindow1.setFocusable(false);//获取焦点
popupWindow1.setOutsideTouchable(true);//获取外部触摸事件
popupWindow1.setTouchable(true);//能够响应触摸事件
popupWindow1.setBackgroundDrawable(newColorDrawable(0x8f000000));//设置背景
如果你设置f ocusable为false的话,那么弹窗影响的区域就是你看到的弹窗内,按上图设置,点击外部区域,事件首先传递到弹窗,类型是MotionEvent.ACTION_OUTSIDE,如果没有设置背景的话,也就是说弹窗没有消耗的话,事件会传递到当前的activity中的。
关于OutsideTouchable的设置
OutsideTouchalbe顾名思义,就是指的是外面的事件,在这里,指的就是弹窗之外touch事件,比如说,像上述设置就能够点击弹窗之外的区域,使得弹窗消失。
popupWindow1.setFocusable(false);//获取焦点
popupWindow1.setOutsideTouchable(true);//获取外部触摸事件
popupWindow1.setTouchable(true);//能够响应触摸事件
popupWindow1.setBackgroundDrawable(newColorDrawable(0x8f000000));//设置背景
上图这么设置,点击弹窗外部区域能够使得弹窗消失,就是因为设置了OutsideTouchalbe为true,导致 事件首先传递到弹窗,类型是MotionEvent.ACTION_OUTSIDE。
总结: 设置focusalbe为true,两个效果那么弹窗就会获取焦点,就会使得按键事件分发到弹窗上;弹窗影响的touch事件分发就是整个屏幕,点击弹窗内和弹窗外传递给弹窗的事件序列是一样的
设置背景的话,就等于给弹窗加了个外壳,而这个外壳重写了几个方法能够处理回退和一部分touch事件,这也就是设置了背景后,能够点击回退键和弹窗外使得弹窗消失的原因
设置 touchable为true的话,就表示弹窗会消耗掉事件,只要是弹窗内的事件都会被消耗掉,包括 focusalbe为true时弹窗外的(因为说过,这时候弹窗内外是一样的)。
设置OutsideTouchable为true的话,就是表示可以收到外部的事件 MotionEvent.ACTION_OUTSIDE。
注意: 无论怎么设置,只要弹窗能够收到touch事件,那么一定是弹窗先收到事件,如果弹窗消耗掉了,那么当前activity将收不到touch事件
按键事件是向焦点获取的控件分发的
popwindow+动画
布局:
main:
<Button
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
pop:
<ImageView
android:id="@+id/iv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@mipmap/ic_launcher"
/>
代码:
package com.example.my_popwindow_donghua;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.PopupWindow;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private PopupWindow popupWindow;
private Button btn;
private ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
btn = (Button) findViewById(R.id.btn);
View inflate = LayoutInflater.from(this).inflate(R.layout.pop, null);
iv = (ImageView) inflate.findViewById(R.id.iv);
popupWindow = new PopupWindow(inflate, ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT);
btn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn:
// AlphaAnimation alphaAnimation = new AlphaAnimation(1,0);
// alphaAnimation.setDuration(2000);
Animation alphaAnimation = AnimationUtils.loadAnimation(this,R.anim.bib);
iv.startAnimation(alphaAnimation);
if (popupWindow.isShowing()){
popupWindow.dismiss();
}else {
popupWindow.showAsDropDown(btn);
}
break;
}
}
}
以上是关于PopWindow完全解析的主要内容,如果未能解决你的问题,请参考以下文章