首页 文章 精选 留言 我的

精选列表

搜索[分代式],共10000篇文章
优秀的个人博客,低调大师

一分钟学会使用9-patch

背景 之前项目开发一般都是写逻辑,UI方面的操作用的比较少。 图片也是直接使用设计师提供的。 因此一般情况下不需要用到9-patch图。 然而,最近项目中分配给我的功能用到了。 因此,记录一下以便给其他没有接触过的开发者参考。 什么是9-patch 引用官方的一段描述 Draw 9-patch 工具是 Android Studio 中包含的一种 WYSIWYG(所见即所得)编辑器,利用此工具,您可以创建能够自动调整大小以适应视图内容和屏幕尺寸的位图图像。图像的选定部分可以根据图像内绘制的指示器在水平或竖直方向上调整比例。 根据上面的描述我们可以知道,当我们要求我们的图片能够自动调整大小以适应视图内容时,我们才需要用到9-patch图。 如何绘制9-patch 这边以Android Studio为例,进行实际说明如何绘制9-patch图。 确定要创建9-patch的图片,这里以下面图片中的chat_bg.png为例。 右键点击您想要用来创建 NinePatch 图像的 PNG 图像,然后点击 Create 9-patch file。 点击之后会弹框,如果名字保持不变,结果如下。 这个时候如果运行,会提示资源重复。所以我们要删除非9patch的原图。 好了,到这里前期准备就结束了。 接下来就需要做两个操作:1.确定横向和纵向拉伸。2.确定横向和纵向显示内容。 我们看下官网的一张图片说明 从图中可以得出如下结论: 左边控制纵向拉伸伸展区域。 上边控制横向拉伸伸展区域。 下边控制横向内容padding(可选) 右边控制纵向内容padding(可选) 具体操作通过下面的gif图来说明: gif图的操作可以归结如下: 点击Show patches,进行拉伸处理。 左边选取一块作为纵向拉伸伸展区域。 上边选取一块作为横向拉伸伸展区域。 点击Show content。 右边选取纵向内容区域。 下边选取横向内容区域。 通过gif图可以很方便的看到所谓的画线操作其实是拖拉操作。 并不是说要像画笔那样去画出来。

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

虚拟 router 原理分析- 每天5分钟玩转 OpenStack(101)

上一节我们创建了虚拟路由器&ldquo;router_100_101&rdquo;,并通过 ping 验证了 vlan100 和 vlan101 已经连通。 本节将重点分析其中的原理。 首先我们查看控制节点的 linux bridge 结构发生了什么变化。 vlan101 的 bridge 上多了一个 tape17162c5-00,从命名上可以推断该 TAP 设备对应 router_100_101 的 interface (e17162c5-00fa)。 vlan100 的 bridge 上多了一个 tapd568ba1a-74,从命名上可以推断该 TAP 设备对应 router_100_101 的 interface (d568ba1a-740e)。 当前网络结构如图所示: 但发现一个问题:两个 TAP 设备上并没有配置相应的 Gateway IP。 如果没有 Gateway IP,router_100_101 是如何完成路由的呢? 答案是: l3 agent 会为每个 router 创建了一个 namespace,通过 veth pair 与 TAP 相连,然后将 Gateway IP 配置在位于 namespace 里面的 veth interface 上,这样就能提供路由了。 通过 ip netns 查看 namespace: router 对应的 namespace 命名为 qrouter-<router id>。 通过 ip netns exec <namespace name> ip a 命令查看 router_100_101 namespace 中的 veth interface 配置。 namespace 中有两个 interface: qr-e17162c5-00 上设置了 Gateway IP 172.16.101.1,与 root namespace 中的 tape17162c5-00 组成 veth pair。 qr-d568ba1a-74 上设置了 Gateway IP 172.16.100.1,与 root namespace 中的 tapd568ba1a-74 组成 veth pair。 网络结构如图所示: namespace 中的路由表也保证了 subnet_172_16_100_0 和 subnet_172_16_101_0 之间是可以路由的。 分析到这里,我们已经搞清楚 router_100_101 是如何打通 vlan100 和 vlan 101 了。 但这里有一个关键问题需要进一步分析:为什么要把 router_100_101 放到 namespace 中? 下一节我们将详细分析这个问题。 本文转自CloudMan6 51CTO博客,原文链接:http://blog.51cto.com/cloudman/1863247

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

一分钟ECS上搭建云HBase Thriftserver

​ 这里详细的介绍下客户自己搭建thriftserver的流程以及步骤;通过一步步的演示达到分钟级别在ecs上自构建Thriftserver流程;Thrfitserver是接收各种语言的client的请求,可以是:java/c++/php/python and so on;thriftserver接收客户端请求,然后等于做一层proxy机制给HBbase server 发送请求,然后等待响应给client; ​ 一:搭建前我们需要确定好几个需要的东西: ​ 1.jdk(java运行环境,因为Thriftserve是java写的);这里以1.8版本为例子;如何部署java环境谷歌一坨资料;这里不在赘述; [root@xxxxx apps]# java -version java version "1.

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

【iOS 开发】3分钟搭建 App Store 动态审核开关

我曾经在一篇文章中写过,希望大家不要欺骗 App Store Review Team,但是近来的 Uber 审核事件,以及发生在我个人身上的 审核团队不对我的长篇详细辩解作正面回答,且无限期推迟我的 App 审核的事情发生后,我彻底对这个团队没有了尊重,作为能力有限的个人开发者,我会选择通过一定的技术手段来欺骗审核团队。 审核团队身在北美,如果你的 app 不需要支持北美地区,并且有地理位置获取权限,那么直接通过地理位置进行开关即可 通过系统时区判断对方位置已经被证明不可行 预判审核时间,进行硬编码的开关,可能会导致审核比较快的时候,项目已经上线,但是无法发布给用户(审核开关还是打开的状态,用户得不到审核不允许通过的功能) 这里介绍一个为没有后台可用的 app 快速搭建动态审核开关的方法: 新建一个 public 的 GitHub Repo,仓库里面有没有东西都无所谓,重点在于你可以通过新建、删除仓库的方式,来远程控制一个开关:即这个仓库的地址(比如 www.github.com/yourName/repoName)是否可以访问 如果你的 app 不能访问 www.github.com 这个 host(比如断网),或者可以访问这个 host 并且你的仓库地址也可以成功访问,则说明正在审核,你可以关掉一些可能导致你的 app 被拒的功能;如果 GitHub 可以访问,但是你的仓库不能访问,说明你已经在审核通过之后删掉了这个仓库,则用户手里的 app 可以解锁那些特定的功能(www.github.com 目前没有被墙,但是 www.gist.github.com 被墙,所以才用新建仓库而不是新建 gist 的方式) 因为 app 可能还会更新,不能因为你下一个版本的 app 正在审核,就把之前版本的 app 里面的功能禁用,所以你新建的仓库需要最好可以和版本号建立一个映射,比如一个叫 happy 的 app,现在上传了 0.0.1 版本的构建,那么仓库名可以是 happy001,下一个版本用 happy002 这个名字建立仓库。 每次都需要用户访问 github 才可以解锁正常功能,不是一个很好的解决方式,可以预估一个相对宽松的审核时间,比如预估 10 天后 app 一定是可以通过审核的,那么可以硬编码一下,时间过了 10 天之后,就不用动态审核的机制,直接解锁那些可能导致被拒的功能。 上面介绍的方法,能不用就不用,能少用就少用,还需自行评估风险哦~ 下面使用 Swift + Alamofire 提供一份代码示例 import UIKit import Alamofire class Cheater { // 审核开关自动配置 class func autoConfig() { Alamofire.request("www.github.com/yourName/repoName") .validate().responseData { response in switch response.result { case .success: print("repo exist") setIsOff(0) case .failure(let error): print(error) setIsOff(1) } } } class func setIsOff(_ value:Int) { if value == 1 { print("已通过审核") }else { print("未通过审核") } UserDefaults.standard.set(value, forKey: "wbdswitch") } class func isOff() -> Bool { if dateIsAfter(20171115) { return true } let num = UserDefaults.standard.integer(forKey: "wbdswitch") return (num == 1) } } fileprivate func dateIsAfter(_ dateNum: Int) -> Bool { let formatter = DateFormatter() formatter.dateFormat = "YYYYMMdd" formatter.timeZone = TimeZone(abbreviation: "CHN") if let current = Int(formatter.string(from: Date())), current >= dateNum { return true }else { return false } } 上面这份代码,实现了利用 www.github.com/yourName/repoName 这个地址进行开关的功能,并且在日期晚于 2017年11月15日时,会直接解锁功能。你可以把可能导致 App 被拒的功能放在如下代码块里: if Cheater.isOff() { print("审核已经通过") } 并通过 Cheater.autoConfig() 来进行开关的配置,可以放在 AppDelegate 或者其他 selector 里面。

资源下载

更多资源
Mario

Mario

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

Nacos

Nacos

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

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册