0%

在web开发中有一个需求,可以根据图片内容动态提取主色改变背景颜色。满足需求的常用第三方库有node-vibrantrgbasterColor Thief

1. node-vibrant

添加依赖库
1
"node-vibrant": "^3.1.5",
导入import
1
import * as Vibrant from 'node-vibrant'
Read more »

ButterKnife 是一款知名老牌 Android 开发框架,通过注解绑定视图,避免了 findViewById() 的操作,广受好评!由于它是在编译时对注解进行解析完成相关代码的生成,所以在项目编译时会略耗时,但不会影响运行时的性能。

简单使用

在Activity中通过注解@BindView绑定视图,@onClick绑定事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class MainActivity extends AppCompatActivity {
@BindView(R.id.tv_title)
TextView title;

@OnClick(R.id.bt)
public void onClick() {
title.setText("hello world");
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this); // 绑定
}
}

原理

ButterKnife和Activity是从ButterKnife.bind(this)建立绑定关系。

Read more »

当View被快速多次点击,onClickListener事件的onClick(View view)会执行多次。

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
/**
* A {@linkplain View.OnClickListener click listener} that debounces multiple clicks posted in the
* same frame. A click on one button disables all buttons for that frame.
*/
public abstract class DebouncingOnClickListener implements View.OnClickListener {
private static final Runnable ENABLE_AGAIN = () -> enabled = true;
private static final Handler MAIN = new Handler(Looper.getMainLooper());

static boolean enabled = true;

@Override public final void onClick(View v) {
if (enabled) {
enabled = false;

// Post to the main looper directly rather than going through the view.
// Ensure that ENABLE_AGAIN will be executed, avoid static field {@link #enabled}
// staying in false state.
MAIN.post(ENABLE_AGAIN);

doClick(v);
}
}

public abstract void doClick(View v);
}

来源:butterknife中DebouncingOnClickListener

注解

定义在类、方法、字段 、参数前的”注释“。注解(annotation)可以被编译器打包进class文件。

元注解

有一些注解可以修饰其他注解,这些注解就称为元注解(meta annotation)。常用 元注解有@Retention、@ Target、@ Repeatable、@ MustBeDocumented

  • @Target 指定可以用该注解标注的元素的可能的类型(类、函数、属性、表达式等);
  • @Retention 指定该注解是否存储在编译后的 class 文件中,以及它在运行时能否通过反射可见 (默认都是 true);
  • @Repeatable 允许在单个元素上多次使用相同的该注解;
  • @MustBeDocumented 指定该注解是公有 API 的一部分,并且应该包含在生成的 API 文档中显示的类或方法的签名中。
1
2
3
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class Subscribe(val threadMode: ThreadMode = ThreadMode.POSTING)
Read more »

注解

定义在类、方法、字段 、参数前的”注释“。注解(annotation)可以被编译器打包进class文件。

元注解

有一些注解可以修饰其他注解,这些注解就称为元注解(meta annotation)。常用 元注解有@Retention、@ Target、@ Inherited、@ Documented

@Retention

RetentionPolicy的枚举,表示注解在何时生效:

Read more »

1.泛型

Dart中泛型 (或 参数化) 类型使用<…> 符号表示。通常情况下,使用一个字母来代表类型参数, 例如 E, T, S, K, 和 V 等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 使用集合字面量
var names = <String>['Seth', 'Kathy', 'Lars'];
var uniqueNames = <String>{'Seth', 'Kathy', 'Lars'};
var pages = <String, String>{
'index.html': 'Homepage',
'robots.txt': 'Hints for web robots',
'humans.txt': 'We are people, not machines'
};

// 运行时中的泛型集合
var names = List<String>();
names.addAll(['Seth', 'Kathy', 'Lars']);
print(names is List<String>); // true
var views = Map<int, View>(); // _InternalLinkedHashMap<int, View>

泛型函数

1
2
3
4
5
6
T first<T>(List<T> ts) {
// Do some initial work or error checking, then...
T tmp = ts[0];
// Do some additional checking or processing...
return tmp;
}

类的泛型

1
2
3
4
5
6
class Location<T> {
T x;
T y;

Location(this.x, this.y);
}
Read more »

1.类

Dart 是一种基于类和 mixin 继承机制的面向对象的语言。 每个对象都是一个类的实例,所有的类都继承于 Object 。 基于 Mixin 继承 意味着每个类(除 Object 外) 都只有一个超类, 一个类中的代码可以在其他多个继承类中重复使用。类的定义和Java、TypeScript类似,定义类用class关键字

1
2
3
4
5
6
7
8
9
class Point {
num x;
num y;
}

void main() {
var point = Point(); // Dart中省略 new 关键字
point.x = 4; // Use the setter method for x.
}

构造函数

当通过类创建一个对象时,会调用这个类的构造方法。通过创建一个与其类同名的函数来声明构造函数。

在没有声明构造函数的情况下, Dart 会提供一个默认的构造函数。 默认构造函数没有参数并会调用父类的无参构造函数。

1
2
3
4
5
6
7
8
9
class Point {
num x, y;

Point(num x, num y) {
// 还有更好的方式来实现下面代码
this.x = x;
this.y = y;
}
}
Read more »

1.函数

Dart 是一门真正面向对象的语言, 甚至其中的函数也是对象,并且有它的类型 Function 。 这也意味着函数可以被赋值给变量或者作为参数传递给其他函数。 也可以把 Dart 类的实例当做方法来调用。

1
2
3
int sum(num num1, num num2) {
return num1 + num2;
}

如果函数中只有一句表达式,可以使用简写语法:
1
sum(num1, num2) => num1 + num2;

=> expr 语法是 { return expr; } 的简写。 => 符号 有时也被称为 箭头 语法。

提示: 在箭头 (=>) 和分号 (;) 之间只能使用一个 表达式 ,不能是 语句 。 例如:不能使用 if 语句 ,但是可以是用 条件表达式.

函数有两种参数类型: required 和 optional。 required 类型参数在参数最前面, 随后是 optional 类型参数。 命名的可选参数也可以标记为 “@ required”。

可选参数

可选参数可以是命名参数或者位置参数,但一个参数只能选择其中一种方式修饰。可选参数可以分为 命名可选参数位置可选参数
定义方式:

1
2
命名可选参数: {param1, param2, ...}
位置可选参数: [param1, param2, ...]

Read more »

1.变量

可以通过显式声明指定类型的方式,创建一个变量并进行初始化。

1
String name = 'Bob';

dart中变量支持类型推导,用var创建一个变量并进行初始化:
1
var name = 'Bob';

name 变量的类型被推断为 String。 var的错误用法:
1
2
var name = 'Bob';
name = 18; // error 不可以将int赋值给一个String类型

如果对象不限定为单个类型,可以指定为 对象类型动态类型
1
2
3
4
dynamic name = 'Bob';
print(name.runtimeType); // String
name = 18;
print(name.runtimeType); // int

提示: 本页局部变量遵守 风格建议指南 使用 var。 没有使用指定类型的方式。

默认值

未初始化的变量默认值是 null。即使变量是数字 类型默认值也是 null,因为在 Dart 中一切都是对象,数字类型 也不例外。

Final 和 Const
Read more »

1. 简介

chrome扩展程序(常称插件)是一个用Web技术开发、用来增强浏览器功能的软件,chrome浏览器扩展开发算是相当简单的,基本只要掌握HTML+CSS+Javascript,即可快速开发一个属于你的chrome插件!它其实就是一个由HTML、CSS、JS、图片等资源组成的一个.crx后缀的压缩包。

chrome插件提供了很多实用API供我们使用,包括但不限于:

书签控制;
下载控制;
窗口控制;
标签控制;
网络请求控制,
各类事件监听;
自定义原生菜单;
完善的通信机制;

2. 文件目录

Read more »