草庐IT

android - 抽屉导航的模糊背景

coder 2023-11-29 原文

我将如何在抽屉导航上创建实时模糊,以便当您拉出抽屉时,列表的背景是其后面显示的 fragment 的模糊背景?

我看过但主要是发现 BitMap 模糊,没有任何东西是活的。

最佳答案

该过程涉及以下阶段:

  1. 获取整个抽屉布局的快照。
  2. 将其裁剪为您的菜单的确切大小。
  3. 将它缩小很多(8 倍就很好)。
  4. 模糊该图像。
  5. 有一个自定义 View ,在您的菜单显示位置的正后方显示图像的一部分。
  6. 当您滑动抽屉时,会显示该图片的较大部分。

这是一个代码示例(全部在 BlurActionBarDrawerToggle 和 BlurAndDimView 中完成):

public class BlurActionBarDrawerToggle extends ActionBarDrawerToggle {

    private static final int DOWNSAMPLING = 8;

    private final DrawerLayout drawerLayout;
    private final BlurAndDimView blurrer;
    private Bitmap drawerSnapshot;
    private final ColorDrawable imageBackgroundDrawable;

    public BlurActionBarDrawerToggle(Activity activity, DrawerLayout drawerLayout, int drawerImageRes, int openDrawerContentDescRes, int closeDrawerContentDescRes, BlurAndDimView blurrer) {
        super(activity, drawerLayout, drawerImageRes, openDrawerContentDescRes, closeDrawerContentDescRes);

        //this should be roughly the same color as your window background
        imageBackgroundDrawable = new ColorDrawable(activity.getResources().getColor(R.color.dark_blue_2));
        this.drawerLayout = drawerLayout;
        this.blurrer = blurrer;
    }

    @Override
    public void onDrawerSlide(final View drawerView, final float slideOffset) {
        super.onDrawerSlide(drawerView, slideOffset);
        if (slideOffset > 0.0f) {
            setBlurAlpha(slideOffset);
        } else {
            clearBlurImage();
        }
    }

    @Override
    public void onDrawerClosed(View view) {
        clearBlurImage();
    }

    private void setBlurAlpha(float slideOffset) {
        if (!blurrer.hasImage()) {
            setBlurImage();
        }
        blurrer.handleScroll(slideOffset);
    }

    public void setBlurImage() {
        blurrer.setVisibility(View.VISIBLE);
        drawerSnapshot = drawViewToBitmap(drawerSnapshot, drawerLayout, DOWNSAMPLING, imageBackgroundDrawable);
        blurrer.setImage(drawerSnapshot, DOWNSAMPLING);
    }

    public void clearBlurImage() {
        blurrer.clearImage();
        blurrer.setVisibility(View.INVISIBLE);
    }

    private Bitmap drawViewToBitmap(Bitmap dest, View view, int downSampling, Drawable background) {
        float scale = 1f / downSampling;
        int viewWidth = view.getWidth();
        int viewHeight = view.getHeight();
        int bmpWidth = (int) (viewWidth * scale);
        int bmpHeight = (int) (viewHeight * scale);
        if (dest == null || dest.getWidth() != bmpWidth || dest.getHeight() != bmpHeight) {
            dest = Bitmap.createBitmap(bmpWidth, bmpHeight, Bitmap.Config.ARGB_8888);
        }
        Canvas c = new Canvas(dest);
        background.setBounds(new Rect(0, 0, viewWidth, viewHeight));
        background.draw(c);
        if (downSampling > 1) {
            c.scale(scale, scale);
        }

        view.draw(c);
        view.layout(0, 0, viewWidth, viewHeight);
        return dest;
    }
}

BlurAndDim View 模糊菜单下方的部分,并使其余部分变暗(您可以调整数字以获得您想要的确切效果):

public class BlurAndDimView extends View {

    private static final int BLUR_RADIUS = 4;
    private static final int BLUE_ALPHA = 178;
    private static final int MAX_DIM_ALPHA = 127;
    private Paint bitmapPaint;
    private Paint dimPaint;
    private Paint blueSemiTransparentPaint;
    private int menuWidth;
    private int titleHeight;

    private Bitmap image;
    private Rect rectDst;
    private Rect rectSrc;
    private int downSampling;
    private Rect rectRest;

    public BlurAndDimView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        postConstruct();
    }

    public BlurAndDimView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
        postConstruct();
    }

    public BlurAndDimView(Context context) {
        this(context, null);
        postConstruct();
    }

    private void postConstruct() {
        bitmapPaint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
        dimPaint = new Paint();
        blueSemiTransparentPaint = new Paint();
        //You might want to also have a semitransparent overlay over your blurred image, since you can't control what's behind your menu.
        blueSemiTransparentPaint.setColor(getResources().getColor(R.color.dark_blue));
        blueSemiTransparentPaint.setAlpha(BLUE_ALPHA);
        menuWidth = getResources().getDimensionPixelSize(R.dimen.browse_menu_width);
    }
}

    @Override
    protected void onDraw(Canvas canvas) {
        if (image != null) {
            canvas.drawBitmap(image, rectSrc, rectDst, bitmapPaint);
            canvas.drawRect(rectDst, blueSemiTransparentPaint);
            canvas.drawRect(rectRest, dimPaint);
        }
    }

    public void handleScroll(float xOffset) {
        if(image != null) {
            rectSrc.right = (int) (image.getWidth() * xOffset);
            rectDst.right = rectSrc.right * downSampling;
            rectRest.left = rectDst.right;
            dimPaint.setAlpha((int) (xOffset * MAX_DIM_ALPHA));
            invalidate();
        }
    }

    public void setImage(Bitmap bmp, int downSampling) {
        Bitmap cropped = Bitmap.createBitmap(bmp, 0, 0, menuWidth / downSampling, getHeight() / downSampling);
        this.image = Blur.blur(getContext(), cropped, BLUR_RADIUS);
        rectSrc = new Rect(0, 0, bmp.getWidth(), bmp.getHeight());
        rectDst = new Rect(0, 0, menuWidth, getHeight());
        rectRest = new Rect(menuWidth, 0, getWidth(), getHeight());
        this.downSampling = downSampling;
        invalidate();
    }

    public boolean hasImage() {
        return image != null;
    }

    public void clearImage() {
        image = null;
    }
}

对于良好的模糊算法(尽可能使用 Renderscript),您可以使用 this .

布局应该是这样的:

<android.support.v4.widget.DrawerLayout
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <android.support.v4.widget.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <com.bla.bla.BlurAndDimView
        android:id="@+id/blurrer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="?android:attr/actionBarSize"
        android:visibility="invisible" />

    <ListView
        android:id="@+id/menu_list"
        android:layout_width="@dimen/browse_menu_width"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice" />
</android.support.v4.widget.DrawerLayout>

关于android - 抽屉导航的模糊背景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21840916/

有关android - 抽屉导航的模糊背景的更多相关文章

  1. ruby-on-rails - 使用 Sublime Text 3 突出显示 HTML 背景语法中的 ERB? - 2

    所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择

  2. ruby-on-rails - 使用 Rmagick 或 ImageMagick 在背景上放置标题 - 2

    我有一张背景图片,我想在其中添加一个文本框。我想弄清楚如何将标题放置在其顶部的正确位置。(我使用标题是因为我需要自动换行功能)。现在,我只能让文本显示在左上角,但我需要能够手动定位它的开始位置。require'RMagick'require'Pry'includeMagicktext="Loremipsumdolorsitamet"img=ImageList.new('template001.jpg')img 最佳答案 这是使用convert的ImageMagick命令行的答案。如果你想在Rmagick中使用这个方法,你必须自己移植

  3. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  4. ruby-on-rails - 在 Rails 3 中向 Active Admin 添加全局导航项的最佳方法是什么 - 2

    我正在尝试将全局导航菜单项添加到我的ActiveAdmin安装(在“仪表板”导航按钮旁边)。ActiveAdmin说这在他们的网站上是可能的,但他们没有任何关于如何实现它的文档。有谁知道如何做到这一点?编辑:抱歉,我应该更清楚。我想添加一个指向由任意文本/链接对组成的全局导航的链接。IE,如果我想添加一个链接到http://google.com在事件管理员的全局导航中使用文本“Google”,我将如何实现? 最佳答案 ActiveAdmin.register_page"Google"domenu:priority=>1,:label

  5. ruby-on-rails - 使用 Rails (Tire) 和 ElasticSearch 进行模糊字符串匹配 - 2

    我有一个Rails应用程序,现在设置了ElasticSearch和Tiregem以在模型上进行搜索,我想知道我应该如何设置我的应用程序以对模型中的某些索引进行模糊字符串匹配。我将我的模型设置为索引标题、描述等内容,但我想对其中一些进行模糊字符串匹配,但我不确定在何处进行此操作。如果您想发表评论,我将在下面包含我的代码!谢谢!在Controller中:defsearch@resource=Resource.search(params[:q],:page=>(params[:page]||1),:per_page=>15,load:true)end在模型中:classResource'Us

  6. Ruby:模糊测试所有 unicode 字符(UTF8/编码/字符串操作) - 2

    我无法遍历整个unicode字符范围。我到处找...我正在构建一个模糊器,并希望将所有unicode字符(一次一个)嵌入到一个url中。例如:http://www.example.com?a=\uff1c我知道有一些内置工具,但我需要更多的灵active。如果我能像下面那样做:"\u"+"ff1c"那就太好了。这是我得到的最接近的:char="\u0000"...#withiniterationchar.succ!...但在字符"\u0039"之后,即数字9,我将得到"10"而不是":" 最佳答案 您可以使用pack将数字转换为UT

  7. ruby-on-rails - 在所有页面上使用 Prawn 的背景图像 - 2

    我在View中有这段代码prawn_document(:page_size=>"A4",:top_margin=>80,:bottom_margin=>40,:background=>"public/uploads/1.png")do|pdf|creation_date=Time.now.strftime('%d-%m-%Y')posts=@posts.eachdo|post|pdf.pad(10)dopdf.textpost.titlepdf.textpost.textendendpdf.page_count.timesdo|i|pdf.go_to_page(i+1)pdf.draw

  8. 千耘农机导航的“星地一体”能力究竟是什么? - 2

    伴随农业机械化和智能化的发展,越来越多的人开始使用农机自动驾驶系统助力耕作,千耘农机导航的“星地一体”能力可有效解决信号受限的问题,实现作业提效。究竟什么是“星地一体”,又是如何解决智能化农机作业的痛点的?下面为大家揭秘。农机效率通常受限于通信网络目前虽然我国通讯网络的人口覆盖率达到99%,但地面移动通讯网络覆盖率仍小于国土面积的40%,而很多农田所在区域恰是山区、戈壁滩等偏远地区。两省交界地也会出现通信信号不稳定的状况;而国内大部分农机自动驾驶系统非常依赖通信网络,当通信网络弱的时候会出现系统掉线的现象,必须得携带小基站才能正常使用,极为繁琐。Q:什么是千耘农机导航“星地一体”能力?A:是星

  9. ruby - 256 种颜色,前景和背景 - 2

    这是两个脚本的故事,与previousquestion有关.这两个脚本位于http://gist.github.com/50692.ansi.rb脚本在所有256种背景颜色上显示所有256种颜色。ncurses.rb脚本显示所有256种前景颜色,但背景显示基本的16种颜色,然后似乎循环显示各种属性,如闪烁和反向视频。那么是什么给了?这是ncurses中的错误,它使用带符号的整数来表示颜色对吗?(即'tputcolors'表示256但'tputpairs'表示32767而不是65536)似乎如果是这种情况,颜色对的前半部分会正确显示但后半部分会重复或进入属性作为int包裹。

  10. ruby 电子表格行背景色 - 2

    我正在尝试使用“电子表格”解析Excel电子表格。如何获取每一行的背景颜色? 最佳答案 book=Spreadsheet::Workbook.newsheet=book.create_worksheet:name=>'Name'format=Spreadsheet::Format.new:color=>:blue,:pattern_fg_color=>:yellow,:pattern=>1sheet.row(0).set_format(0,format)#forfirstcellinfirstrow或sheet.row(0).def

随机推荐