这一篇博文的思路很简单,没有什么深入的理论,源由是最近在实习公司里开发用到了Android O的通知,发现与以往有所不同,相关的资料是有,但是大部分都不适用于这个版本,这里只是写一个非常简单的Demo,算是代码的保存吧。另外,为什么一个自定义View要和通知弄一起说呢,是因为本想在这个通知上用上一个自定义的View,结果发现,通知是不支持自定义View 的。

具体通知的知识点,网上有很多,这里不再缀述。

Android O的通知与以往最大的不同,在于增加的频道这个概念,所以,在这个版本,倘若,不加入频道,以之前的方式去控制通知,就会弹出以下的错误(弹出一个Toast :Developer warning for package):

所以和以往的最大不同就在此,其他的设置,具体看一下api测试即可。

说一说自定义通知,自定义通知当然是个创建一个布局文件,然后根据布局文件加载到通知即可。方法是通过创建一个RemoteViews,调用RemoteViews的一系列方法,通过传入View控件的id,及相对应的值,即可完成设置,这个过程也非常简单。代码如下:

Ps:一定要设置setSmallIcon,否则不能显示。

         notificationManager=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);NotificationChannel mChannel=new NotificationChannel("my_channel_01","123",NotificationManager.IMPORTANCE_LOW);mChannel.setDescription("123456");mChannel.enableLights(false);notificationManager.createNotificationChannel(mChannel);builder=new Notification.Builder(this).setSmallIcon(R.mipmap.ic_launcher);             //一定要设置,不然不能够弹出RemoteViews remoteViews=new RemoteViews(getPackageName(),R.layout.notification_layout);remoteViews.setTextViewText(R.id.down_tv,"正在下载");remoteViews.setProgressBar(R.id.pb,100,50,false);builder.setCustomBigContentView(remoteViews);btn_notification=(Button)findViewById(R.id.btn_notification);btn_notification.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {notificationManager.notify(nofitication_id,builder.build());}});

另外,假若你设置了进度条,然后又看不见效果,请注意有没有设置其margin值,有些时候是会被其他的通知给盖住的。至于进度条的样式,可以通过设置其Style或者Theme标签达到想到的效果,如:

style="?android:attr/progressBarStyleHorizontal"

本来想在通知上加下一个自定义控件,不过一加上去就报了错误,查了一下资料,才得知,原来自定义的通过是加不了自定义控件的。

这个自定义控件的需求是,传入四张图片,然后可以根据控件的大小去自动调整图片的显示大小,同时对图片的大小进行相对应比例的切割,同时再对图片进行压缩,达到内存调优的效果。

自定义控件好的教程也是非常多,我这里简单地叙述一下自己的实战经历。

首先,继承View,然后重写一个含AttributeSet的方法,这个方法似乎是必须,当然这个还要用到自定义属性,方法就是在attrs.xml里进行定义即可,具体看其他教程。这里获得用户传入的资源文件:

 <com.example.jakera.notificationtest.FourImageViewandroid:layout_width="match_parent"android:layout_height="match_parent"app:ImageView1="@mipmap/timg"app:ImageView2="@mipmap/timg1"app:ImageView3="@mipmap/timg3"app:ImageView4="@mipmap/timg4"android:background="#269194"/>

TypedArray ta=context.obtainStyledAttributes(attrs,R.styleable.FourImageView);

        imageView1=ta.getResourceId(R.styleable.FourImageView_ImageView1,R.drawable.ic_launcher_background);imageView2=ta.getResourceId(R.styleable.FourImageView_ImageView2,R.drawable.ic_launcher_background);imageView3=ta.getResourceId(R.styleable.FourImageView_ImageView3,R.drawable.ic_launcher_background);imageView4=ta.getResourceId(R.styleable.FourImageView_ImageView4,R.drawable.ic_launcher_background);

由于onMeasure方法,我们不需要对View的测量作什么处理,这里不重写。

最重要的当然是onDraw方法,这里我是直接根据用户传入的View大小,计算出每个View的大小,及相对应的间隔。当然,后期应该考虑到可拓展性,应该通过image的个数来计算。

        int viewWidth=(getWidth()/51)*25;int viewWidthSpan=getWidth()/51;int viewHeight=(getHeight()/51)*25;int viewHeightSpan=getHeight()/51;

根据上边的imageview,及View的大小来进行绘制。Rect封装了View的大小。通过计算能够把四张图张按田字格绘制出来。

        Rect mDestRect1=new Rect(0,0,viewWidth,viewHeight);canvas.drawBitmap(getBitmap(imageView1,viewHeight,viewWidth),null,mDestRect1,null);Rect mDestRect2=new Rect(viewWidth+viewWidthSpan,0,getWidth(),viewHeight);canvas.drawBitmap(getBitmap(imageView2,viewHeight,viewWidth),null,mDestRect2,null);Rect mDestRect3=new Rect(0,viewHeight+viewHeightSpan,viewWidth,getHeight());canvas.drawBitmap(getBitmap(imageView3,viewHeight,viewWidth),null,mDestRect3,null);Rect mDestRect4=new Rect(viewWidth+viewWidthSpan,viewHeight+viewHeightSpan,getWidth(),getHeight());canvas.drawBitmap(getBitmap(imageView4,viewHeight,viewWidth),null,mDestRect4,null);

上边的代码调用一个方法,这个方法是作用是,由于我们传入的图片形状不一,假若不进行处理,会出现一个问题,就是图片会在某个方向上被拉伸,显得特别不友好。另一个问题是,我们要把图片放到一个小小的View里边,应该做一下压缩处理,不用把大图加载到内存去。

一开始图方便,在网上找了许多的代码段,发现很多代码都不适用,有些可以用,但是可能在某些情况下,还是存在拉伸问题,比如当View的宽>长时,可以使用,但是反过来长>宽时不行,捣鼓了大半天,还是没能弄好,索性自己耐下心下来做分析计算,结果还花不了半个小时就完成了。其实也简单,就是一些简单的数学计算。

思路,首先,根据View要显示图片大小的比例,去切割自己的图片,切割自己的图片要求:按比例切,然后把这个最大的切割区域移动图片中心,即得到图片的中心位置。

下图为当W/r<h的情况,即切割不会超出图片边界,则宽度保持不变,而高度截出nh的高度,居中也很简单,由于宽度不变,则水平不需偏移,则rX=0;而y的偏移,则为(h-需要截出的高度再除以2)即可。这样便可以截出。

l表示想要设置view的宽度,s表示想要设置View的高度,w即为图片宽度,h图片高度rX 水平方向的偏移量,rY垂直方向偏移量。r为宽高比。nh图片切割后的高度,nw图片切割后的宽度。

同理,还有一种情况是,当w除以比率得到的新高超出图片高度时,即得换得高度去乘以比率来获得新的宽度。分析图如下:

好的,整个分析就这样,代码如下:

public Bitmap getBitmap(int path,int height,int width){Bitmap srcBitmap=BitmapFactory.decodeResource(getResources(),path);int w = srcBitmap.getWidth(); // 得到图片的宽,高int h = srcBitmap.getHeight();int retX, retY;int nw, nh;if (w > h * width / height){nh = h;nw = h * width / height;retY = 0;retX = (w - nw) / 2;} else{nh = w * height / width;nw = w;retY = (h - nh) / 2;retX = 0;}
//在这里切割图片
Bitmap bmp = Bitmap.createBitmap(srcBitmap, retX, retY, nw, nh, null,false);// 如果是放大图片,filter决定是否平滑,如果是缩小图片,filter无影响,我们这里是缩小图片,所以直接设置为false
//这里压缩图片至相应大小。
Bitmap dst = Bitmap.createScaledBitmap(bmp, width, height, false);if (srcBitmap != dst) { // 如果没有缩放,那么不回收srcBitmap.recycle(); // 释放Bitmap的native像素数组}bmp.recycle();     //记得回收srcBitmap.recycle();return dst;}

测试控件的适配性能,原图两张长>宽,两张宽>长:

小图:

大图:

高>宽:

宽>高:

好了,一个自定义的通知,以及一个自定义的田字格显示图片的View制作而成,当然后期可以再拓展开发,如QQ的九宫格显示等等。

这个通知也好,控件也罢,都挺简单的,但是真正去写它,还是花了一些时间,特别是在处理图片这一块。另外,我现在有了一个小小的心得,遇到问题,不要一味地去依赖网上的答案,静下心来想一想,其实自己的解决方案说不定更赞。

加油,共勉。

Android O 自定义通知实例及一个自定义自动适配缩放图片至特定大小的田字格ImageView相关推荐

  1. java自定义窗口_Java-创建一个自定义窗口,扁平化界面

    众所周知,Java的默认窗口使用的是系统默认样式,那么我们如何自己定义样式使其更好看呢?下面我就来分享一下如何自定义样式. 效果: 首先准备好我们的背景,按钮贴图: 然后开始. 先创建两个图片对象,把 ...

  2. Android端与PC端同步绘画板(二)-适配手机和PC屏幕大小

    前言 关于手机端与PC端如何建立通讯,请参考: Android端与PC端同步绘画板(一)-使用Socket建立连接 这篇文章我们来简单说一下关于手机端和PC端的屏幕适配问题,因为我们都知道因为Andr ...

  3. 获取手机通讯录联系人(包含模糊查询,dialog自定义,也有一个自定义通知栏)

    这里还有一个联系人类: package com.example.sendmsg;import android.graphics.Bitmap;public class ContactEntity {/ ...

  4. vue自定义组件html,Vue自定义组件(简单实现一个自定义组件)

    在用vue构建项目的过程中,我们有时会用到别人开发的组件如vue-router:使用他人组件的正常步骤如下: 1.命令行进行安装,执行install: 2.在vue项目中的入口文件main.js中,进 ...

  5. android简单阅读app实例,PureRead 一个简单而精致的轻量级碎片化阅读App

    这是基于Flutter开发的碎片化阅读App,dd级作品,欢迎初学者学习 hxdm,过来康康啊! 主要使用的库 cached_network_image,图片缓存加载库 provider,对Widge ...

  6. Android笔记(二十四):gradle写一个android12自动适配exported脚本,支持aab

    背景 由于Google play的政策,提审aab的时候需要适配android12,适配android12最大的工作就是在AndroidManifesst.xml文件中声明的四大组件,都要显式声明ex ...

  7. 安卓android按宽/高缩放图片到指定大小并进行裁剪得到中间部分图片

    /*** 按宽/高缩放图片到指定大小并进行裁剪得到中间部分图片 <br>* 方 法 名:zoomBitmap <br>* 创 建 人:楼翔宇 <br>* 创建时间: ...

  8. android 广告效果图,Android_Android实现加载广告图片和倒计时的开屏布局,这是一个android开屏布局的实例 - phpStudy...

    Android实现加载广告图片和倒计时的开屏布局 这是一个android开屏布局的实例,可以用于加载广告图片和倒计时的布局.程序中设置的LayoutParams,划分额外空间比例为6分之5,具体权重比 ...

  9. 怎么写一个文章自动生成器-免费的文章生成器下载

    怎么写一个文章自动生成器 写一个文章自动生成器需要具备一些特定的技术和编程能力,主要包括以下几个步骤: 数据收集:为了训练 AI 文章生成器,需要收集大量的文章数据,可以通过爬虫程序从互联网上收集数据 ...

最新文章

  1. 银行卡为何要使用ISO8583格式
  2. 原型设计工具【收集转帖】
  3. Spring事务失效 -方法内部调用
  4. Anaconda3+Python3.6搭建Tensorflow
  5. SCPPO(二):禅道的使用—管理员
  6. hibernate 批量插入 Batch
  7. 阶段5 3.微服务项目【学成在线】_day01 搭建环境 CMS服务端开发_13-MongoDb入门-数据库和集合...
  8. Windows中cmd命令启动Oracle数据
  9. 人脸识别 face_recognition
  10. matlab求合同矩阵,matlab-线性代数 判断 合同矩阵
  11. 关于MacOS降系统版本的处理方法
  12. 基础js实现下雨效果(超简单)
  13. PYNQ-z2的学习过程
  14. .NetCore微信支付+服务商模式(saas)
  15. [编程题] 创造新世界
  16. 多光纤推接 (MPO) 连接器
  17. linux以长格式显示文件名,linux怎样以长格式显示用户目录下所有文件
  18. OGeek网络安全挑战赛圆满收官,OPPO倾力培养高校尖端人才
  19. 数据结果出来了!公众号批量伪原创文章群发霸屏与公众号排名被动引流
  20. 搜狗浏览器打开的网页ico图标不显示

热门文章

  1. Dev C++ 英文模式改成中文模式
  2. 常用的logo设计技巧
  3. 夫妻卖盲盒、年入16亿,揭秘泡泡玛特的暴利生意
  4. 5G无线技术基础自学系列 | 双工技术
  5. 如何在模拟器中测试Windows Phone 8的NFC应用
  6. Oracle 考试题 答案
  7. 【工具】VScode|Linux 中怎么调试 Python 项目比较方便?又名 VScode 怎么调试 Python 项目(兼容环境Ubuntu18.04)
  8. Outlook 阿里邮箱 重复收取邮件 的情况 及解决方案
  9. 网状结构(图)图的存储(邻接矩阵、邻接表)、图的遍历(深度DFS、广度BFS)、图的最短路径
  10. 计算机wps是什么意思啊,路由器WPS是什么意思?