Android透明背景Dialog、Dialog实现悬浮窗口 可与输入法交互,不被输入法覆盖
来源:互联网 发布:侠客风云传mod数据 编辑:程序博客网 时间:2024/05/21 10:25
直接干货上代码!
直接干货上代码!
PersonSetRemarkDialog 核心代码
package com.ctri.ui.personal.widget;import android.app.AlertDialog;import android.content.Context;import android.os.Bundle;import android.view.View;import android.view.WindowManager;import android.widget.EditText;import android.widget.TextView;import com.ctri.ui.R;/******************** * 设置备注dialog ********************/public class PersonSetRemarkDialog extends AlertDialog { private OnCertainButtonClickListener mOnCertainButtonClickListener; private Context context; public interface OnCertainButtonClickListener { void onCertainButtonClick(String remark); } public PersonSetRemarkDialog(Context context) { super(context); this.context = context; } public void setOnCertainButtonClickListener(OnCertainButtonClickListener listener) { mOnCertainButtonClickListener = listener; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.dialog_person_setremark); TextView mSure = (TextView) findViewById(R.id.dialog_person_setremark_ensure); final EditText et = (EditText) findViewById(R.id.dialog_person_setremark_edit); et.setFocusable(true); mSure.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mOnCertainButtonClickListener != null) { String remark = et.getText().toString(); mOnCertainButtonClickListener.onCertainButtonClick(remark); } PersonSetRemarkDialog.this.dismiss(); } }); findViewById(R.id.dialog_person_setremark_cancle).setOnClickListener(new View .OnClickListener() { @Override public void onClick(View view) { PersonSetRemarkDialog.this.dismiss(); } }); findViewById(R.id.dialog_person_setremark_cancle_x).setOnClickListener(new View .OnClickListener() { @Override public void onClick(View view) { PersonSetRemarkDialog.this.dismiss(); } }); setCancelable(false); getWindow().setBackgroundDrawableResource(android.R.color.transparent);//只有这样才能去掉黑色背景 } @Override public void show() { super.show(); //这样后边的view怎么获取焦点呢? 谁调用 谁就可以获取焦点 如下 // mParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; //mWm.updateViewLayout(view, mParams); getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager .LayoutParams.FLAG_ALT_FOCUSABLE_IM); getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); }}
dialog_person_setremark.xml 布局
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/transparent" android:orientation="vertical"> <ImageView android:id="@+id/dialog_person_setremark_border" android:layout_width="1dp" android:layout_height="20dp" android:layout_below="@+id/dialog_person_setremark_layout" android:layout_centerHorizontal="true" android:background="@color/white"/> <ImageView android:id="@+id/dialog_person_setremark_cancle_x" android:layout_width="35dp" android:layout_height="35dp" android:layout_below="@+id/dialog_person_setremark_border" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:scaleType="fitXY" android:src="@drawable/clearedittext"/> <RelativeLayout android:id="@+id/dialog_person_setremark_layout" android:layout_width="270dp" android:layout_height="185dp" android:layout_alignParentTop="true" android:layout_centerInParent="true" android:background="@color/white" > <TextView android:id="@+id/dialog_person_setremark_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_marginTop="12dp" android:text="设置备注" android:textColor="@color/home_title_color" android:textSize="@dimen/font_size_18"/> <EditText android:id="@+id/dialog_person_setremark_edit" android:layout_width="240dp" android:layout_height="36dp" android:layout_below="@+id/dialog_person_setremark_title" android:layout_centerHorizontal="true" android:layout_marginTop="@dimen/margin_size_20" android:background="@drawable/bg_buy_gray" android:gravity="center" android:hint="1~8个汉字" android:inputType="number" android:padding="5dp" android:singleLine="true" android:textColor="@color/black" android:textSize="16sp"/> <TextView android:id="@+id/dialog_person_setremark_cancle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignEnd="@+id/dialog_person_setremark_edit" android:layout_below="@+id/dialog_person_setremark_edit" android:layout_marginEnd="6dp" android:layout_marginLeft="@dimen/margin_size_25" android:layout_marginTop="28dp" android:background="@drawable/detail_community_add_bg" android:ems="6" android:gravity="center" android:paddingBottom="@dimen/margin_size_5" android:paddingLeft="@dimen/margin_size_20" android:paddingRight="@dimen/margin_size_20" android:paddingTop="@dimen/margin_size_5" android:text="取消" android:textColor="@color/bg_red" android:textSize="@dimen/font_size_15"/> <TextView android:id="@+id/dialog_person_setremark_ensure" android:layout_width="112.5dp" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/dialog_person_setremark_cancle" android:layout_alignBottom="@+id/dialog_person_setremark_cancle" android:layout_alignStart="@+id/dialog_person_setremark_edit" android:background="@drawable/detail_sub_bg" android:ems="6" android:gravity="center" android:paddingBottom="@dimen/margin_size_5" android:paddingLeft="@dimen/margin_size_20" android:paddingRight="@dimen/margin_size_20" android:layout_marginBottom="20dp" android:paddingTop="@dimen/margin_size_5" android:text="确定" android:textColor="@color/white" android:textSize="@dimen/font_size_15"/> </RelativeLayout><
调用方法
PersonSetRemarkDialog personSetRemarkDialog = new PersonSetRemarkDialog (getContext()); personSetRemarkDialog.setOnCertainButtonClickListener(new PersonSetRemarkDialog .OnCertainButtonClickListener() { @Override public void onCertainButtonClick(String remark) { ToastHelper.getInstance()._toast("success"); if (!remark.isEmpty()) { tv_personal_name.setText(remark); } } }); personSetRemarkDialog.show();
简单吧,使用的图片我就不传了,可以自己弄一个。
在说点额外的知识,调用的view(activity、fragment)是怎么获取焦点的呢?
WindowManager mWm = (WindowManager)getSystemService(Context.WINDOW_SERVICE); Button view = new Button(this); view.setText("window manager test!"); WindowManager.LayoutParams mParams = new WindowManager.LayoutParams(); mWm.addView(view, mParams);
我们这个button的显示和当前的运行环境基本上是无关的,当前是什么activity或者是桌面,使用这个底层的结果给你的编程带来很大的灵活性,但是要注意,显示出来就要销毁掉,这个是必须的,销毁其实就是一个remove。
但是仅仅这么写会有个问题,就是view显示在最上层,但是后面的view无法获得焦点,当你touch的坐标超出上次view的范围时
mParams = new WindowManager.LayoutParams(); mWm.updateViewLayout(view, mParams);
需要后面的view获得焦点时:
mParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; mWm.updateViewLayout(view, mParams);别忘了在AndroidManifest.xml中添加权限:
<uses-permissionandroid:name="android.permission.SYSTEM_ALERT_WINDOW"/>
public int flags;
行为选项/旗标,默认为 none .
下面定义了 flags 的取值:
不许获得焦点。
不能获得按键输入焦点,所以不能向它发送按键或按钮事件。那些时间将发送给它后面的可以获得焦点的窗口。此选项还会设置FLAG_NOT_TOUCH_MODAL选项。设置此选项,意味着窗口不能与软输入法进行交互,所以它的Z序独立于任何活动的输入法(换句话说,它可以全屏显示,如果需要的话,可覆盖输入法窗口)。要修改这一行为,可参考FLAG_ALT_FOCUSALBE_IM选项。
public static final int FLAG_NOT_FOCUSABLE = 0x00000008;
不接受触摸屏事件。
public static final int FLAG_NOT_TOUCHABLE = 0x00000010;
当窗口可以获得焦点(没有设置 FLAG_NOT_FOCUSALBE 选项)时,仍然将窗口范围之外的点设备事件(鼠标、触摸屏)发送给后面的窗口处理。否则它将独占所有的点设备事件,而不管它们是不是发生在窗口范围内。
public static final int FLAG_NOT_TOUCH_MODAL = 0x00000020;
另外一种情况
当请求布局时,你的窗口可能出现在状态栏的上面或下面,从而造成遮挡。当设置这一选项后,窗口管理器将确保窗口内容不会被装饰条(状态栏)盖住。public static final int FLAG_LAYOUT_INSET_DECOR = 0x00010000;
反转FLAG_NOT_FOCUSABLE选项。
如果同时设置了FLAG_NOT_FOCUSABLE选项和本选项,窗口将能够与输入法交互,允许输入法窗口覆盖;
如果FLAG_NOT_FOCUSABLE没有设置而设置了本选项,窗口不能与输入法交互,可以覆盖输入法窗口。
public static final int FLAG_ALT_FOCUSABLE_IM = 0x00020000;
如果你设置了FLAG_NOT_TOUCH_MODAL,那么当触屏事件发生在窗口之外事,可以通过设置此标志接收到一个MotionEvent.ACTION_OUTSIDE事件。注意,你不会收到完整的down/move/up事件,只有第一次down事件时可以收到ACTION_OUTSIDE。
public static final int FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000;
跟输入法的关系
7. public int softInputMode;
软输入法模式选项:
以下选项与 softInputMode 有关:
软输入区域是否可见。
public static final int SOFT_INPUT_MASK_STATE = 0x0f;
未指定状态。
public static final int SOFT_INPUT_STATE_UNSPECIFIED = 0;
不要修改软输入法区域的状态。
public static final int SOFT_INPUT_STATE_UNCHANGED = 1;
隐藏输入法区域(当用户进入窗口时)。
public static final int SOFT_INPUT_STATE_HIDDEN = 2;
当窗口获得焦点时,隐藏输入法区域。
public static final int SOFT_INPUT_STATE_ALWAYS_HIDDEN = 3;
显示输入法区域(当用户进入窗口时)。
public static final int SOFT_INPUT_STATE_VISIBLE = 4;
当窗口获得焦点时,显示输入法区域。
public static final int SOFT_INPUT_STATE_ALWAYS_VISIBLE = 5;
窗口应当主动调整,以适应软输入窗口。
public static final int SOFT_INPUT_MASK_ADJUST = 0xf0;
未指定状态,系统将根据窗口内容尝试选择一个输入法样式。
public static final int SOFT_INPUT_ADJUST_UNSPECIFIED = 0x00;
当输入法显示时,允许窗口重新计算尺寸,使内容不被输入法所覆盖。
不可与SOFT_INPUT_ADJUSP_PAN混合使用,如果两个都没有设置,系统将根据窗口内容自动设置一个选项。
public static final int SOFT_INPUT_ADJUST_RESIZE = 0x10;
输入法显示时平移窗口。它不需要处理尺寸变化,框架能够移动窗口以确保输入焦点可见。
不可与SOFT_INPUT_ADJUST_RESIZE混合使用;如果两个都没设置,系统将根据窗口内容自动设置一个选项。
public static final int SOFT_INPUT_ADJUST_PAN = 0x20;
当用户转至此窗口时,由系统自动设置,所以你不要设置它。
当窗口显示之后该标志自动清除。
public static final int SOFT_INPUT_IS_FORWARD_NAVIGATION = 0x100;
摘自网上的另一种实现,也贴出来。Android输入法弹出,设置控件在软键盘之上显示
/** * @param root 最外层布局,需要调整的布局 * @param scrollToView 被键盘遮挡的scrollToView,滚动root,使scrollToView在root可视区域的底部 */ private void controlKeyboardLayout(final View root, final View scrollToView) { // 注册一个回调函数,当在一个视图树中全局布局发生改变或者视图树中的某个视图的可视状态发生改变时调用这个回调函数。 root.getViewTreeObserver().addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { Rect rect = new Rect(); // 获取root在窗体的可视区域 root.getWindowVisibleDisplayFrame(rect); // 当前视图最外层的高度减去现在所看到的视图的最底部的y坐标 int rootInvisibleHeight = root.getRootView().getHeight() - rect.bottom; // 若rootInvisibleHeight高度大于100,则说明当前视图上移了,说明软键盘弹出了 if (rootInvisibleHeight > 100) { //软键盘弹出来的时候 int[] location = new int[2]; // 获取scrollToView在窗体的坐标 scrollToView.getLocationInWindow(location); // 计算root滚动高度,使scrollToView在可见区域的底部 int srollHeight = (location[1] + scrollToView.getHeight() + PixelUtil.dp2px(20, getContext())) - rect.bottom; if (srollHeight != 0){ root.scrollTo(0, srollHeight); } } else { // 软键盘没有弹出来的时候 root.scrollTo(0, 0); } } }); }
实例:在一开始的时候已经给出,这样就可以在调用输入发的时候,把view顶上去,而不是覆盖view
@Override public void show() { super.show(); //这样后边的view怎么获取焦点呢? 谁调用 谁就可以获取焦点 如下 // mParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; //mWm.updateViewLayout(view, mParams); getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager .LayoutParams.FLAG_ALT_FOCUSABLE_IM); getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); }
看了这篇文章收货很大,也引用了一部分,贴出来大家一起看。谢谢~
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1105/509.html
- Android透明背景Dialog、Dialog实现悬浮窗口 可与输入法交互,不被输入法覆盖
- Android dialog 强制弹出输入法
- Android背景透明的 Dialog
- Android背景透明的 Dialog
- Android背景透明的 Dialog
- android 对话框Dialog背景透明
- Android背景透明的 Dialog
- Android背景透明的 Dialog
- Android 透明背景的dialog
- android--对话框Dialog背景透明
- Android Dialog 设置背景透明
- android设置背景透明dialog
- 输入法dialog、window
- android 随记1 Dialog和输入法
- Android在dialog中如何隐藏输入法
- 安卓Dialog实现透明背景
- 实现背景透明,宽度可控的Dialog
- 安卓Dialog实现透明背景
- Android Studio使用svn配置忽略文件和解决提交时一直performing的问题
- UE4第二课 创建一个关卡和基本操作
- Editplus使用技巧集萃
- 【POJ 2524 Ubiquitous Religions】+ 并查集
- java微信公众号支付相关说明
- Android透明背景Dialog、Dialog实现悬浮窗口 可与输入法交互,不被输入法覆盖
- 腾讯好文!配色新人应该学会的6个色彩知识点
- jquery实现以原点为中心圆线上都是div圆
- Genymotion Error: Unable to load Virtualbox engine
- 图标网址
- 通过Bundle传递不同Intent之间的原始数据
- python爬取静态和动态网页
- 【云知道】春运火车票手速大比拼
- (c++)题目描述 求方程 的根,用三个函数分别求当b^2-4ac大于0、等于0、和小于0时的根,并输出结果。从主函数输入a、b、c的值。