Android各种Background

setBackground、setBackgroundDrawable、setBackgroundResource、setBackgroundColor 的区别

在 Android 开发中,我们常常遇到对 View 组件的背景颜色或者背景图片进行一些动态的设置。那么常见的这四种方法往往分不清楚,下面我们来看下它们之间的不同之处。
1.setBackground(Drawable background) 方法的参数是一个Drawable对象.该方法用于设置view组件的背景图片。其中 Drawable 对象可以这样获取:

1
Drawable background = getResources().getDrawable(R.drawable.xxx);

2.setBackgroundDrawable(Drawable background) 方法跟setBackground大体相同。

3.setBackgroundResource(int resId) 方法的参数是一个组件的id值。该方法也是用于加载组件的背景图片的。

4.setBackgroundColor(Color.XXX) 方法参数为一个 Color 类的静态常量,它是用来设置背景颜色的方法。

我们在动态设置背景颜色或图片时,有可能该背景颜色有圆角,如果我们直接设置背景颜色,那么原先的圆角就会没有了。所以,如果背景颜色有圆角的话,就不能直接设置了。我们使用如下的方法解决。

1
2
3
4
5
Drawable drawable = tv.getBackground();
if (null != drawable && drawable instanceof GradientDrawable) {
// 这种情况是设置了带shape的背景颜色
((GradientDrawable)drawable).setColor(Color.GREEN);
}

android EditText 延迟搜索

1.Handler
2.RxJava

#Handler
监听EditText的输入,每当文本变化,先检查Handler当前有无未处理的消息,有则移除该消息,然后用sendEmptyMessageDelayed再发哟天延迟消息,
如果文本超过延迟时间没有变化,该延迟消息就可以成功执行。

#例:

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
private final int RC_SEARCH = 1;
private final int INTERVAL = 300; //输入时间间隔为300毫秒
private EditText mEtHandler;

private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == RC_SEARCH) {
handlerSearch();
}
}
};

mEtHandler.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}

@Override
public void afterTextChanged(Editable s) {

if (mHandler.hasMessages(RC_SEARCH)) {
mHandler.removeMessages(RC_SEARCH);
}
mHandler.sendEmptyMessageDelayed(RC_SEARCH, INTERVAL);
}
});

#RxJava
学习了RxJava后发现还有更简便的方法,即使用debounce操作符处理不断产生的文本变化事件

debounce操作符对源Observable每产生一个结果后,如果在规定的间隔时间内没有别的结果产生,则吧这个结果提交给订阅者处理,否则忽略结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private EditText mEtRxJava;

private final int INTERVAL = 300; //输入时间间隔为300毫秒

RxTextView.textChangeEvents(mEtRxJava)
.debounce(INTERVAL, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<TextViewTextChangeEvent>() {
@Override
public void onCompleted() {

}

@Override
public void onError(Throwable e) {

}

@Override
public void onNext(TextViewTextChangeEvent textViewTextChangeEvent) {
rxJavaSearch();
}
});

Go语言中 new()和make()的区别详解

#概述
Go语言中的new和make 一直是新手比较容易混淆的东西,咋一看很相似,接下来我们来分析两者的区别

#new的主要特性

首先new是内建函数,你可以从 http://golang.org/pkg/builtin/#new 这儿看到它,它的定义也很简单:

1
2
代码如下:
func new(Type) *Type

官方文档对于它的描述是:

内建函数new用来分配内存,它的第一个参数是类型,不是一个值,它的返回值是一个指向新分配类型零值的指针

根据这段描述,我们可以自己实现一个类似的new的功能

1
2
3
4
5
6
代码如下:
func newInt() *Int{
var i int
return &i
}
someint :=newInt()

这个函数的功能跟 someInt :=new(int) 一摸一样,所以在我们自定义new开头的函数时,出于约定应该返回类型的指针。

#make的主要特性

make也是内建函数,你可以从http://golang.org/pkg/builtin/#make 这儿看到它,它的定义比 new 多了一个参数,返回值也不同:

1
2
代码如下:
func make(Type,size INtergerType)Type

官方文档对于它的描述是:

内建函数make用来为slie ,map 或 chan 类型分配内存和初始化一个对象(注意:只能用在这三种类型上),跟new类似,第一个参数也是一个类型而不是一个值,
跟new不同的是,make返回的类型的引用而不是指针,而返回值也依赖于具体传入的类型,具体说明如下:

代码如下:

Slice :第二个参数size指定了它的长度,它的容易和长度相同。
你可以传入第三个参数来指定不同的容量值,但必须不能长度值小。
比如 make([]int,0,10)
Map:根据size大小来初始化分配内存,不过分配后的map长度为0,如果size被忽略了,那么会在初始化分配内存时分配一个小尺寸的内存
Channel:管道缓冲区依据缓冲区容量被初始化。如果容量为0或者忽略容量。管道是没有缓冲区的

总结

new 的作用是初始化一个指向类型的指针(*T),make 的作用是为 slice,map 或 chan 初始化并返回引用(T)。

Go语言中 new()和make()的区别详解

#概述
Go语言中的new和make 一直是新手比较容易混淆的东西,咋一看很相似,接下来我们来分析两者的区别

#new的主要特性

首先new是内建函数,你可以从 http://golang.org/pkg/builtin/#new 这儿看到它,它的定义也很简单:

1
2
代码如下:
func new(Type) *Type

官方文档对于它的描述是:

内建函数new用来分配内存,它的第一个参数是类型,不是一个值,它的返回值是一个指向新分配类型零值的指针

根据这段描述,我们可以自己实现一个类似的new的功能

1
2
3
4
5
6
代码如下:
func newInt() *Int{
var i int
return &i
}
someint :=newInt()

这个函数的功能跟 someInt :=new(int) 一摸一样,所以在我们自定义new开头的函数时,出于约定应该返回类型的指针。

#make的主要特性

make也是内建函数,你可以从http://golang.org/pkg/builtin/#make 这儿看到它,它的定义比 new 多了一个参数,返回值也不同:

1
2
代码如下:
func make(Type,size INtergerType)Type

官方文档对于它的描述是:

内建函数make用来为slie ,map 或 chan 类型分配内存和初始化一个对象(注意:只能用在这三种类型上),跟new类似,第一个参数也是一个类型而不是一个值,
跟new不同的是,make返回的类型的引用而不是指针,而返回值也依赖于具体传入的类型,具体说明如下:

代码如下:

Slice :第二个参数size指定了它的长度,它的容易和长度相同。
你可以传入第三个参数来指定不同的容量值,但必须不能长度值小。
比如 make([]int,0,10)
Map:根据size大小来初始化分配内存,不过分配后的map长度为0,如果size被忽略了,那么会在初始化分配内存时分配一个小尺寸的内存
Channel:管道缓冲区依据缓冲区容量被初始化。如果容量为0或者忽略容量。管道是没有缓冲区的

总结

new 的作用是初始化一个指向类型的指针(*T),make 的作用是为 slice,map 或 chan 初始化并返回引用(T)。

Go sync包 WaitGroup使用

sync.WaitGroup用途:
它能够一直等到所有的goroutine执行完成,
并且阻塞主线程的执行,直到所有的goroutine执行完成
注意:它们的执行结果有没有顺序的,调度器不能保证多个goroutine执行次序,且进程退出时不会等待它们结束。

waiGroup共有三个方法:Add(delta int)Done()Wait()
Add:添加或者减少等待goroutine的数量
Done:相当于Add(-1)
Wait:执行阻塞,知道直到所有的WaitGroutine数量变成0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main

import (
"sync"
"time"
"fmt"
)

func main() {
var wg sync.WaitGroup
for i := 0; i > 5; i = i + 1 {
wg.Add(1)
go func(n int) {
defer wg.Add(-1)
EchoNumber(n)

}(i)
}
wg.Wait()
}
func EchoNumber(i int) {
time.Sleep(3e9)
fmt.Println(i)
}

golang中的同步是通过sync.WaitGroup来实现的,
WaitGroup的功能:它实现了一个类似队列的结构,
可以一直向队列添加任务,当任务完成后便从队列中删除,
如果队列中的任务没有完全完成,可以通过Wait()函数来出发阻塞,
防止程序继续进行,直到所有的队列任务都完成为止。
WaitGroup的特点是Wait()可以用来阻塞直到队列中的所有任务都完成才解除阻塞,
而不需要Sleep一个固定的时间来等待,但是其缺点是无法指定固定的goroutine数目,
可能通过使用channel解决此问题。

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
package main

import (
"fmt"
"sync"
)

var waitgroup sync.WaitGroup

func Afunction(shownum int) {

fmt.Println(shownum)
//任务队列,将任务队列中的任务数量-1,其实.Done就是.Add(-1)
waitgroup.Done()

}

func main() {
for i := 0; i < 10; i++ {
//每创建一个goroutine,就把任务队列中的任务的数量+1
waitgroup.Add(1)
go Afunction(i)
}
//.Wait()这里发生阻塞,直到队列中所有的任务结束就会解除阻塞
waitgroup.Wait()
}