问题描述
问题
试图模糊(而不是变暗)Dialog
的背景.
Tried to blur (not DIM) the background of a Dialog
.
和 FLAG_BLUR_BEHIND
已弃用.
方法是,从currant视图中截取屏幕截图并将其模糊.然后附加到背景,当AlertDialog
出现时,它就可以工作了.
Approach is, take a screenshot form the currant view and blur it.Then attach to the background,When AlertDialog
appears, and it works.
但是AlertDialog
总是在顶部而不在中心.(检查图像)
but AlertDialog
is always in the Top not in the center.(check the image)
WindowManager.LayoutParams
附加后无效.(附加到背景之前,alert 可以定位到中心,但附加后背景的模糊视图 AlertDialog
总是到顶部 )
WindowManager.LayoutParams
has no effect after attach .(before attach it to the background,alert can position to center, but after attaching the blur view to the background AlertDialog
always go to the top )
如何让我的提醒中心出现在屏幕上?
How can I make my alert center in the screen?
以下是我尝试过的代码,任何指南将不胜感激,
below is code i tried,any guide will be appreciated ,
按下返回时显示警报.
@Override
public void onBackPressed() {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this, R.style.AlertDialogCustom);
builder.setTitle("Lets Blur");
builder.setMessage("This is Blur Demo");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
dialog = builder.create();
// this position alert in the CENTER
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
WindowManager.LayoutParams wmlp = dialog.getWindow().getAttributes();
wmlp.gravity = Gravity.CENTER;
dialog.show();
new BlurAsyncTask().execute();
}
class BlurAsyncTask extends AsyncTask<Void, Integer, Bitmap> {
protected Bitmap doInBackground(Void...arg0) {
Bitmap map = AppUtils.takeScreenShot(MainActivity.this);
Bitmap fast = new BlurView().fastBlur(map, 10);
return fast;
}
protected void onPostExecute(Bitmap result) {
if (result != null){
final Drawable draw=new BitmapDrawable(getResources(),result);
Window window = dialog.getWindow();
// this position alert again in the TOP -- need to avoid that!
window.setBackgroundDrawable(draw);
window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
window.setGravity(Gravity.CENTER);
dialog.show();
}
}
其他类
AppUtils
public class AppUtils {
public static Bitmap takeScreenShot(Activity activity) {
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap b1 = view.getDrawingCache();
Rect frame = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
Display display = activity.getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height - statusBarHeight);
view.destroyDrawingCache();
return b;
}
}
模糊视图
public class BlurView {
public Bitmap fastBlur(Bitmap sentBitmap, int radius) {
Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
if (radius < 1) {
return (null);
}
int w = bitmap.getWidth();
int h = bitmap.getHeight();
int[] pix = new int[w * h];
Log.e("pix", w + " " + h + " " + pix.length);
bitmap.getPixels(pix, 0, w, 0, 0, w, h);
int wm = w - 1;
int hm = h - 1;
int wh = w * h;
int div = radius + radius + 1;
int r[] = new int[wh];
int g[] = new int[wh];
int b[] = new int[wh];
int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
int vmin[] = new int[Math.max(w, h)];
int divsum = (div + 1) >> 1;
divsum *= divsum;
int dv[] = new int[256 * divsum];
for (i = 0; i < 256 * divsum; i++) {
dv[i] = (i / divsum);
}
yw = yi = 0;
int[][] stack = new int[div][3];
int stackpointer;
int stackstart;
int[] sir;
int rbs;
int r1 = radius + 1;
int routsum, goutsum, boutsum;
int rinsum, ginsum, binsum;
for (y = 0; y < h; y++) {
rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
for (i = -radius; i <= radius; i++) {
p = pix[yi + Math.min(wm, Math.max(i, 0))];
sir = stack[i + radius];
sir[0] = (p & 0xff0000) >> 16;
sir[1] = (p & 0x00ff00) >> 8;
sir[2] = (p & 0x0000ff);
rbs = r1 - Math.abs(i);
rsum += sir[0] * rbs;
gsum += sir[1] * rbs;
bsum += sir[2] * rbs;
if (i > 0) {
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
} else {
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
}
}
stackpointer = radius;
for (x = 0; x < w; x++) {
r[yi] = dv[rsum];
g[yi] = dv[gsum];
b[yi] = dv[bsum];
rsum -= routsum;
gsum -= goutsum;
bsum -= boutsum;
stackstart = stackpointer - radius + div;
sir = stack[stackstart % div];
routsum -= sir[0];
goutsum -= sir[1];
boutsum -= sir[2];
if (y == 0) {
vmin[x] = Math.min(x + radius + 1, wm);
}
p = pix[yw + vmin[x]];
sir[0] = (p & 0xff0000) >> 16;
sir[1] = (p & 0x00ff00) >> 8;
sir[2] = (p & 0x0000ff);
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
rsum += rinsum;
gsum += ginsum;
bsum += binsum;
stackpointer = (stackpointer + 1) % div;
sir = stack[(stackpointer) % div];
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
rinsum -= sir[0];
ginsum -= sir[1];
binsum -= sir[2];
yi++;
}
yw += w;
}
for (x = 0; x < w; x++) {
rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
yp = -radius * w;
for (i = -radius; i <= radius; i++) {
yi = Math.max(0, yp) + x;
sir = stack[i + radius];
sir[0] = r[yi];
sir[1] = g[yi];
sir[2] = b[yi];
rbs = r1 - Math.abs(i);
rsum += r[yi] * rbs;
gsum += g[yi] * rbs;
bsum += b[yi] * rbs;
if (i > 0) {
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
} else {
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
}
if (i < hm) {
yp += w;
}
}
yi = x;
stackpointer = radius;
for (y = 0; y < h; y++) {
// Preserve alpha channel: ( 0xff000000 & pix[yi] )
pix[yi] = ( 0xff000000 & pix[yi] ) | ( dv[rsum] << 16 ) | ( dv[gsum] << 8 ) | dv[bsum];
rsum -= routsum;
gsum -= goutsum;
bsum -= boutsum;
stackstart = stackpointer - radius + div;
sir = stack[stackstart % div];
routsum -= sir[0];
goutsum -= sir[1];
boutsum -= sir[2];
if (x == 0) {
vmin[y] = Math.min(y + r1, hm) * w;
}
p = x + vmin[y];
sir[0] = r[p];
sir[1] = g[p];
sir[2] = b[p];
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
rsum += rinsum;
gsum += ginsum;
bsum += binsum;
stackpointer = (stackpointer + 1) % div;
sir = stack[stackpointer];
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
rinsum -= sir[0];
ginsum -= sir[1];
binsum -= sir[2];
yi += w;
}
}
Log.e("pix", w + " " + h + " " + pix.length);
bitmap.setPixels(pix, 0, w, 0, 0, w, h);
return (bitmap);
}
}
屏幕截图 - 这是我得到的结果 - 我想制作警报中心,但它保持在顶部
screen shot - this is the result i get- i want to make alert center but it stays on top
答案的概念
- 截屏
- 以编程方式为该屏幕截图设置动画/模糊/任何效果
- 使用没有任何内容的对话框获取 currant 窗口
- 附上带有效果的屏幕截图
- 显示我想显示的真实视图
旁注:这可用于附加任何类型的背景!blur..dim..bright.. 只需添加接受位图并返回位图的正确方法,并在 BlurView
类中更改您想要的更改.我加了一个模糊的.
Side Note: This can be used to attach any type of a background! blur.. dim..bright.. Just add the right method that accept a bitmap and return a bitmap with changes you want in BlurView
class. I added a blur one.
推荐答案
注意: 这个屏幕背景可以是你拥有的任何东西,它的作用是截取它并最终模糊它将其设置为带有模糊效果的 alertDialog
背景
Note: This screen background can be anything you have on it, what it does is take a screenshot of it and blur that finally set it as the background of the alertDialog
with blur effect
问题是 alertDialog
附加的模糊背景总是在顶部,我无法改变它.
Problem was alertDialog
attached with that blur background was always on the top and i couldn't change that.
我想出了这个解决方案.
I came up with this solution.
我不得不使用两个 alertDialogs
一个是模糊效果(用于getWindow()
),现在没有显示(我去掉了它的setContentView
/可以使用透明背景)
I had to use two alertDialogs
one is for the blur effect(for the use of getWindow()
) and it does not get display now(I removed its setContentView
/ can use transparent background)
另一个是在模糊效果后显示的真实警告对话框.
The other one is the real alert dialog got display after the blur effect.
主活动
public class MainActivity extends AppCompatActivity {
private AlertDialog dialogWhichDisplayAlert;
private Dialog fakeDialogUseToGetWindowForBlurEffect;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void onBackPressed() {
fakeDialogUseToGetWindowForBlurEffect = new Dialog(MainActivity.this);
// fakeDialogUseToGetWindowForBlurEffect.setContentView(R.layout.fakealert); // removed the content so not visible
new BlurAsyncTask().execute();
}
class BlurAsyncTask extends AsyncTask<Void, Integer, Bitmap> {
protected Bitmap doInBackground(Void...arg0) {
Bitmap map = AppUtils.takeScreenShot(MainActivity.this);
Bitmap fast = new BlurView().fastBlur(map, 10);
return fast;
}
protected void onPostExecute(Bitmap result) {
if (result != null){
final Drawable draw=new BitmapDrawable(getResources(),result);
Window window = fakeDialogUseToGetWindowForBlurEffect.getWindow();
window.setBackgroundDrawable(draw);
window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
window.setGravity(Gravity.CENTER);
fakeDialogUseToGetWindowForBlurEffect.show();
// real one
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this, R.style.AlertDialogCustom);
builder.setTitle("Lets Blur");
builder.setMessage("This is Blur Demo");
builder.setCancelable(false);
builder.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
fakeDialogUseToGetWindowForBlurEffect.dismiss();
dialog.cancel();
}
});
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
fakeDialogUseToGetWindowForBlurEffect.dismiss();
dialog.cancel();
}
});
dialogWhichDisplayAlert = builder.create();
// position real dialogWhichDisplayAlert using Gravity.CENTER;
dialogWhichDisplayAlert.requestWindowFeature(Window.FEATURE_NO_TITLE);
WindowManager.LayoutParams wmlp = dialogWhichDisplayAlert.getWindow().getAttributes();
wmlp.gravity = Gravity.CENTER;
dialogWhichDisplayAlert.show();
}
}
}
}
[使用的其他类与问题相同]
[other classes used are same as the question]
风格
<style name="AlertDialogCustom" parent="@android:style/Theme.Dialog">
<item name="android:textColor">#00FF00</item>
<item name="android:typeface">monospace</item>
<item name="android:textSize">10sp</item>
</style>
输出
这篇关于位置中心带有模糊背景的 AlertDialog的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!