首页 文章 精选 留言 我的

精选列表

搜索[不可见索引],共10000篇文章
优秀的个人博客,低调大师

稳赚不赔~Spark社区招募志愿者!

首先了解下这是个什么组织 Apache Spark是大数据方面最大的开源社区之一,拥有来自250多个组织的超过1000个贡献者,以及遍布全球570多个地方的超过30万个Spark Meetup社区成员。 在中国,阿里云计算平台EMR团队组织了为国内Spark开发者服务的Spark中国技术交流社区,运营了专门的社群、技术圈和公众号Apache Spark技术交流社区,用于分享和交流Spark相关信息。目前我们完全公益的服务于超过1w的国内开发者。这中间也得到了国内外的互联网大厂,举个栗子:Databricks,领英,蚂蚁金服,Intel等多家技术团队的支持。感兴趣微信关注公众号了解 Spark社区招募志愿者 活儿少礼多: 送书送衣服送杯子送水壶送书包送贴纸送门票送鼠标垫送公仔 但凡是 Spark 社区周边都!可!以!(别的社区周边我也可以去偷点) 送大佬微信送大佬钉钉号送线下活动前排位置送不打码资源送一手招聘信息送简历绿色通道送劲爆八卦 按劳送礼,多劳多得,绝对公平。 也就是整理整理稿子,排排版,有活动时协助维持一下纪律。 可能是21世纪唯一不看颜值只看人品的招募。 有兴趣加志愿打工钉钉群: 开业活动:第5名,第15名,第25名,第35名进群的兄弟直接发红包

优秀的个人博客,低调大师

做SaaS不赚钱?先想清楚这5个问题

即将开播:5月14日,Jenkins在K8S下的三种部署流程和实战演示 1、你的SaaS打算怎么赚钱 在中国做SaaS没定力不行。因为每隔一段时间,SaaS就被推断要爆发,然后就又进入低谷,能做到气定神闲着实不易。 在底部待久了,现在又开始怀疑和自我怀疑,SaaS到底能不能赚到钱? 不管这是不是焦虑,都请相信:赚到钱的继续努力,没赚到的也莫慌。这不是鸡汤,而是态度。 你看市值近200亿美金的Slack不是也还没盈利嘛,还上亿美金的亏着呢。再看SaaS的灯塔、市值1000多亿美金的Salesforce,干了20多年了也才开始盈利,而且赢的也不算多,人家慌了吗? 所以,一家SaaS公司是不是个好公司、未来有没有盈利能力,甚至能不能活到真正赚钱那天,这些事都不能简单地用当前是否赚了钱来衡量。 实际上,财务报表上并没有“赚钱”这回事,有盈利未必就赚到钱,没盈利也有可能赚了钱。 倒是有其它几个指标,能比较好地刻画一家SaaS公司的优劣。它们是毛利率,净利率、订阅收入占比、收入增速和收入净留存(NDR),下表摘录了2019年底几家美股SaaS公司的相关数据,看看赚钱的SaaS公司都长啥样。公司毛利率净利率订阅收入占比NDR 不管怎么说,SaaS作为一个生意,赚钱那是必须的,但不一定就是现在。 中国的SaaS公司还有很多比赚钱更重要的事要做。这些事情没想清楚和问题没解决,不但现在赚不到钱,未来赚钱也够呛。 说句题外话,大部分中国的SaaS公司,目前该焦虑的不是赚钱问题,而应该是现金流问题;只有活到真正赚钱的那一天,才是最重要的。 2.SaaS有没有机会赚钱 一个生意的初期,最关注的是有没有市场机会。 当前大部分国内SaaS没赚钱,很多人都怀疑是市场机会问题,至少是当下的机会不多。 我们看到,全球SaaS市场规模已达1000亿美元,在软件市场中占比约22%;无疑SaaS已经成为整个软件产业持续发展的核心支撑。 再往远期看,行业潜在市场空间(TAM)也非常的大。美股大部分上市SaaS公司,其核心业务对应市场空间在百亿~千亿美元之间。例如,Salesforce、ServiceNow等公司对应的TAM均超过1000亿美元。 全球绝大部分优质的SaaS公司都在美国市场,合计市值达数万亿美元,市值超过100亿美元的SaaS企业就超过50家。 这种情况下,投资美国SaaS已经变得很贵,中国自然就成了SaaS投资的优秀市场。从这个角度看,中国的SaaS是资本驱动的。 但是,数年过去,无论是整体增速,还是IPO数量,中美SaaS的差距还非常大。也正是因为这个巨大的差距,对中国SaaS市场产生了疑问。 无论目前国内市场怎样,我们都必须看到:经济和产业链的全球化,ToB SaaS在不同国家或区域,可能存在着应用领域的不同,但不会产生市场的空缺。 不过,将美国SaaS“赛道”直接投射到中国企业市场,二者恐怕并不完全fit。而且,将PMF概念用在ToB领域,本身也是不适合的。如同并非企业有销售就一定需要CRM、有人就一定需要用HR那么简单的推论。 对ToB来说,不是看产品与市场的fit,而应该是产品与中国企业业务的fit。 所以,海外大火的SaaS产品,直接复制到国内未必有企业需求。中国的SaaS必须基于中国企业市场寻找需求切入点。 综上所述,SaaS在中国的商业机会不但有,而且还很大;但“复制品”的机会可能并不大。 3.SaaS凭什么赚钱 每种生意都有其独特的盈利方式,SaaS又是凭什么赚钱,它赚的是什么钱呢? 前面提到SaaS的两个评价指标:订阅收入占比和收入净留存NDR(Net Dollar Retention),它们就是SaaS赚钱的生意模型。 在所有的收入模式中,订阅是一种优良的收入模式。它代表了持续而稳定的收入水平,也是SaaS收入模式最显著的特征。订阅收入占比越大,意味着收入的稳定部分越大。 而NDR则是反映收入的留存水平,只有留存率高,订阅业务才有持续的保障。 NDR是这样定义的: NDR=(beginning revenue+upgrades-downgrades-churn)/beginningrevenue Upgrades相当于增购订阅数,或者加购/升级服务所增加的收入,Downgrades则是对应的减项,churn则代表纯流失造成的收入减少。 为了搞清每个名词的具体含义,参考下面的计算示例。 这样就容易看出SaaS是从哪里挣的钱。 举个例子,比如说去年的收入是9000万,那么9000 X NDR就是今年的保底收入。 如果NDR是100%,就是说即使解散整个销售团队,也不再做任何获客,今年也能躺赚9000万。 对比美国SaaS资本市场的数据:Pre-IPO公司的NDR中位数约为106%;而大部分中国SaaS公司的流失率(churn)非常高,因而NDR就非常低。 当NDR低到一定程度,比如说20%,那么上一年的努力基本白费;新的一年又要重新花钱找新客户。这差不多相当于传统的软件业务,但盈利性会比软件还要差。 本质上,低的NDR使SaaS的收入模式发生了质变,SaaS生意就赚不到钱了。 所以,SaaS赚的是客户生命周期内持续的付费,所以SaaS公司业务目标是努力维护留存。 4.让SaaS更有效率地赚钱 SaaS生意不但要赚到钱,还必须更有效率地赚钱,以更少的钱挣更多的钱。 SaaS生意的效率受多种因素影响,比如:营销过程、项目大小、复杂度、实施交付等等,但占主要的还是销售效率。 衡量销售效率有很多方法,从营销的资本效率角度,有一种比较量化和说明问题的Magic Number方法,可以量化分析SaaS的销售效率。 SaaS的MagicNumber计算公式是: SaaS MagicNumber=[(该季度收入-上季度收入)*4]/上季度市场和销售的费用。 它反映了公司的获新客能力,直观来看,大约相当于一个季度的营销成本,能否在一年内赚回来。 如果这个指标>1,说明销售体系搭建是OK的,干就是了。 如果这个指标太低,比如说低到0.5,那销售团队配置肯定是有问题的。可能的问题是管理、招聘、培训等等,这就需要调整了。 想当初为了追求高速增长,很多SaaS公司都大规模烧钱扩张销售队伍。最后,大部分销售员都变成了公司的成本,这就是不考虑销售效率活生生的教训。 所以,SaaS的销售效率,决定了SaaS生意的效率。 5.让SaaS有质量地增长 收入增长固然重要,但收入的质量更重要。 前面提到,为延长客户付费周期,就必须以维护留存为主要业务目标。但是,这也是有成本的,这些增加的成本会导致SaaS收入质量的降低。 SaaS理想的收入模式是:收入是软件自动产生的,而非投入的人工服务产生。 而实际上,除了市场&销售成本外,一个客户的生命周期内,可能会产生其它的人工服务成本。比如:获客、售前、实施、CSM,甚至产品研发。因为人工越来越贵,所以叠加的成本也越来越高;更悲催的是:投入配套的人工资源往往并没有收入回报。 如果产品的suite化程度不高,或平台可配置化能力不够;那就需要二开、业务集成等定制化方式交付,比如要做一个SaaS的中台,这势必牵扯更多高成本的人进来。 可以想象,随着所服务客户数量增加,就必须同步增加服务的人力资源,这是任何SaaS公司都难以承受的。 在美国数万家SaaS公司中,绝大部分都是“小公司”,即它们的产品专注于细分业务。依靠软件就能获得大部分收入,比如Slack、Zoom,随产品的稳定,收入质量也越来越高。 这说明,盲目地追求增长和不当的产品定位,会导致收入质量降低,这种增长也就没有意义了。 小结 SaaS并非只是放上一个在线产品,然后推广收费那么简单。其实,SaaS有着相当高的生意门槛。 我们讨论了一个走向盈利之路的SaaS公司,需要面对的5个关键要素,在考虑赚钱之前,最好把它们先想清楚: 生意准备 生意机会 盈利原理 销售效率 收入质量 (每个问题的解决方案,在公众号前面文章都有讨论,此处不再展开。) 创业的过程就是问题解决过程。解决了,也不能保证一定赚到钱;而没解决,则一定赚不到钱。 赚钱是结果,而非原因。

优秀的个人博客,低调大师

拿走不谢!

云栖号:https://yqh.aliyun.com第一手的上云资讯,不同行业精选的上云企业案例库,基于众多成功案例萃取而成的最佳实践,助力您上云决策! 软件技能在科技界很重要,如果你不会正确使用编程语言或平台,你可能得不到这份工作。 以下为译文: 软件技能在科技界很重要,如果你不会正确使用编程语言或平台,你可能得不到这份工作。 目前Indeed 人才招聘实验室跟踪调查了500多名技术人员,其中有哪些技能在美国最受欢迎? 以下是有关美国技术技能的新报告中所分析的结果。该调研团队由经济学家和研究人员组成,对Indeed.com网站在2014年至2019年的5年间发布的数百万个技术职位的招聘信息进行了研究,以发现软件技术公司最需要哪些技能。为了帮助你更好的发展职业生涯,以下是所有技术中最流行的五种编程语言和技能(倒序排列)。 JavaScript 作为前端的主要编程语言,JavaScript出现在14.5%的技术岗位招聘信息中。它不仅是一种广受欢迎的技能,也是使用最多的编程语言,69.7%的专业开发人员经常使用它编写代码。 该语言经历了不断的演变,特别是在库和框架方面。Angular是应用最广泛的,在2016年底击败了Ajax,在2018年中击败了jQuery。事实上,在过去五年中,jQuery的流行度下降了33%,Ajax下降了55%。 当然,并不是所有的技术都在下降。自2014年以来,js、Vue.js和Node.js都实现了强劲、稳定的增长。 Linux 在所有的技术岗位中,Linux占据了14.9%,这就不难理解为什么Linux是第四大最受欢迎的技术。人们每天访问的大多数网站和应用程序都是由Linux提供的(它在微软Azure上的表现甚至比Windows还要好)。 不仅作为最安全的操作系统,而且由于其开源开发模式,各个行业的公司都在寻找懂得Linux生态系统的技术专家,以节约各种产品和服务开发所需的时间和成本。 事实上,Linux开始在智能电视、无人机、冰箱、恒温控制器甚至超级计算机上寻找出路(世界上最快的电脑都是由Linux驱动的)。汽车制造商也看到了这种潜力。例如, Automotive Grade Linux (AGL)是一个开发联网汽车车载技术的开源项目,包括奥迪(Audi)、梅赛德斯-奔驰(Mercedes-Benz)、现代(Hyundai)和丰田(Toyota)。 Python 截至2019年9月,Python出现在18%的技术工作招聘信息中,使其成为榜单上第三受欢迎的技能。在招聘实验室调查的所有主要技术技能中,Python也是增长最快的。2014年,Python是排名第15的技能,但到2019年,它上升到第3名(增加了118%)。 数据科学家和相关角色(如数据工程师、数据分析师和机器学习工程师)在内的新工作组合,在一定程度上解释了这种增长。例如,自2013年12月以来,数据科学的工作岗位激增了256%。随着公司产生越来越多的数据,Python很可能会继续保持这种高速增长的轨迹,特别是因为Python多年来一直是数据科学家的最爱。 不仅仅是数据科学工作的兴起促使了Python的成功。软件工程师、全栈开发人员、QA工程师和其他一些角色越来越多地使用Python,是因为它的通用性、易用性和开发速度。在2019年,Python第一次超越Java成为第二大最受欢迎的语言(仅次于JavaScript)。 Java Java出现在21%的科技职位招聘中,使其成为第二大受欢迎的技能。Java不仅是Android移动开发的中流砥柱,而且在近25年的时间里一直是软件工程师的热门技能。因为它是一种“write once, run anywhere”(WORA)语言,所以它是跨平台的,允许公司在一个系统上开发Java代码,并在任何其他支持Java的机器上运行它。 因为它是为那些规模不断扩大的项目而设计的,所以大多数企业——包括Facebook、Netflix和airbnb等大公司以及初创公司——都使用它来构建从电子商务后端和机器学习环境到云应用甚至物联网技术的一切。由于它的通用性、丰富的工具生态系统和强大的社区,现在全世界有130亿支持Java的设备——这意味着对Java人才的需求还会持续。 SQL SQL是2019年最优秀的技能,在所有科技职位中占22%(仅比Java高出1%)。为什么呢?因为所有公司都依赖数据,需要组织、理解和可视化数据来做出重要的业务决策。SQL是最通用的数据库语言,支持Microsoft SQL Server、MySQL、PostgreSQL和SQLite等数据库引擎。 各种各样的技术人员都在使用它,从访问数据库编写程序的开发人员到设计数据库的工程师,再到数据科学家和分析师——他们将数千万(或数亿)行数据转化为商业价值信息。即使是非技术团队,比如市场和销售,也可以利用SQL来进行决策。 不过,尽管SQL占据了首位,但在过去五年里,SQL的份额实际上略有下降,部分原因可能是NoSQL等替代数据库查询工具的兴起。尽管如此,正如技术职位所描述的那样,SQL主导着市场,而且短期内似乎不会有任何变化。 编程语言和技术的兴衰变化 2019年雇主最看重的五种语言和技能不一定是增长最快的。科技从来都不是一成不变的,所以让我们来看看哪些技能正在经历最大的增长,哪些技能正在迅速失宠,这样你就可以在最新的趋势中保持领先。 通过学习以下发展最快的技术,在激烈的人才竞争中脱颖而出。你掌握了几种呢?在你的简历中突出它们,让雇主优先选择你。 Docker:在过去的五年里,Docker的发展轨迹令人印象深刻。2014年,在Indeed的工作岗位描述中几乎没有这种软件(因为第一个正式版本是在那年晚些时候发布的)。但在2019年,Docker增长了40多倍,雇主的需求实际上超过了求职者的兴趣。 IOT: IOT(物联网)技术在过去五年里增长了近2000%,这是由大量连接到互联网的物理设备推动的,包括智能家居、联网汽车、智能城市和可穿戴技术。 Ansible: 2014年,让应用程序和系统更容易部署的IT自动化平台只出现在0.1%的技术职位描述中,但现在达到2.8%——显著增长了近130%。 Kafka: Apache Kafka,一个建立实时流数据管道的开源平台,也经历了爆炸性的增长,在五年内增长了超过1200%。这反映了数据科学和与之相关的技术工作的迅速普及,如开发运营人员、数据科学家和全栈开发人员。 衰落最快的技能 随着新的技术、语言和标准进入主流,旧的技术、语言和标准被挤出了排行榜(甚至被淘汰)。考虑在2020年放弃这些技术。 Clojure:作为一种Lisp编程语言的经典,曾一度受到狂热的追捧,它的粉丝人数虽少,但热情高涨。它不是一种主流语言,由于其缺乏强大的库系统以及它需要更高的CPU占用率(这将增加使用和运营成本),因此对Clojure的需求自2014年以来下降了80%。 EJB:尽管Java是2019年最热门的技术之一,但EJB (Enterprise javabean的缩写)自2014年以来下降了73%。一种可能的解释是,其他现代的基于java的框架,比如Spring Boot(去年增长了58%)是开源的,使用起来更方便,资源消耗也更少。 Servlets: servlets是另一种基于java的技术,但很快就会成为一种遗留技术。为什么呢?使用servlets的开发人员必须编写大量程序代码来构建web应用程序,而其他框架,如Spring MVC,则使手工工作自动化,从而使构建web应用程序更快、更容易。 JSP: 与EJB和servlets的情况类似,随着构建动态web页面的新技术成熟和流行,JSP (JavaServer Pages)开始过时。JSP仅限于简单、固定的交互,但是像Angular、React和Vue.js这样的新JS框架提供了更丰富的web应用程序,其中包含大量用户交互。 你的技术能与时俱进吗? 在瞬息万变的科技世界里,无论是想找到一份新的科技工作还是投资未来的职业发展,保持你的技能与时俱进,都是至关重要的。但是,很难弄清楚什么技术是一时的流行,什么技术会持续下去,尤其是在新技术日益更新(旧的技术正在被淘汰)的情况下。 那么你该如何适应?学习所需的技能,而不是沉迷于昙花一现的狂热中。这五年的稳定(有时是爆炸性的)增长表明,一些像Python、Java或SQL语言或技能可能还会继续存在,至少在下一次打破排名之前是这样。 云栖号:https://yqh.aliyun.com第一手的上云资讯,不同行业精选的上云企业案例库,基于众多成功案例萃取而成的最佳实践,助力您上云决策! 原文发布时间:2020-1-17本文作者:CSDN App本文来自阿里云云栖号合作伙伴“CSDN”,了解相关信息可以关注“CSDN”

优秀的个人博客,低调大师

竞品分析实操-全文不掺杂任何“鸡汤”

写在前面的话 一、竞品分析和功能分析是不同的,竞品分析主要掌握一个产品的节奏和玩法,进而为自己的产品迭代和方向指导,简单点说就是做同一类产品别人是怎么一步一步走向成功的(当然产品只是其中的一部分),还有别人是怎么一步一步的作死的。 二、功能分析主要是要优化自己的功能时去借鉴别人是怎么做的,还有自检自己产品的功能是否可以做的更好。 三、还有一点要说就是无论功能分析或竞品分析报告如果为了工作需要没必要大篇幅的去写,把市场、交互、UI统统都写进去没多大意义。 竞品分析实操 产品分析过程图 调研背景和目的 这个就结合自己的产品情况,比如我新进入一个行业,想快速熟悉这个行业的产品都是怎么玩的,为自己的产品做指导。 选择产品 选择产品这个就是选择行业内的佼佼者和上升较快的产品,原因是行业内的佼佼者有更多的资源去试错和踩过很多坑,而上升快的产品肯定有上升快的原因,要通过分析找出背后的原因,比如我想做生鲜类的产品我就会去选择“京东到家”“每日优鲜”等这些竞品去分析。 体验产品 体验产品主要关注用户、使用场景、需求,把这几点明确下来,如果能找到相应的用户做简单的访谈那就更好了,如“每日优鲜”。 使用场景 :(1)场景一 用户 : 懒人、吃货。 需求 : 吃水果、零食等。 要解决的痛点 :懒得动,不想去超市买水果、蔬菜 。 (2)场景二 用户 : 家庭主妇。 需求 : 买菜、做饭。 要解决的痛点 :带孩子出去买菜不方便,自己出去买菜把孩子放家不放心。 还原产品 所谓还原产品就是还原产品的业务流程图,无论那个产品交互可能随时会调整(为了更好的用户体验),但是业务流程图很少有变动,还是以“每日优鲜”为例如下图。 关于业务流程图怎么做可以查看我上篇文章:“业务流程图实操篇 https://www.jianshu.com/p/1d5dbb8f7a5e” 除了还原竞品的业务流程图,还要还原竞品的产品结构,就是如何把业务流程以产品的形式展示给用户的,如下图 有小伙伴会说,我看了很多但是当我自己产品搭建产品架构的时候我依旧不知道怎么做?那么我说你持续分析某个行业的一些产品每个产品都画出来,坚持做个几十个产品,再看看会不会做。 分析产品 1、产品表现分析: 这里的分析产品表现不是去网上找各种N手数据,通常用户流程中的使用过程,数据已经表现出来了,如下图 其它类的产品道理是一样的,比如评论数、点赞量、阅读量等,都是通过产品的关键页面数据的表现来分析这款产品的现状。 2、产品迭代、运营分析 还是以“每日优鲜”为例思路和实操是这样的,第一步:借用第三方工具(酷传:http://www.kuchuan.com)查看产品的历史下载数据如下图: 历史下载数据曲线图 这个数据可以自定义时间段,也可以导出。 第二步:查看版本迭代的过程,看不同的版本迭代后数据的表现是如何的。也是用这个工具如下图: 版本迭代 第三步:看这个阶段除了产品运营还做了哪些动作,看运营和什么动作和数据的关系。这个可以通过IT桔子(或google浏览器)如下图: 新闻动态 第四步:看关键版本的产品业务流程和架构是如何的,这个可以通过“手机乐园”去下载历史版本,如下图 把这些数据整合后你就很清晰知道了这个产品是怎么一步一步的走过来的了,或者有些产品如何一步一步作死的,做了哪些动作数据大幅度提升了,做了哪些事情无意义,会对自己的产品有个明确的引导。 3、横向比较同类产品 用以上同样的方法是分析其它的竞品,找出核心的的差异点,看下每个产品都有什么不同的优点,分析优点当然是为了借鉴喽。 总结、撰写调研报告 对上面的分析进行总结,比如某个产品每一步是如何一步一步做过来的,综合考虑我们的资源是否可以借鉴,再比如同类产品竞品分析后,我们自己的产品处于什么阶段,我们下一步要怎么走。 调研报告应该包含上面的过程的展现和对每个步骤的结论,有过程有结论,这样的报告无论给领导看还是和同事间沟通都是有说服力的。 娱乐下,写这篇文章是因为我女朋友看过前面竞品分析vs功能分析那篇后还是不会实操,所以我想大家可能也有同样的问题,就补充了这篇,可以说每一步都是实操,如果对你有帮助请点个喜欢。

优秀的个人博客,低调大师

解决Centos下“ssh免密码登录不生效”问题

摘要 一般为了方便运维管理都会配置ssh免密登录,ssh免密登录实现也很方便。今天遇到一个完成了配置了却不能生效的问题。 思考 遇到这个问题一般有以下几点: authorized_keys文件是否启用 .ssh 和 authorized_keys 文件权限问题 排查 检查AuthorizedKeysFile配置是否启用authorized_keys root@pts/1 $ cat /etc/ssh/sshd_config |egrep AuthorizedKeysFile AuthorizedKeysFile .ssh/authorized_keys 没有问题,继续检查.ssh (700) 和 authorized_keys(644) 权限 root@pts/1 $ getfacl /root/.ssh/ getfacl: Removing leading '/' from absolute path names # file: root/.ssh/ # owner: root # group: root user::rwx group::--- other::--- root@pts/1 $ getfacl /root/.ssh/authorized_keys getfacl: Removing leading '/' from absolute path names # file: root/.ssh/authorized_keys # owner: root # group: root user::rw- group::--- other::--- authorized_keys权限不对,修改一下chmod 644 authorized_keys 再次尝试结果发现还是不行。但是该设置的权限都设置了。既然.ssh目录和其下文件的权限都OK了,那就检查下其父目录的权限,也就是这里的/root的权限 root@pts/1 $ getfacl /root/ getfacl: Removing leading '/' from absolute path names # file: root/ # owner: ftpuser # group: ftpuser user::r-x group::r-x other::--- 发现这里/root的属主都发生了变化。为了不影响别的业务情况,保留这里的ftpuser权限,利用setfacl添加特殊ACL权限 root@pts/1 $ chown -R root:root /root/ root@pts/1 $ setfacl -m u:ftpuser:rwx /root/ root@pts/1 $ getfacl /root/ getfacl: Removing leading '/' from absolute path names # file: root/ # owner: root # group: root user::rwx user:ftpuser:rwx #effective:r-x group::r-x mask::r-x other::r-x 附加 权限问题 /root 775 /root/.ssh 700 /root/.ssh/authorized_keys 644 开启文件AuthorizedKeysFile .ssh/authorized_keys

优秀的个人博客,低调大师

Android Shape渲染的使用(经典,学习研究不后悔)

感觉好久都没有写博文了,感觉自己变懒了,真对不起…-_-… 也有部分原因是因为我想写的东 西网上已经有了,再加上还有很多方面小马我也正在学习,所以….这段时间一直暂停更新我的博客文 章,看到博客的访问量一天天的增加,很开心 。。。O_O。。。这一阵子也看了各种各样的书籍,技 术类的、非技术类的,也找到了自身很多的不足之处,我会用更多的心思来弥补不足,希望大家一起 努力、加油! 以上是对自己讲的一点废话,现在开始今天的主题,控件渲染Shade(也可以叫着色器,但坏小 马不喜欢这么叫,着色器….怪怪的!)的使用,一直都有在关注这方面的东西,网上也有部分文章写 得不错,但是还是觉得不过瘾,往往都是写一点点自己在工作中使用过的,今天小马就用点心总结下 这方面的东西,希望对这块知识有兴趣的帅果、美驴们有所帮助或提高,果断先看效果再一步步看代 码!希望大家仔细看看我在XML及.java中添加的注释,相信你不会后悔花时间在这文章上的,今天的 DEMO效果图如下: 好了,效果看完了,下一步开始看代码吧,亲…….静下心….一步步来!!! PS:模拟器与eclipse效果中预览的以下部分有点不一样,可能是eclipse与模拟器二者之前存在Bug吧…吼吼…. 工程目录如下: 首先,先做个小小的铺垫: Android提供的Shader类主要是渲染图像以及一些几何图形。 Shader有几个直接子类: BitmapShader :主要用来渲染图像 LinearGradient :用来进行线性渲染 RadialGradient :用来进行环形渲染 SweepGradient :扫描渐变---围绕一个中心点扫描渐变就像电影里那种雷达扫描,用来梯度渲染。 ComposeShader :组合渲染,可以和其他几个子类组合起来使用。 小记:Android控件渲染Shade的实现方式有两种,(一、JAVA代码实现;二、XML配置来实现), 小马自己比较偏向XML实现,原因很简单: 1.你代码实现写得再经典,不跑起来效果看不到! 2.跑一遍Android模拟器,思路可以断一大节!(我很笨,经常这样 T_T)! 3.JAVA代码的每个函数参数你也得一个个去啃(老板管效率,不管怎么实现,等你啃完参数时,XML已经看到效果了 O_o ……走起…..)! 4,这是最主要的一点,Eclipse或者I/O大会刚推出的Android Studio,实时显示,我就特别 喜欢立竿见影 ^_^ ! 5.二者各有利弊,JAVA代码实现可以动态且灵活滴,XML配置的统一但不杂乱 @_@!! Now…….. Ladies and乡亲们,看举一种JAVA代码excmple,其余类型的与之类似,亲们自己“度娘 、谷哥 ”: LinearGradient是线性渐变,用法如下: Gradient是基于Shader类,所以我们通过Paint的setShader方法来设置这个渐变,代码如下: Paint p=new Paint(); LinearGradient lg=newLinearGradien(0,0,100,100,Color.RED,Color.BLUE,Shader.TileMode.MIRROR); Gradient是基于Shader类,所以我们通过Paint的setShader方法来设置这个渐变,代码如下: p.setShader(lg); canvas.drawCicle(0,0,200,p); //参数3为画圆的半径,类型为float型。 先不说效果了,PS:看着上面的代码,有没有想哭的冲动啊 ? ? ?感觉乱乱的,不知道是什么,然后单词gradient不懂,一查如下(晕),看着挺牛,还是只是个渲染!不管了,继续往下看… 再看XML配置代码,如下: 一:主布局文件代码如下(为了方便,布局是直接拖的,大家不用太关注): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 < RelativeLayout xmlns:android = "http://schemas.android.com/apk/res/android" xmlns:tools = "http://schemas.android.com/tools" android:layout_width = "match_parent" android:layout_height = "match_parent" android:background = "@drawable/background" android:paddingBottom = "@dimen/activity_vertical_margin" android:paddingLeft = "@dimen/activity_horizontal_margin" android:paddingRight = "@dimen/activity_horizontal_margin" android:paddingTop = "@dimen/activity_vertical_margin" tools:context = ".MainActivity" > < com.xiaoma.shadedemo.TextViewBorder android:id = "@+id/textView1" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_alignParentLeft = "true" android:layout_alignParentTop = "true" android:layout_marginLeft = "22dp" android:layout_marginTop = "20dp" android:text = " JAVA实现带四条边框" android:textColor = "@android:color/white" android:textSize = "25sp" /> < com.xiaoma.shadedemo.TextViewBorderLeftRight android:id = "@+id/TextViewBorder01" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:textColor = "@android:color/white" android:layout_alignLeft = "@+id/textView1" android:layout_below = "@+id/textView1" android:layout_marginTop = "20dp" android:text = "JAVA实现带左右边框" android:textSize = "25sp" /> < com.xiaoma.shadedemo.TextViewBorderUnder android:id = "@+id/TextViewBorder02" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_alignLeft = "@+id/TextViewBorder01" android:textColor = "@android:color/white" android:layout_below = "@+id/TextViewBorder01" android:layout_marginTop = "33dp" android:text = "JAVA代码实现下边框" android:textSize = "25sp" /> < TextView android:id = "@+id/TextViewBorderUnder01" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_alignLeft = "@+id/button1" android:layout_below = "@+id/TextViewBorder02" android:layout_marginTop = "20dp" android:text = "Shape XML实现边框" android:background = "@drawable/shape_test" android:textColor = "@android:color/white" android:textSize = "25sp" /> < Button android:id = "@+id/button1" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_alignLeft = "@+id/TextViewBorder02" android:layout_below = "@+id/TextViewBorderUnder01" android:layout_marginTop = "29dp" android:background = "@drawable/shape_selector" android:text = "Selector与Shape混用按钮" android:textColor = "@android:color/black" /> </ RelativeLayout > 二:上面布局中使用的自定义控件代码及Shape渲染代码分别如下: 2.1:JAVA实现带四条边框(自定义TextView JAVA代码一) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 package com.xiaoma.shadedemo; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.widget.TextView; public class TextViewBorder extends TextView { /** * 下面两个方法在构造时需注意: 一:如果是XML文件加载的方式使用自定义控件到布局中是用以下方式, 二:如果是用纯代码的方式加载自定义的控制到而已中时用第二种方式 */ // 方式一: public TextViewBorder(Context context, AttributeSet attrs) { super (context, attrs); } // 方式二: /* * public TextViewBorder(Context context) { // TODO Auto-generated constructor stub super(context); } */ /** * 1. Rect对象 一个区域对象Rect(left, top, right, bottom) , 是一个左闭右开的区域, 即是说使用 Rect.contains(left, top)为true, * Rect.contains(right, bottom)为false 2. drawLine方法 drawLine(float startX, float startY, float stopX, float stopY, * Paint paint) 也是一个左闭右开的区间,只会绘制到stopX-1,stopY-1 3. drawRect(Rect r, Paint paint) 当绘制空心矩形时,绘制的是一个左闭右闭的区域 * 验证方法:下面就是可以验证左闭右开的区间方法,现在知道为什么要-1 了 */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setColor(Color.GREEN); canvas.drawLine(0, 0, this.getWidth() - 1, 0, paint);// 绘制上边框 canvas.drawLine(0, 0, 0, this.getHeight() - 1, paint); // 绘制左边框 canvas.drawLine(this.getWidth() - 1, 0, this.getWidth() - 1, this.getHeight() - 1, paint); // 绘制右边框 canvas.drawLine(0, this.getHeight() - 1, this.getWidth() - 1, this.getHeight() - 1, paint);// 绘制下边框 } /* * 1. Rect对象 * * 一个区域对象Rect(left, top, right, bottom) , 是一个左闭右开的区域,即是说使用 Rect.contains(left, top)为true, Rect.contains(right, * bottom)为false * * 2.drawLine方法 * * drawLine(float startX, float startY, float stopX, float stopY, Paint paint) 也是一个左闭右开的区间,只会绘制到stopX-1,stopY-1 * * 验证方法: * * Canvas c = canvas; paint.setColor(Color.RED); c.drawLine(x, y, x+c.getWidth()-1, y, paint); c.drawLine(x, * y+height-1, x+c.getWidth(), y+height-1, paint); paint.setColor(Color.BLUE); c.drawPoint(x+c.getWidth()-1, y, * paint); 说明drawLine是没有绘制到右边最后一个点的 * * 3.drawRect(Rect r, Paint paint) * * 当绘制空心矩形时,绘制的是一个左闭右闭的区域 * * 验证方法: * * rect.set(x, y, x+width, y+height); paint.setStyle(Style.STROKE); paint.setColor(Color.BLUE); c.drawRect(rect, * paint); paint.setColor(Color.RED); c.drawLine(x, y, x+width, y, paint); c.drawLine(x, y+height, x+width, * y+height, paint); c.drawLine(x, y, x, y+height, paint); c.drawLine(x+width, y, x+width, y+height, paint); * 当绘制实心矩形时,绘制的是一个左闭右开的区域 * * 验证方法: * * rect.set(x, y, x+width, y+height); paint.setColor(Color.RED); c.drawLine(x, y, x+width, y, paint); c.drawLine(x, * y+height, x+width, y+height, paint); c.drawLine(x, y, x, y+height, paint); c.drawLine(x+width, y, x+width, * y+height, paint); paint.setStyle(Style.FILL); paint.setColor(Color.BLUE); c.drawRect(rect, paint); * 这个规则跟j2me也是一样的,在j2me里,drawRect长宽会多画出1px。SDK的说明是: * * The resulting rectangle will cover an area (width + 1) pixels wide by (height + 1) pixels tall. If either width * or height is less than zero, nothing is drawn. * * 例如drawRect(10,10,100,1)绘制,结果是一个2px高的矩形,用fillRect(10,10,100,1),结果是一个1px高的矩形 * * 以上就是对Android绘图的具体介绍。 */ } /** * 在布局文件中引用 这样引用就行了..吼吼 <com.xiaoma.shadedemo.TextViewBorder android:id="@+id/a02_txtKSSJ" android:textColor="#000000" * android:layout_marginLeft="10dip" android:layout_width="100dip" android:layout_height="wrap_content" /> */ 2.2:JAVA实现带左右边框(自定义TextView JAVA代码二) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 package com.xiaoma.shadedemo; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.widget.TextView; public class TextViewBorderLeftRight extends TextView { /** * 下面两个方法在构造时需注意: 一:如果是XML文件加载的方式使用自定义控件到布局中是用以下方式, 二:如果是用纯代码的方式加载自定义的控制到而已中时用第二种方式 */ // 方式一: public TextViewBorderLeftRight(Context context, AttributeSet attrs) { super (context, attrs); } // 方式二: /* * public TextViewBorder(Context context) { // TODO Auto-generated constructor stub super(context); } */ /** * 1. Rect对象 一个区域对象Rect(left, top, right, bottom) , 是一个左闭右开的区域, 即是说使用 Rect.contains(left, top)为true, * Rect.contains(right, bottom)为false 2. drawLine方法 drawLine(float startX, float startY, float stopX, float stopY, * Paint paint) 也是一个左闭右开的区间,只会绘制到stopX-1,stopY-1 3. drawRect(Rect r, Paint paint) 当绘制空心矩形时,绘制的是一个左闭右闭的区域 * 验证方法:下面就是可以验证左闭右开的区间方法,现在知道为什么要-1 了 */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setColor(Color.GREEN); canvas.drawLine(0, 0, 0, getHeight(), paint); // canvas.drawLine(getWidth(), 0, getWidth() - 1, getHeight() - 1, paint); canvas.drawLine(this.getWidth() - 1, 0, this.getWidth() - 1, this.getHeight() - 1, paint); // canvas.drawLine(0, 0, 0, this.getHeight() - 1, paint); // canvas.drawLine(this.getWidth() - 1, 0, this.getWidth() - 1, this.getHeight() - 1, paint); // canvas.drawLine(0, this.getHeight() - 1, this.getWidth() - 1, this.getHeight() - 1, paint); } /* * 1. Rect对象 * * 一个区域对象Rect(left, top, right, bottom) , 是一个左闭右开的区域,即是说使用 Rect.contains(left, top)为true, Rect.contains(right, * bottom)为false * * 2.drawLine方法 * * drawLine(float startX, float startY, float stopX, float stopY, Paint paint) 也是一个左闭右开的区间,只会绘制到stopX-1,stopY-1 * * 验证方法: * * Canvas c = canvas; paint.setColor(Color.RED); c.drawLine(x, y, x+c.getWidth()-1, y, paint); c.drawLine(x, * y+height-1, x+c.getWidth(), y+height-1, paint); paint.setColor(Color.BLUE); c.drawPoint(x+c.getWidth()-1, y, * paint); 说明drawLine是没有绘制到右边最后一个点的 * * 3.drawRect(Rect r, Paint paint) * * 当绘制空心矩形时,绘制的是一个左闭右闭的区域 * * 验证方法: * * rect.set(x, y, x+width, y+height); paint.setStyle(Style.STROKE); paint.setColor(Color.BLUE); c.drawRect(rect, * paint); paint.setColor(Color.RED); c.drawLine(x, y, x+width, y, paint); c.drawLine(x, y+height, x+width, * y+height, paint); c.drawLine(x, y, x, y+height, paint); c.drawLine(x+width, y, x+width, y+height, paint); * 当绘制实心矩形时,绘制的是一个左闭右开的区域 * * 验证方法: * * rect.set(x, y, x+width, y+height); paint.setColor(Color.RED); c.drawLine(x, y, x+width, y, paint); c.drawLine(x, * y+height, x+width, y+height, paint); c.drawLine(x, y, x, y+height, paint); c.drawLine(x+width, y, x+width, * y+height, paint); paint.setStyle(Style.FILL); paint.setColor(Color.BLUE); c.drawRect(rect, paint); * 这个规则跟j2me也是一样的,在j2me里,drawRect长宽会多画出1px。SDK的说明是: * * The resulting rectangle will cover an area (width + 1) pixels wide by (height + 1) pixels tall. If either width * or height is less than zero, nothing is drawn. * * 例如drawRect(10,10,100,1)绘制,结果是一个2px高的矩形,用fillRect(10,10,100,1),结果是一个1px高的矩形 * * 以上就是对Android绘图的具体介绍。 */ } /** * 在布局文件中引用 这样引用就行了..吼吼 <com.xiaoma.shadedemo.TextViewBorder android:id="@+id/a02_txtKSSJ" android:textColor="#000000" * android:layout_marginLeft="10dip" android:layout_width="100dip" android:layout_height="wrap_content" /> */ 2.3:JAVA代码实现下边框(自定义TextView JAVA代码三) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 package com.xiaoma.shadedemo; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.widget.TextView; public class TextViewBorderUnder extends TextView { /** * 下面两个方法在构造时需注意: 一:如果是XML文件加载的方式使用自定义控件到布局中是用以下方式, 二:如果是用纯代码的方式加载自定义的控制到而已中时用第二种方式 */ // 方式一: public TextViewBorderUnder(Context context, AttributeSet attrs) { super (context, attrs); } // 方式二: /* * public TextViewBorder(Context context) { // TODO Auto-generated constructor stub super(context); } */ /** * 1. Rect对象 一个区域对象Rect(left, top, right, bottom) , 是一个左闭右开的区域, 即是说使用 Rect.contains(left, top)为true, * Rect.contains(right, bottom)为false 2. drawLine方法 drawLine(float startX, float startY, float stopX, float stopY, * Paint paint) 也是一个左闭右开的区间,只会绘制到stopX-1,stopY-1 3. drawRect(Rect r, Paint paint) 当绘制空心矩形时,绘制的是一个左闭右闭的区域 * 验证方法:下面就是可以验证左闭右开的区间方法,现在知道为什么要-1 了 */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setColor(Color.GREEN); // canvas.drawLine(0, 0, this.getWidth() - 1, 0, paint); // canvas.drawLine(0, getHeight(), getWidth() - 1, getHeight(), paint); // canvas.drawLine(this.getWidth() - 1, 0, this.getWidth() - 1, this.getHeight() - 1, paint); canvas.drawLine(0, getHeight() - 1, getWidth() - 1, getHeight() - 1, paint); } /* * 1. Rect对象 * * 一个区域对象Rect(left, top, right, bottom) , 是一个左闭右开的区域,即是说使用 Rect.contains(left, top)为true, Rect.contains(right, * bottom)为false * * 2.drawLine方法 * * drawLine(float startX, float startY, float stopX, float stopY, Paint paint) 也是一个左闭右开的区间,只会绘制到stopX-1,stopY-1 * * 验证方法: * * Canvas c = canvas; paint.setColor(Color.RED); c.drawLine(x, y, x+c.getWidth()-1, y, paint); c.drawLine(x, * y+height-1, x+c.getWidth(), y+height-1, paint); paint.setColor(Color.BLUE); c.drawPoint(x+c.getWidth()-1, y, * paint); 说明drawLine是没有绘制到右边最后一个点的 * * 3.drawRect(Rect r, Paint paint) * * 当绘制空心矩形时,绘制的是一个左闭右闭的区域 * * 验证方法: * * rect.set(x, y, x+width, y+height); paint.setStyle(Style.STROKE); paint.setColor(Color.BLUE); c.drawRect(rect, * paint); paint.setColor(Color.RED); c.drawLine(x, y, x+width, y, paint); c.drawLine(x, y+height, x+width, * y+height, paint); c.drawLine(x, y, x, y+height, paint); c.drawLine(x+width, y, x+width, y+height, paint); * 当绘制实心矩形时,绘制的是一个左闭右开的区域 * * 验证方法: * * rect.set(x, y, x+width, y+height); paint.setColor(Color.RED); c.drawLine(x, y, x+width, y, paint); c.drawLine(x, * y+height, x+width, y+height, paint); c.drawLine(x, y, x, y+height, paint); c.drawLine(x+width, y, x+width, * y+height, paint); paint.setStyle(Style.FILL); paint.setColor(Color.BLUE); c.drawRect(rect, paint); * 这个规则跟j2me也是一样的,在j2me里,drawRect长宽会多画出1px。SDK的说明是: * * The resulting rectangle will cover an area (width + 1) pixels wide by (height + 1) pixels tall. If either width * or height is less than zero, nothing is drawn. * * 例如drawRect(10,10,100,1)绘制,结果是一个2px高的矩形,用fillRect(10,10,100,1),结果是一个1px高的矩形 * * 以上就是对Android绘图的具体介绍。 */ } /** * 在布局文件中引用 这样引用就行了..吼吼 <com.xiaoma.shadedemo.TextViewBorder android:id="@+id/a02_txtKSSJ" android:textColor="#000000" * android:layout_marginLeft="10dip" android:layout_width="100dip" android:layout_height="wrap_content" /> */ 2.4:Shape XML实现边框(XML代码) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <? xml version = "1.0" encoding = "utf-8" ?> < shape xmlns:android = "http://schemas.android.com/apk/res/android" > <!-- <solid android:color="#cceeff"/> 直接写这个的话,可以给控制添加一个整体的背景哦 --> < stroke android:width = "0.5dp" android:color = "#22ccff" /> < padding android:left = "5dp" android:top = "5dp" android:right = "5dp" android:bottom = "5dp" /> < size android:height = "0.5dp" android:width = "5dp" /> <!-- 目前没有什么用,可删除,留在这个地方防止乱猜 --> < corners android:radius = "10dp" /> <!-- 这个radius里面的值需要个整型,单位用dp,用其它单位亦无影响 --> </ shape > 2.5:Selector与Shape混用控件效果实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 <? xml version = "1.0" encoding = "utf-8" ?> < selector xmlns:android = "http://schemas.android.com/apk/res/android" > <!-- 今天主要讲的是shape渲染,shape主要类型分四种,效果如下,我们常用rectangle,也就是矩形渲染,其它的都太丑了!! --> < item android:state_pressed = "true" > <!--按钮按下时的渲染效果 --> < shape android:shape = "oval" > < corners android:radius = "10dp" /> <!-- 四个角的角度 --> <!--gradient就是梯度渲染,简单说就是颜色渐变,type为渐变方式,总共三种 linear sweep ridial,常用linear--> < gradient android:endColor = "#eebbbb" android:startColor = "#9900ee" android:type = "linear" /> <!-- padding属性是指定内容与控件边距,这个地方小马专门将距左边距设置较大,方便观察 --> < padding android:bottom = "5dp" android:left = "20dp" android:right = "5dp" android:top = "5dp" /> <!-- solid填充整个区域,颜色为FFDDFF,如果使用整个区域填充的话,上面的gradient梯度会失效,即:覆盖 --> <!-- <solid android:color="#FFDDFF"/> --> <!-- stroke为需要填充的边框,指定颜色及边框宽度 --> < stroke android:width = "3dp" android:color = "#000000" /> </ shape > <!-- <clip android:clipOrientation="vertical" android:gravity="right" android:drawable="@drawable/ic_launcher" /> --> <!-- 试了下没用 --> <!-- <color android:color="#223344"/> --> <!-- <scale android:scaleWidth="15dp" android:scaleHeight=" 5dp" android:scaleGravity="center" /> --> </ item > < item > <!-- 默认 --> < shape android:shape = "rectangle" > < corners android:radius = "10dp" /> <!-- 四个角的角度 --> <!--gradient就是梯度渲染,简单说就是颜色渐变,type为渐变方式,总共三种 linear sweep ridial,常用linear--> <!-- 这个地方一定注意,在使用gradient标签中使用android:type的前提是必须android:gradientRadius="20dp"已经设置,否则会报错 --> < gradient android:endColor = "#acefda" android:startColor = "#0099ff" android:type = "linear" /> <!-- padding属性是指定内容与控件边距,这个地方小马专门将距左边距设置较大,方便观察 --> < padding android:bottom = "5dp" android:left = "20dp" android:right = "5dp" android:top = "5dp" /> <!-- solid填充整个区域,颜色为FFDDFF,如果使用整个区域填充的话,上面的gradient梯度会失效,即:覆盖 --> <!-- <solid android:color="#FFDDFF"/> --> <!-- stroke为需要填充的边框,指定颜色及边框宽度 --> < stroke android:width = "3dp" android:color = "#000000" /> </ shape > </ item > </ selector > 怎么样?看着JAVA自定义TextView代码是不是觉得特别的繁琐?今天的主题就是来解决这个问题的....…^_^.........下面着重来讲一下Selector与Shape混用控件效果Selector实现的细节,(请仔细看下XML里面的注释 O_O) 每个Item过是由Shape来进行渲染生成最终的效果,首先来看根Shape节点的常用属性<shape android:shape="rectangle">: 这个shape属性总共分三种 rectangle(矩形)、oval(椭圆) 、line(删除线)、ring(铃,这个存在不知道有什么意义),其效果分别如下: 1.rectangle 2.oval 3.line 4.ring 其中,gradient标签中的type为渐变方式,总共三种 linear sweep ridial,常用linear,其效果分别为(注意:ridial试了无任何效果 T_T) 1.linear效果 2.sweep效果 好了,代码及整体效果已经分解完毕了,如果认真从头到尾的看一边的话,肯定有所收获的,对了,以上的Shape渲染写好了,可以在任意控件上使用…不限于TextView,上面的例子只是拿TextView来开刀用的…大家别误会,呵呵….^_^…. ,最后,小马希望在文章中有什么不清楚或不明白或有错误的地方,请大家直接指出…有错必改的….这个源码小马已经上传到附件中,有兴趣或有用的朋友可以直接下载来跑跑改改看,有批评才有进步,希望有什么不好的,直接指出….在此先谢谢大家啦…. 官网参考链接如下(只是没效果图,所以大家也懒得去看这个东西) http://developer.android.com/guide/topics/resources/drawable-resource.html 这段时间也有在关注各种各样的东西,老听人说学这学那的人越来越多什么的,也希望大家不要随便听人家讲,我敢说….安卓虽然在很多人眼里看来简单、烂,但我觉得如果要深入的话,水还是很深的,如果用心,一定可以做的越来越好的,一步一步来,大家一起努力!做安卓的人越来越多,越有竞争!越有动力!!!这样才会进步!哈哈….加油加油加油! O_O 附件:http://down.51cto.com/data/2362968 本文转自华华世界 51CTO博客,原文链接:http://blog.51cto.com/mzh3344258/1215749,如需转载请自行联系原作者

优秀的个人博客,低调大师

数据中心安全凭AI,靠谱不?

IT服务安全性有很多层次。 比如:IT安全层包括防火墙、入侵检测和访问控制。基础设施层包括电力、网络、服务器的健康和冷却等。其中,最为重要的是管理人员。正确的人员有正确的流程、工具和措施,以确保一切正常。人工智能(AI)将会通过放大功能,精简流程和提高效率,这会对人们使用的工具和措施产生巨大的影响。 人工智能和深度学习将成为解析和分析数据中心内生成的数据的必要条件,从而提供更有效地管理服务交付,同时减少停机等风险。这源于最近我们如何交付应用程序工作负载的转变。 数据太多? 在过去十年中,我们从大多数单服务器单应用程序转移成以容器运行的分布式应用程序。而现在,这些都是由运行在云端的微服务,以及自动化工具管理的云服务提供的。基础设施已成为应用程序的一部分,而其他应用程序已成为基础设施的一部分。如果您正在使用像Amazon S3或谷歌地图这样的平台作为您的服务交付的一个组成部分,那么您将亲身体验这种转换。 由此而产生的对数据中心管理造成的影响是显著的,而电力和制冷只是其中需要关注的一小部分。环境控制,物理设备,虚拟机和公有云都需要被全天候监控和管理,以提高成本和性能。那么,了解何时何地移动特定工作负载就变得至关重要了。 企业今天收集,监测和分析数据都是确保业务能够连续性的爆发。他们需要考虑从传感器、应用、门禁系统、配电单元、UPS、发电机和太阳能电池板产生的数据,添加到外部数据源,如应用程序漏洞信息,电力费率和天气预报。更需要强大的数据中心基础架构管理(DCIM)工具来存储所有这些数据,进行分析并将其转化为可操作信息。你可以尝试具体划分一部分,但是这变得越来越困难。 AI和深度学习正在成为数据中心和关键基础设施管理的一部分。以下是一些较为显著的领域: 态势感知 活动仪表板具有趋势、相关性分析和推荐操作。 预防性的维护 深度学习用于识别和关联预测电源、存储或网络连接故障的数据。这样,在进行维护的同时,运营商可以动员并主动将工作负载移至更安全的区域。 根本原因分析 机器学习用于追踪几个服务故障的根本原因。这被学习并用于将来的预防性维护。 网络安全和入侵检测 机器学习和深度神经网络用于在应用传感器、访问控制系统和网络系统中发现异常模式,并提供更好的信噪比和主动缓解的措施。学习神经网络用于不断提高企业的安全态势和管理相关问题的能力。 自动化 “窄定义AI” 配备各种自动缓解技术,并产生类似于汽车在看到即将碰撞时刹车的动作。 深度神经网络和机器学习算法将随着时间的推移而改善,从而实现更高的效率和性能,以配合快速增长的应用程序工作负载。 随着这一切的诞生与发展,毫无疑问,未来AI将对企业如何管理数据中心产生十分巨大的影响。 本文转自d1net(转载)

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册