<(|怎么下上海时时乐开奖走势图走势图带人玩求求 7557365|)&gt

Go 语言简介(下)— 特性&转载&
原文地址:/n/163075/本系列博客为个人学习收藏,转载部分均贴出原文路径。《Go 语言简介(上):语法》  goroutine  GoRoutine 主要是使用 go 关键字来调用函数,你还可以使用匿名函数,如下所示:package mainimport &fmt& func f (msg string) {
fmt.Println (msg)} func main (){
go f (&goroutine&)
go func (msg string) {
fmt.Println (msg)
}(&going&)}  我们再来看一个示例,下面的代码中包括很多内容,包括时间处理,随机数处理,还有 goroutine 的代码。如果你熟悉C语言,你应该会很容易理解下面的代码。  你可以简单的把 go 关键字调用的函数想像成 pthread_create。下面的代码使用 for 循环创建了 3 个线程,每个线程使用一个随机的 Sleep 时间,然后在 routine ()函数中会输出一些线程执行的时间信息。package main import &fmt&import &time&import &math/rand& func routine (name string, delay time.Duration) {
t0 := time.Now ()
fmt.Println (name, & start at &, t0)
time.Sleep(delay)
t1 := time.Now ()
fmt.Println (name, & end at &, t1)
fmt.Println (name, & lasted &, t1.Sub(t0))} func main () {
//生成随机种子
rand.Seed (time.Now () .Unix ())
var name string
for i:=0; i&3; i++{
name = fmt.Sprintf(&go_%02d&, i) //生成 ID
//生成随机等待时间,从0-4秒
go routine (name, time.Duration (rand.Intn (5)) * time.Second)
//让主进程停住,不然主进程退了,goroutine 也就退了
var input string
fmt.Scanln (&input)
fmt.Println (&done&)}  运行的结果可能是:go_00
2012-11-04 19:46:35.8974894 +0800 +0800go_01
2012-11-04 19:46:35.8974894 +0800 +0800go_02
2012-11-04 19:46:35.8974894 +0800 +0800go_01
2012-11-04 19:46:36.8975894 +0800 +0800go_01
1.0001sgo_02
2012-11-04 19:46:38.8987895 +0800 +0800go_02
3.0013001sgo_00
2012-11-04 19:46:39.8978894 +0800 +0800go_00
4.0004s  goroutine 的并发安全性  关于 goroutine,我试了一下,无论是 Windows 还是 Linux,基本上来说是用操作系统的线程来实现的。不过,goroutine 有个特性,也就是说,如果一个 goroutine 没有被阻塞,那么别的 goroutine 就不会得到执行。这并不是真正的并发,如果你要真正的并发,你需要在你的 main 函数的第一行加上下面的这段代码:import &runtime&...runtime.GOMAXPROCS (4)  还是让我们来看一个有并发安全性问题的示例(注意:我使用了C的方式来写这段 Go 的程序)  这是一个经常出现在教科书里卖票的例子,我启了 5 个 goroutine 来卖票,卖票的函数 sell_tickets 很简单,就是随机的 sleep 一下,然后对全局变量 total_tickets 作减一操作。package main import &fmt&import &time&import &math/rand&import &runtime& var total_tickets int32 = 10; func sell_tickets (i int){
if total_tickets & 0 { //如果有票就卖
time.Sleep( time.Duration (rand.Intn (5)) * time.Millisecond)
total_tickets-- //卖一张票
fmt.Println (&id:&, i, &
ticket:&, total_tickets)
}} func main () {
runtime.GOMAXPROCS (4) //我的电脑是 4 核处理器,所以我设置了4
rand.Seed (time.Now () .Unix ()) //生成随机种子
for i := 0; i & 5; i++ { //并发 5 个 goroutine 来卖票
go sell_tickets (i)
//等待线程执行完
var input string
fmt.Scanln (&input)
fmt.Println (total_tickets, &done&) //退出时打印还有多少票}  这个程序毋庸置疑有并发安全性问题,所以执行起来你会看到下面的结果:$go run sell_tickets.goid: 0
ticket: 9 id: 0
ticket: 8 id: 4
ticket: 7 id: 1
ticket: 6 id: 3
ticket: 5 id: 0
ticket: 4 id: 3
ticket: 3 id: 2
ticket: 2 id: 0
ticket: 1 id: 3
ticket: 0 id: 1
ticket: -1 id: 4
ticket: -2 id: 2
ticket: -3 id: 0
ticket: -4 -4 done  可见,我们需要使用上锁,我们可以使用互斥量来解决这个问题。下面的代码,我只列出了修改过的内容:package mainimport &fmt&import &time&import &math/rand&import &sync&import &runtime& var total_tickets int32 = 10;var mutex = &sync.Mutex{} //可简写成:var mutex sync.Mutex func sell_tickets (i int){
for total_tickets&0 {
mutex.Lock()
if total_tickets & 0 {
time.Sleep( time.Duration (rand.Intn (5)) * time.Millisecond)
total_tickets--
fmt.Println (i, total_tickets)
mutex.Unlock ()
}}.............  原子操作  说到并发就需要说说原子操作,相信大家还记得我写的那篇《无锁队列的实现》一文,里面说到了一些 CAS – CompareAndSwap 的操作。Go 语言也支持。你可以看一下相当的文档  我在这里就举一个很简单的示例:下面的程序有 10 个 goroutine,每个会对 cnt 变量累加 20 次,所以,最后的 cnt 应该是 200。如果没有 atomic 的原子操作,那么 cnt 将有可能得到一个小于 200 的数。  下面使用了 atomic 操作,所以是安全的。package main import &fmt&import &time&import &sync/atomic& func main () {
var cnt uint32 = 0
for i := 0; i & 10; i++ {
go func () {
for i:=0; i&20; i++ {
time.Sleep(time.Millisecond)
atomic.AddUint32(&cnt, 1)
time.Sleep(time.Second)//等一秒钟等 goroutine 完成
cntFinal := atomic.LoadUint32(&cnt)//取数据
fmt.Println (&cnt:&, cntFinal)}  这样的函数还有很多,参看&go 的 atomic 包文档(被墙)  Channel 信道  Channal 是什么?Channal 就是用来通信的,就像 Unix 下的管道一样,在 Go 中是这样使用 Channel 的。  下面的程序演示了一个 goroutine 和主程序通信的例程。这个程序足够简单了。package main import &fmt& func main () {
//创建一个 string 类型的 channel
channel := make (chan string)
//创建一个 goroutine 向 channel 里发一个字符串
go func () { channel &- &hello& }()
msg := &- channel
fmt.Println (msg)}  指定 channel 的 buffer  指定 buffer 的大小很简单,看下面的程序:package mainimport &fmt& func main () {
channel := make (chan string, 2)
go func () {
channel &- &hello&
channel &- &World&
msg1 := &-channel
msg2 := &-channel
fmt.Println (msg1, msg2)}  Channel 的阻塞  注意,channel 默认上是阻塞的,也就是说,如果 Channel 满了,就阻塞写,如果 Channel 空了,就阻塞读。于是,我们就可以使用这种特性来同步我们的发送和接收端。  下面这个例程说明了这一点,代码有点乱,不过我觉得不难理解。package main import &fmt&import &time& func main () {
channel := make (chan string) //注意: buffer 为1
go func () {
channel &- &hello&
fmt.Println (&write /&hello/& done!&)
channel &- &World& //Reader 在 Sleep,这里在阻塞
fmt.Println (&write /&World/& done!&)
fmt.Println (&Write go sleep...&)
time.Sleep(3*time.Second)
channel &- &channel&
fmt.Println (&write /&channel/& done!&)
time.Sleep(2*time.Second)
fmt.Println (&Reader Wake up...&)
msg := &-channel
fmt.Println (&Reader: &, msg)
msg = &-channel
fmt.Println (&Reader: &, msg)
msg = &-channel //Writer 在 Sleep,这里在阻塞
fmt.Println (&Reader: &, msg)}  上面的代码输出的结果如下:Reader Wake up...Reader:
hellowrite &hello& done!write &World& done!Write go sleep...Reader:
Worldwrite &channel& done!Reader:
channel  Channel 阻塞的这个特性还有一个好处是,可以让我们的 goroutine 在运行的一开始就阻塞在从某个 channel 领任务,这样就可以作成一个类似于线程池一样的东西。关于这个程序我就不写了。我相信你可以自己实现的。  多个 Channel 的 selectpackage mainimport &time&import &fmt& func main () {
//创建两个 channel - c1 c2
c1 := make (chan string)
c2 := make (chan string)
//创建两个 goruntine 来分别向这两个 channel 发送数据
go func () {
time.Sleep(time.Second * 1)
c1 &- &Hello&
go func () {
time.Sleep(time.Second * 1)
c2 &- &World&
//使用 select 来侦听两个 channel
for i := 0; i & 2; i++ {
case msg1 := &-c1:
fmt.Println (&received&, msg1)
case msg2 := &-c2:
fmt.Println (&received&, msg2)
}}  注意:上面的 select 是阻塞的,所以,才搞出 ugly 的 for i &2这种东西。  Channel select 阻塞的 Timeout  解决上述那个 for 循环的问题,一般有两种方法:一种是阻塞但有 timeout,一种是无阻塞。我们来看看如果给 select 设置上 timeout 的。for {
timeout_cnt := 0
case msg1 := &-c1:
fmt.Println (&msg1 received&, msg1)
case msg2 := &-c2:
fmt.Println (&msg2 received&, msg2)
&-time.After (time.Second * 30):
fmt.Println (&Time Out&)
timout_cnt++
if time_cnt & 3 {
}}  上面代码中高亮的代码主要是用来让 select 返回的,注意 case 中的 time.After 事件。  Channel 的无阻塞  好,我们再来看看无阻塞的 channel,其实也很简单,就是在 select 中加入 default,如下所示:for {
case msg1 := &-c1:
fmt.Println (&received&, msg1)
case msg2 := &-c2:
fmt.Println (&received&, msg2)
default: //default 会导致无阻塞
fmt.Println (&nothing received!&)
time.Sleep(time.Second)
}}  Channel 的关闭  关闭 Channel 可以通知对方内容发送完了,不用再等了。参看下面的例程:package main import &fmt&import &time&import &math/rand& func main () {
channel := make (chan string)
rand.Seed (time.Now () .Unix ())
//向 channel 发送随机个数的 message
go func () {
cnt := rand.Intn (10)
fmt.Println (&message cnt :&, cnt)
for i:=0; i& i++{
channel &- fmt.Sprintf(&message-%2d&, i)
close(channel) //关闭 Channel
var more bool = true
var msg string
for more {
//channel 会返回两个值,一个是内容,一个是还有没有内容
case msg, more = &- channel:
fmt.Println (msg)
fmt.Println (&channel closed!&)
}}  定时器  Go 语言中可以使用 time.NewTimer 或 time.NewTicker 来设置一个定时器,这个定时器会绑定在你的当前 channel 中,通过 channel 的阻塞通知机器来通知你的程序。  下面是一个 timer 的示例。package main import &time&import &fmt& func main () {
timer := time.NewTimer (2*time.Second)
&- timer.C
fmt.Println (&timer expired!&)}  上面的例程看起来像一个 Sleep,是的,不过 Timer 是可以 Stop 的。你需要注意 Timer 只通知一次。如果你要像C中的 Timer 能持续通知的话,你需要使用 Ticker。下面是 Ticker 的例程:package main import &time&import &fmt& func main () {
ticker := time.NewTicker (time.Second)
for t := range ticker.C {
fmt.Println (&Tick at&, t)
}}  上面的这个 ticker 会让你程序进入死循环,我们应该放其放在一个 goroutine 中。下面这个程序结合了 timer 和 tickerpackage main import &time&import &fmt& func main () {
ticker := time.NewTicker (time.Second)
go func () {
for t := range ticker.C {
fmt.Println (t)
//设置一个 timer,10钞后停掉 ticker
timer := time.NewTimer (10*time.Second)
&- timer.C
ticker.Stop ()
fmt.Println (&timer expired!&)}  Socket 编程  下面是我尝试的一个 Echo Server 的 Socket 代码,感觉还是挺简单的。  Server 端package main import (
&io&) const RECV_BUF_LEN = 1024 func main () {
listener, err := net.Listen(&tcp&, &0.0.0.0:6666&)//侦听在 6666 端口
if err != nil {
panic (&error listening:&+err.Error ())
fmt.Println (&Starting the server&)
conn, err := listener.Accept() //接受连接
if err != nil {
panic (&Error accept:&+err.Error ())
fmt.Println (&Accepted the Connection :&, conn.RemoteAddr ())
go EchoServer (conn)
}} func EchoServer (conn net.Conn) {
buf := make ([]byte, RECV_BUF_LEN)
defer conn.Close()
n, err := conn.Read(buf);
switch err {
conn.Write( buf[0:n] )
case io.EOF:
fmt.Printf(&Warning: End of data: %s /n&, err);
fmt.Printf(&Error: Reading data : %s /n&, err);
}}  Client 端package main import (
&net&) const RECV_BUF_LEN = 1024 func main () {
conn,err := net.Dial (&tcp&, &127.0.0.1:6666&)
if err != nil {
panic (err.Error ())
defer conn.Close()
buf := make ([]byte, RECV_BUF_LEN)
for i := 0; i & 5; i++ {
//准备要发送的字符串
msg := fmt.Sprintf(&Hello World, %03d&, i)
n, err := conn.Write([]byte (msg))
if err != nil {
println (&Write Buffer Error:&, err.Error ())
fmt.Println (msg)
//从服务器端收字符串
n, err = conn.Read(buf)
if err !=nil {
println (&Read Buffer Error:&, err.Error ())
fmt.Println (string (buf[0:n]))
//等一秒钟
time.Sleep(time.Second)
}}  系统调用  Go 语言那么C,所以,一定会有一些系统调用。Go 语言主要是通过两个包完成的。一个是&os 包,一个是&syscall 包。(注意,链接被墙)  这两个包里提供都是 Unix-Like 的系统调用,syscall 里提供了什么 Chroot/Chmod/Chmod/Chdir…,Getenv/Getgid/Getpid/Getgroups/Getpid/Getppid…,还有很多如 Inotify/Ptrace/Epoll/Socket/…的系统调用。os 包里提供的东西不多,主要是一个跨平台的调用。它有三个子包,Exec(运行别的命令), Signal(捕捉信号)和 User(通过 uid 查 name 之类的)  syscall 包的东西我不举例了,大家可以看看《Unix 高级环境编程》一书。  os 里的取几个例:  环境变量package main import &os&import &strings&
func main () {
os.Setenv (&WEB&, &&) //设置环境变量
println (os.Getenv (&WEB&)) //读出来
for _, env := range os.Environ () { //穷举环境变量
e := strings.Split(env, &=&)
println (e[0], &=&, e[1])
}}  执行命令行  下面是一个比较简单的示例package mainimport &os/exec&import &fmt&func main () {
cmd := exec.Command (&ping&, &127.0.0.1&)
out, err := cmd.Output ()
if err!=nil {
println (&Command Error!&, err.Error ())
fmt.Println (string (out))}  正规一点的用来处理标准输入和输出的示例如下:package main import (
&os/exec&) func main () {
cmd := exec.Command (&tr&, &a-z&, &A-Z&)
cmd.Stdin = strings.NewReader (&some input&)
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run ()
if err != nil {
log.Fatal (err)
fmt.Printf(&in all caps: %q/n&, out.String ())}  命令行参数  Go 语言中处理命令行参数很简单:(使用 os 的 Args 就可以了)func main () {
args := os.Args
fmt.Println (args) //带执行文件的
fmt.Println (args[1:]) //不带执行文件的}  在 Windows 下,如果运行结果如下:  C:/Projects/Go&go run args.go aaa bbb ccc ddd  [C:/Users/haoel/AppData/Local/Temp/go-build/command-line-arguments/_  obj/a.out.exe aaa bbb ccc ddd]  [aaa bbb ccc ddd]  那么,如果我们要搞出一些像 mysql -uRoot -hLocalhost -pPwd 或是像 cc -O3 -Wall -o a a.c 这样的命令行参数我们怎么办?Go 提供了一个 package 叫 flag 可以容易地做到这一点package mainimport &flag&import &fmt& func main () {
//第一个参数是“参数名”,第二个是“默认值”,第三个是“说明”。返回的是指针
host := flag.String (&host&, &<&, &a host name &)
port := flag.Int(&port&, 80, &a port number&)
debug := flag.Bool (&d&, false, &enable/disable debug mode&)
//正式开始 Parse 命令行参数
flag.Parse ()
fmt.Println (&host:&, *host)
fmt.Println (&port:&, *port)
fmt.Println (&debug:&, *debug)}  执行起来会是这个样子:#如果没有指定参数名,则使用默认&#20540;$ go run flagtest.gohost: port: 80debug: false #指定了参数名后的情况$ go run flagtest.go -host=localhost -port=22 -dhost: localhostport: 22debug: true #用法出错了(如:使用了不支持的参数,参数没有=)$ go build flagtest.go$ ./flagtest -debug -host localhost -port=22flag provided but not defined: -debugUsage of flagtest:
-d=false: enable/disable debug mode
-host=&<&: a host name
-port=80: a port numberexit status 2  感觉还是挺不错的吧。  一个简单的 HTTP Server  代码胜过千言万语。呵呵。这个小程序让我又找回以前用C写 CGI 的时光了。(Go 的官方文档是《Writing Web Applications》)package main import (
&net/http&
&io/ioutil&
&path/filepath&) const http_root = &/home//& func main () {
http.HandleFunc (&/&, rootHandler)
http.HandleFunc (&/view/&, viewHandler)
http.HandleFunc (&/html/&, htmlHandler)
http.ListenAndServe (&:8080&, nil)} //读取一些 HTTP 的头func rootHandler (w http.ResponseWriter, r *http.Request) {
fmt.Fprintf (w, &rootHandler: %s/n&, r.URL.Path)
fmt.Fprintf (w, &URL: %s/n&, r.URL)
fmt.Fprintf (w, &Method: %s/n&, r.Method)
fmt.Fprintf (w, &RequestURI: %s/n&, r.RequestURI )
fmt.Fprintf (w, &Proto: %s/n&, r.Proto)
fmt.Fprintf (w, &HOST: %s/n&, r.Host)} //特别的 URL 处理func viewHandler (w http.ResponseWriter, r *http.Request) {
fmt.Fprintf (w, &viewHandler: %s&, r.URL.Path)} //一个静态网页的服务示例。(在 http_root 的 html 目录下)func htmlHandler (w http.ResponseWriter, r *http.Request) {
fmt.Printf(&htmlHandler: %s/n&, r.URL.Path)
filename := http_root &#43; r.URL.Path
fileext := filepath.Ext (filename)
content, err := ioutil.ReadFile (filename)
if err != nil {
fmt.Printf(&
404 Not Found!/n&)
w.WriteHeader (http.StatusNotFound)
var contype string
switch fileext {
case &.html&, &htm&:
contype = &text/html&
case &.css&:
contype = &text/css&
case &.js&:
contype = &application/javascript&
case &.png&:
contype = &image/png&
case &.jpg&, &.jpeg&:
contype = &image/jpeg&
case &.gif&:
contype = &image/gif&
contype = &text/plain&
fmt.Printf(&ext %s, ct = %s/n&, fileext, contype)
w.Header () .Set (&Content-Type&, contype)
fmt.Fprintf (w, &%s&, content)
最新教程周点击榜
微信扫一扫Android实战简易教程&四十五&(SlideSwitch-好看又实用的开关按钮)
开关按钮也是在项目中经常用到的控件,github上有开源的项目,我们研究下它的使用方法:1.SlideButton.java:[java]&view plaincopy/*&&*&Copyright&(C)&2015&Quinn&Chen&&*&&*&Licensed&under&the&Apache&License,&Version&2.0&(the&&License&);&&*&you&may&not&use&this&file&except&in&compliance&with&the&License.&&*&You&may&obtain&a&copy&of&the&License&at&&*&&*&&&&&&http://www.apache.org/licenses/LICENSE-2.0&&*&&*&Unless&required&by&applicable&law&or&agreed&to&in&writing,&software&&*&distributed&under&the&License&is&distributed&on&an&&AS&IS&&BASIS,&&*&WITHOUT&WARRANTIES&OR&CONDITIONS&OF&ANY&KIND,&either&express&or&implied.&&*&See&the&License&for&the&specific&language&governing&permissions&and&&*&limitations&under&the&License.&&*/&&package&com.leaking.&&&&import&android.animation.A&&import&android.animation.AnimatorListenerA&&import&android.animation.ValueA&&import&android.animation.ValueAnimator.AnimatorUpdateL&&import&android.content.C&&import&android.content.res.TypedA&&import&android.graphics.C&&import&android.graphics.C&&import&android.graphics.P&&import&android.graphics.R&&import&android.graphics.RectF;&&import&android.os.B&&import&android.os.L&&import&android.os.P&&import&android.support.v4.view.MotionEventC&&import&android.util.AttributeS&&import&android.view.MotionE&&import&android.view.V&&import&android.view.animation.AccelerateDecelerateI&&&&import&com.example.slideswitch.R;&&&&public&class&SlideSwitch&extends&View&{&&&&&&&&public&static&final&int&SHAPE_RECT&=&1;&&&&&&public&static&final&int&SHAPE_CIRCLE&=&2;&&&&&&private&static&final&int&RIM_SIZE&=&6;&&&&&&private&static&final&int&DEFAULT_COLOR_THEME&=&Color.parseColor(&#ff00ee00&);&&&&&&//&3&attributes&&&&&&private&int&color_&&&&&&private&boolean&isO&&&&&&private&int&&&&&&&//&varials&of&drawing&&&&&&private&Paint&&&&&&&private&Rect&backR&&&&&&private&Rect&frontR&&&&&&private&RectF&frontCircleR&&&&&&private&RectF&backCircleR&&&&&&private&int&&&&&&&private&int&max_&&&&&&private&int&min_&&&&&&private&int&frontRect_&&&&&&private&int&frontRect_left_begin&=&RIM_SIZE;&&&&&&private&int&eventStartX;&&&&&&private&int&eventLastX;&&&&&&private&int&diffX&=&0;&&&&&&private&boolean&slideable&=&true;&&&&&&private&SlideListener&&&&&&&&&public&interface&SlideListener&{&&&&&&&&&&public&void&open();&&&&&&&&&&&&public&void&close();&&&&&&}&&&&&&&&public&SlideSwitch(Context&context,&AttributeSet&attrs,&int&defStyleAttr)&{&&&&&&&&&&super(context,&attrs,&defStyleAttr);&&&&&&&&&&listener&=&null;&&&&&&&&&&paint&=&new&Paint();&&&&&&&&&&paint.setAntiAlias(true);&&&&&&&&&&TypedArray&a&=&context.obtainStyledAttributes(attrs,&&&&&&&&&&&&&&&&&&R.styleable.slideswitch);&&&&&&&&&&color_theme&=&a.getColor(R.styleable.slideswitch_themeColor,&&&&&&&&&&&&&&&&&&DEFAULT_COLOR_THEME);&&&&&&&&&&isOpen&=&a.getBoolean(R.styleable.slideswitch_isOpen,&false);&&&&&&&&&&shape&=&a.getInt(R.styleable.slideswitch_shape,&SHAPE_RECT);&&&&&&&&&&a.recycle();&&&&&&}&&&&&&&&public&SlideSwitch(Context&context,&AttributeSet&attrs)&{&&&&&&&&&&this(context,&attrs,&0);&&&&&&}&&&&&&&&public&SlideSwitch(Context&context)&{&&&&&&&&&&this(context,&null);&&&&&&}&&&&&&&&@Override&&&&&&protected&void&onMeasure(int&widthMeasureSpec,&int&heightMeasureSpec)&{&&&&&&&&&&super.onMeasure(widthMeasureSpec,&heightMeasureSpec);&&&&&&&&&&int&width&=&measureDimension(280,&widthMeasureSpec);&&&&&&&&&&int&height&=&measureDimension(140,&heightMeasureSpec);&&&&&&&&&&if&(shape&==&SHAPE_CIRCLE)&{&&&&&&&&&&&&&&if&(width&&&height)&&&&&&&&&&&&&&&&&&width&=&height&*&2;&&&&&&&&&&}&&&&&&&&&&setMeasuredDimension(width,&height);&&&&&&&&&&initDrawingVal();&&&&&&}&&&&&&&&public&void&initDrawingVal()&{&&&&&&&&&&int&width&=&getMeasuredWidth();&&&&&&&&&&int&height&=&getMeasuredHeight();&&&&&&&&&&&&backCircleRect&=&new&RectF();&&&&&&&&&&frontCircleRect&=&new&RectF();&&&&&&&&&&frontRect&=&new&Rect();&&&&&&&&&&backRect&=&new&Rect(0,&0,&width,&height);&&&&&&&&&&min_left&=&RIM_SIZE;&&&&&&&&&&if&(shape&==&SHAPE_RECT)&&&&&&&&&&&&&&max_left&=&width&/&2;&&&&&&&&&&else&&&&&&&&&&&&&&max_left&=&width&-&(height&-&2&*&RIM_SIZE)&-&RIM_SIZE;&&&&&&&&&&if&(isOpen)&{&&&&&&&&&&&&&&frontRect_left&=&max_&&&&&&&&&&&&&&alpha&=&255;&&&&&&&&&&}&else&{&&&&&&&&&&&&&&frontRect_left&=&RIM_SIZE;&&&&&&&&&&&&&&alpha&=&0;&&&&&&&&&&}&&&&&&&&&&frontRect_left_begin&=&frontRect_&&&&&&}&&&&&&&&public&int&measureDimension(int&defaultSize,&int&measureSpec)&{&&&&&&&&&&int&&&&&&&&&&&int&specMode&=&MeasureSpec.getMode(measureSpec);&&&&&&&&&&int&specSize&=&MeasureSpec.getSize(measureSpec);&&&&&&&&&&if&(specMode&==&MeasureSpec.EXACTLY)&{&&&&&&&&&&&&&&result&=&specS&&&&&&&&&&}&else&{&&&&&&&&&&&&&&result&=&defaultS&//&UNSPECIFIED&&&&&&&&&&&&&&if&(specMode&==&MeasureSpec.AT_MOST)&{&&&&&&&&&&&&&&&&&&result&=&Math.min(result,&specSize);&&&&&&&&&&&&&&}&&&&&&&&&&}&&&&&&&&&&return&&&&&&&}&&&&&&&&@Override&&&&&&protected&void&onDraw(Canvas&canvas)&{&&&&&&&&&&if&(shape&==&SHAPE_RECT)&{&&&&&&&&&&&&&&paint.setColor(Color.GRAY);&&&&&&&&&&&&&&canvas.drawRect(backRect,&paint);&&&&&&&&&&&&&&paint.setColor(color_theme);&&&&&&&&&&&&&&paint.setAlpha(alpha);&&&&&&&&&&&&&&canvas.drawRect(backRect,&paint);&&&&&&&&&&&&&&frontRect.set(frontRect_left,&RIM_SIZE,&frontRect_left&&&&&&&&&&&&&&&&&&&&&&&#43;&getMeasuredWidth()&/&2&-&RIM_SIZE,&getMeasuredHeight()&&&&&&&&&&&&&&&&&&&&&&-&RIM_SIZE);&&&&&&&&&&&&&&paint.setColor(Color.WHITE);&&&&&&&&&&&&&&canvas.drawRect(frontRect,&paint);&&&&&&&&&&}&else&{&&&&&&&&&&&&&&//&draw&circle&&&&&&&&&&&&&&int&&&&&&&&&&&&&&&radius&=&backRect.height()&/&2&-&RIM_SIZE;&&&&&&&&&&&&&&paint.setColor(Color.GRAY);&&&&&&&&&&&&&&backCircleRect.set(backRect);&&&&&&&&&&&&&&canvas.drawRoundRect(backCircleRect,&radius,&radius,&paint);&&&&&&&&&&&&&&paint.setColor(color_theme);&&&&&&&&&&&&&&paint.setAlpha(alpha);&&&&&&&&&&&&&&canvas.drawRoundRect(backCircleRect,&radius,&radius,&paint);&&&&&&&&&&&&&&frontRect.set(frontRect_left,&RIM_SIZE,&frontRect_left&&&&&&&&&&&&&&&&&&&&&&&#43;&backRect.height()&-&2&*&RIM_SIZE,&backRect.height()&&&&&&&&&&&&&&&&&&&&&&-&RIM_SIZE);&&&&&&&&&&&&&&frontCircleRect.set(frontRect);&&&&&&&&&&&&&&paint.setColor(Color.WHITE);&&&&&&&&&&&&&&canvas.drawRoundRect(frontCircleRect,&radius,&radius,&paint);&&&&&&&&&&}&&&&&&}&&&&&&&&&&&&@Override&&&&&&public&boolean&onTouchEvent(MotionEvent&event)&{&&&&&&&&&&if&(slideable&==&false)&&&&&&&&&&&&&&return&super.onTouchEvent(event);&&&&&&&&&&int&action&=&MotionEventCompat.getActionMasked(event);&&&&&&&&&&switch&(action)&{&&&&&&&&&&case&MotionEvent.ACTION_DOWN:&&&&&&&&&&&&&&eventStartX&=&(int)&event.getRawX();&&&&&&&&&&&&&&break;&&&&&&&&&&case&MotionEvent.ACTION_MOVE:&&&&&&&&&&&&&&eventLastX&=&(int)&event.getRawX();&&&&&&&&&&&&&&diffX&=&eventLastX&-&eventStartX;&&&&&&&&&&&&&&int&tempX&=&diffX&&#43;&frontRect_left_&&&&&&&&&&&&&&tempX&=&(tempX&&&max_left&?&max_left&:&tempX);&&&&&&&&&&&&&&tempX&=&(tempX&&&min_left&?&min_left&:&tempX);&&&&&&&&&&&&&&if&(tempX&&=&min_left&&&&tempX&&=&max_left)&{&&&&&&&&&&&&&&&&&&frontRect_left&=&tempX;&&&&&&&&&&&&&&&&&&alpha&=&(int)&(255&*&(float)&tempX&/&(float)&max_left);&&&&&&&&&&&&&&&&&&invalidateView();&&&&&&&&&&&&&&}&&&&&&&&&&&&&&break;&&&&&&&&&&case&MotionEvent.ACTION_UP:&&&&&&&&&&&&&&int&wholeX&=&(int)&(event.getRawX()&-&eventStartX);&&&&&&&&&&&&&&frontRect_left_begin&=&frontRect_&&&&&&&&&&&&&&boolean&toR&&&&&&&&&&&&&&toRight&=&(frontRect_left_begin&&&max_left&/&2&?&true&:&false);&&&&&&&&&&&&&&if&(Math.abs(wholeX)&&&3)&{&&&&&&&&&&&&&&&&&&toRight&=&!toR&&&&&&&&&&&&&&}&&&&&&&&&&&&&&moveToDest(toRight);&&&&&&&&&&&&&&break;&&&&&&&&&&default:&&&&&&&&&&&&&&break;&&&&&&&&&&}&&&&&&&&&&return&true;&&&&&&}&&&&&&&&/**&&&&&&*&draw&again&&&&&&*/&&&&&&private&void&invalidateView()&{&&&&&&&&&&if&(Looper.getMainLooper()&==&Looper.myLooper())&{&&&&&&&&&&&&&&invalidate();&&&&&&&&&&}&else&{&&&&&&&&&&&&&&postInvalidate();&&&&&&&&&&}&&&&&&}&&&&&&&&public&void&setSlideListener(SlideListener&listener)&{&&&&&&&&&&this.listener&=&&&&&&&}&&&&&&&&public&void&moveToDest(final&boolean&toRight)&{&&&&&&&&&&ValueAnimator&toDestAnim&=&ValueAnimator.ofInt(frontRect_left,&&&&&&&&&&&&&&&&&&toRight&?&max_left&:&min_left);&&&&&&&&&&toDestAnim.setDuration(500);&&&&&&&&&&toDestAnim.setInterpolator(new&AccelerateDecelerateInterpolator());&&&&&&&&&&toDestAnim.start();&&&&&&&&&&toDestAnim.addUpdateListener(new&AnimatorUpdateListener()&{&&&&&&&&&&&&&&&&@Override&&&&&&&&&&&&&&public&void&onAnimationUpdate(ValueAnimator&animation)&{&&&&&&&&&&&&&&&&&&frontRect_left&=&(Integer)&animation.getAnimatedValue();&&&&&&&&&&&&&&&&&&alpha&=&(int)&(255&*&(float)&frontRect_left&/&(float)&max_left);&&&&&&&&&&&&&&&&&&invalidateView();&&&&&&&&&&&&&&}&&&&&&&&&&});&&&&&&&&&&toDestAnim.addListener(new&AnimatorListenerAdapter()&{&&&&&&&&&&&&&&@Override&&&&&&&&&&&&&&public&void&onAnimationEnd(Animator&animation)&{&&&&&&&&&&&&&&&&&&if&(toRight)&{&&&&&&&&&&&&&&&&&&&&&&isOpen&=&true;&&&&&&&&&&&&&&&&&&&&&&if&(listener&!=&null)&&&&&&&&&&&&&&&&&&&&&&&&&&listener.open();&&&&&&&&&&&&&&&&&&&&&&frontRect_left_begin&=&max_&&&&&&&&&&&&&&&&&&}&else&{&&&&&&&&&&&&&&&&&&&&&&isOpen&=&false;&&&&&&&&&&&&&&&&&&&&&&if&(listener&!=&null)&&&&&&&&&&&&&&&&&&&&&&&&&&listener.close();&&&&&&&&&&&&&&&&&&&&&&frontRect_left_begin&=&min_&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&}&&&&&&&&&&});&&&&&&}&&&&&&&&public&void&setState(boolean&isOpen)&{&&&&&&&&&&this.isOpen&=&isO&&&&&&&&&&initDrawingVal();&&&&&&&&&&invalidateView();&&&&&&&&&&if&(listener&!=&null)&&&&&&&&&&&&&&if&(isOpen&==&true)&{&&&&&&&&&&&&&&&&&&listener.open();&&&&&&&&&&&&&&}&else&{&&&&&&&&&&&&&&&&&&listener.close();&&&&&&&&&&&&&&}&&&&&&}&&&&&&&&public&void&setShapeType(int&shapeType)&{&&&&&&&&&&this.shape&=&shapeT&&&&&&}&&&&&&&&public&void&setSlideable(boolean&slideable)&{&&&&&&&&&&this.slideable&=&&&&&&&}&&&&&&&&@Override&&&&&&protected&void&onRestoreInstanceState(Parcelable&state)&{&&&&&&&&&&if&(state&instanceof&Bundle)&{&&&&&&&&&&&&&&Bundle&bundle&=&(Bundle)&&&&&&&&&&&&&&&this.isOpen&=&bundle.getBoolean(&isOpen&);&&&&&&&&&&&&&&state&=&bundle.getParcelable(&instanceState&);&&&&&&&&&&}&&&&&&&&&&super.onRestoreInstanceState(state);&&&&&&}&&&&&&&&@Override&&&&&&protected&Parcelable&onSaveInstanceState()&{&&&&&&&&&&Bundle&bundle&=&new&Bundle();&&&&&&&&&&bundle.putParcelable(&instanceState&,&super.onSaveInstanceState());&&&&&&&&&&bundle.putBoolean(&isOpen&,&this.isOpen);&&&&&&&&&&return&&&&&&&}&&}&&使用方法:1.在布局文件中引用控件:[html]&view plaincopy&LinearLayout&xmlns:android=&/apk/res/android&&&&&&&xmlns:tools=&/tools&&&&&&&xmlns:slideswitch=&/apk/res/com.example.testlibs&&&&&&&android:layout_width=&match_parent&&&&&&&android:layout_height=&match_parent&&&&&&&android:background=&#ffffffff&&&&&&&android:gravity=&center_horizontal&&&&&&&android:orientation=&vertical&&&&&&&android:padding=&10dip&&&&&&&tools:context=&com.example.testlibs.MainActivity&&&&&&&&&&&&com.leaking.slideswitch.SlideSwitch&&&&&&&&&&android:id=&@&#43;id/swit&&&&&&&&&&&android:layout_width=&150dip&&&&&&&&&&&android:layout_height=&60dip&&&&&&&&&&&slideswitch:isOpen=&true&&&&&&&&&&&slideswitch:shape=&rect&&&&&&&&&&&slideswitch:themeColor=&#ffee3a00&&&&&&&&&&/com.leaking.slideswitch.SlideSwitch&&&&&&&&&&TextView&&&&&&&&&&android:id=&@&#43;id/txt&&&&&&&&&&&android:layout_width=&wrap_content&&&&&&&&&&&android:layout_height=&wrap_content&&/&&&&&&&&&&com.leaking.slideswitch.SlideSwitch&&&&&&&&&&android:id=&@&#43;id/swit2&&&&&&&&&&&android:layout_width=&190dip&&&&&&&&&&&android:layout_height=&100dip&&&&&&&&&&&android:layout_marginTop=&10dip&&&&&&&&&&&slideswitch:isOpen=&true&&&&&&&&&&&slideswitch:shape=&circle&&&&&&&&&&&slideswitch:themeColor=&#ff0a5a00&&&&&&&&&&/com.leaking.slideswitch.SlideSwitch&&&&&&&&&&com.leaking.slideswitch.SlideSwitch&&&&&&&&&&android:id=&@&#43;id/swit3&&&&&&&&&&&android:layout_width=&20dip&&&&&&&&&&&android:layout_height=&50dip&&&&&&&&&&&android:layout_marginTop=&10dip&&&&&&&&&&&slideswitch:isOpen=&true&&&&&&&&&&&slideswitch:shape=&circle&&&&&&&&&&&slideswitch:themeColor=&#ff73aa00&&&&&&&&&&/com.leaking.slideswitch.SlideSwitch&&&&&&&&&&com.leaking.slideswitch.SlideSwitch&&&&&&&&&&android:id=&@&#43;id/swit4&&&&&&&&&&&android:layout_width=&100dip&&&&&&&&&&&android:layout_height=&120dip&&&&&&&&&&&android:layout_marginTop=&10dip&&&&&&&&&&&slideswitch:isOpen=&false&&&&&&&&&&&slideswitch:shape=&circle&&&&&&&&&&&slideswitch:themeColor=&#f200aa96&&&&&&&&&&/com.leaking.slideswitch.SlideSwitch&&&&&&&&&&com.leaking.slideswitch.SlideSwitch&&&&&&&&&&android:id=&@&#43;id/swit5&&&&&&&&&&&android:layout_width=&90dip&&&&&&&&&&&android:layout_height=&50dip&&&&&&&&&&&android:layout_marginTop=&10dip&&&&&&&&&&&slideswitch:isOpen=&true&&&&&&&&&&&slideswitch:shape=&rect&&&&&&&&&&&slideswitch:themeColor=&#f23331a0&&&&&&&&&&/com.leaking.slideswitch.SlideSwitch&&&&&&/LinearLayout&&&MainActivity.java:[java]&view plaincopy/*&&*&Copyright&(C)&2015&Quinn&Chen&&*&&*&Licensed&under&the&Apache&License,&Version&2.0&(the&&License&);&&*&you&may&not&use&this&file&except&in&compliance&with&the&License.&&*&You&may&obtain&a&copy&of&the&License&at&&*&&*&&&&&&http://www.apache.org/licenses/LICENSE-2.0&&*&&*&Unless&required&by&applicable&law&or&agreed&to&in&writing,&software&&*&distributed&under&the&License&is&distributed&on&an&&AS&IS&&BASIS,&&*&WITHOUT&WARRANTIES&OR&CONDITIONS&OF&ANY&KIND,&either&express&or&implied.&&*&See&the&License&for&the&specific&language&governing&permissions&and&&*&limitations&under&the&License.&&*/&&package&com.example.&&&&import&android.app.A&&import&android.os.B&&import&android.widget.TextV&&import&android.widget.T&&&&import&com.leaking.slideswitch.SlideS&&import&com.leaking.slideswitch.SlideSwitch.SlideL&&&&public&class&MainActivity&extends&Activity&implements&SlideListener&{&&&&&&&&TextView&&&&&&&SlideSwitch&&&&&&&SlideSwitch&slide2;&&&&&&&&@Override&&&&&&protected&void&onCreate(Bundle&savedInstanceState)&{&&&&&&&&&&super.onCreate(savedInstanceState);&&&&&&&&&&setContentView(R.layout.activity_main);&&&&&&&&&&slide&=&(SlideSwitch)&findViewById(R.id.swit);&&&&&&&&&&slide2&=&(SlideSwitch)&findViewById(R.id.swit2);&&&&&&&&&&&&slide.setState(false);&&&&&&&&&&txt&=&(TextView)&findViewById(R.id.txt);&&&&&&&&&&slide.setSlideListener(this);&&&&&&}&&&&&&&&@Override&&&&&&public&void&open()&{&&&&&&&&&&txt.setText(&first&switch&is&opend,&and&set&the&second&one&is&'slideable'&);&&&&&&&&&&Toast.makeText(this,&&红色打开!蓝色按钮可调!&,&Toast.LENGTH_LONG).show();&&&&&&&&&&slide2.setSlideable(true);&&&&&&}&&&&&&&&@Override&&&&&&public&void&close()&{&&&&&&&&&&txt.setText(&first&switch&is&closed,and&set&the&second&one&is&'unslideable'&);&&&&&&&&&&Toast.makeText(this,&&红色关闭!蓝色按钮不可调!&,&Toast.LENGTH_LONG).show();&&&&&&&&&&slide2.setSlideable(false);&&&&&&}&&}&&运行代码如下:下载源码
最新教程周点击榜
微信扫一扫

我要回帖

更多关于 amp gt amp lt 的文章

 

随机推荐