Android使用Xfermode图形渲染方法实现自定义圆形、圆角和椭圆ImageView
一:简介:
在上一篇《Android使用BitmapShader图形渲染实现圆形、圆角和椭圆自定义图片View》中,采用BitmapShader方法实现自定义的圆形、圆角等自定义ImageView,这篇我们将采用更为常见的Xfermode渲染模式方案来实现圆形、圆角和椭圆样式的ImageView,同样本实例也是直接继承ImageView,
这样可以省很多事情,比如测量步骤,以及不需要自己去写设置图片的方法,本文使用Xfermode模式中的DST_IN模式来实现要达到的效果,当然大家也可以采用其他的模式,比如SRC_IN等都可以实现该效果。
(照例完整源代码在文章的最后给出下载地址哈)
二:效果图:
三、Xfermode渲染模式简介:
xfermode影响在Canvas已经有的图像上绘制新的颜色的方式
* 正常的情况下,在图像上绘制新的形状,如果新的Paint不是透明的,那么会遮挡下面的颜色.
* 如果新的Paint是透明的,那么会被染成下面的颜色
下面的Xfermode子类可以改变这种行为:
AvoidXfermode 指定了一个颜色和容差,强制Paint避免在它上面绘图(或者只在它上面绘图)。
PixelXorXfermode 当覆盖已有的颜色时,应用一个简单的像素XOR操作。
PorterDuffXfermode 这是一个非常强大的转换模式,使用它,可以使用图像合成的16条Porter-Duff规则的任意一条来控制Paint如何与已有的Canvas图像进行交互。
这里不得不提到那个经典的图:
上面的16种模式的说明如下:
从上面我们可以看到PorterDuff.Mode为枚举类,一共有16个枚举值:
1.PorterDuff.Mode.CLEAR
所绘制不会提交到画布上。
2.PorterDuff.Mode.SRC
显示上层绘制图片
3.PorterDuff.Mode.DST
显示下层绘制图片
4.PorterDuff.Mode.SRC_OVER
正常绘制显示,上下层绘制叠盖。
5.PorterDuff.Mode.DST_OVER
上下层都显示。下层居上显示。
6.PorterDuff.Mode.SRC_IN
取两层绘制交集。显示上层。
7.PorterDuff.Mode.DST_IN
取两层绘制交集。显示下层。
8.PorterDuff.Mode.SRC_OUT
取上层绘制非交集部分。
9.PorterDuff.Mode.DST_OUT
取下层绘制非交集部分。
10.PorterDuff.Mode.SRC_ATOP
取下层非交集部分与上层交集部分
11.PorterDuff.Mode.DST_ATOP
取上层非交集部分与下层交集部分
12.PorterDuff.Mode.XOR
异或:去除两图层交集部分
13.PorterDuff.Mode.DARKEN
取两图层全部区域,交集部分颜色加深
14.PorterDuff.Mode.LIGHTEN
取两图层全部,点亮交集部分颜色
15.PorterDuff.Mode.MULTIPLY
取两图层交集部分叠加后颜色
16.PorterDuff.Mode.SCREEN
取两图层全部区域,交集部分变为透明色
四、自定义圆形、圆角和椭圆的ImageView的实现
1、测量View的大小,对圆形作特殊处理
代码如下 | 复制代码 |
/** * 测量view的大小 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub super.onMeasure(widthMeasureSpec, heightMeasureSpec); //如果类型是圆形,则强制设置view的宽高一致,取宽高的较小值 if(mType == TYPE_CIRCLE){ int width = Math.min(getMeasuredWidth(),getMeasuredHeight()); setMeasuredDimension(width, width); } } |
2、绘制不同图形的Bitmap,供onDraw()绘制的时候用
代码如下 | 复制代码 |
/** * 绘制不同的图形Bitmap */ private Bitmap getDrawBitmap(){ Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.BLACK); if(mType == TYPE_CIRCLE) {//绘制圆形 canvas.drawCircle(getWidth() / 2, getWidth() / 2, getWidth() / 2, paint); }else if(mType == TYPE_ROUND) {//绘制圆角矩形 canvas.drawRoundRect(new RectF(0, 0, getWidth(), getHeight()), mRoundBorderRadius, mRoundBorderRadius, paint); }else if(mType == TYPE_OVAL ){ //绘制椭圆 canvas.drawOval(new RectF(0, 0, getWidth(), getHeight()), mPaint); } return bitmap; } |
3、在onDraw()中绘制出来
代码如下 | 复制代码 |
/** * 绘制view的内容 */ @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub //从缓存中取出bitmap Bitmap bmp = (mBufferBitmap == null ? null:mBufferBitmap.get()); if(bmp == null || bmp.isRecycled()){ //如果没有缓存存在的情况 //获取drawable Drawable drawable = getDrawable(); //获取drawable的宽高 int dwidth = drawable.getIntrinsicWidth(); int dheight = drawable.getIntrinsicHeight(); Log.v("czm","dwidth="+dwidth+",width="+getWidth()); if(null != drawable){ bmp = Bitmap.createBitmap(getWidth(), getHeight(), Config.ARGB_8888); float scale = 1.0f; //创建画布 Canvas drawCanvas = new Canvas(bmp); //按照bitmap的宽高,以及view的宽高,计算缩放比例;因为设置的src宽高 //比例可能和imageview的宽高比例不同,这里我们不希望图片失真; if(mType == TYPE_CIRCLE) {//如果是圆形 scale = getWidth() * 1.0F / Math.min(dwidth, dheight); }else if (mType == TYPE_ROUND || mType == TYPE_OVAL) {//如果是圆角矩形或椭圆 // 如果图片的宽或者高与view的宽高不匹配,计算出需要缩放的比例; //缩放后的图片的宽高,一定要大于我们view的宽高;所以我们这里取大值; scale = Math.max(getWidth() * 1.0f / dwidth, getHeight() * 1.0f / dheight); } Log.v("czm","scale="+scale); //根据缩放比例,设置bounds,即相当于做缩放图片 drawable.setBounds(0, 0, (int)(scale * dwidth), (int)(scale * dheight)); drawable.draw(drawCanvas); //获取bitmap,即圆形、圆角或椭圆的bitmap if(mMaskBitmap == null || mMaskBitmap.isRecycled()){ mMaskBitmap = getDrawBitmap(); } //为paint设置Xfermode 渲染模式 mPaint.reset(); mPaint.setFilterBitmap(false); mPaint.setXfermode(mXfermode); //绘制不同形状 drawCanvas.drawBitmap(mMaskBitmap, 0, 0,mPaint); mPaint.setXfermode(null); //将准备好的bitmap绘制出来 canvas.drawBitmap(bmp, 0, 0, null); //bitmap缓存起来,避免每次调用onDraw,分配内存 mBufferBitmap = new WeakReference<Bitmap>(bmp); } }else{ //如果缓存还存在的情况 mPaint.setXfermode(null); canvas.drawBitmap(bmp, 0.0f, 0.0f, mPaint); return; } } |
4、因为使用了弱引用的缓存技术,所以需要在重写invalidate()方法中做些释放回收资源等处理:
代码如下 | 复制代码 |
/** * 因为使用了缓存技术,所以需要在invalidate中做些回收释放资源的处理 */ @Override public void invalidate() { // TODO Auto-generated method stub mBufferBitmap = null; if(mMaskBitmap != null){ mMaskBitmap.recycle(); mMaskBitmap = null; } super.invalidate(); } |
五、视图布局的实现:
代码如下 | 复制代码 |
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout <com.czm.myroundimageview.XCRoundImageViewByXfermode <com.czm.myroundimageview.XCRoundImageViewByXfermode <com.czm.myroundimageview.XCRoundImageViewByXfermode </ScrollView> |
六、使用和测试自定义ImageView
上面直接绘制的自定义ImageView写完了,下面就是使用这个自定义的ImageView了,使用方法和普通的ImageView一样,当作普通控件使用即可。
代码如下 | 复制代码 |
package com.czm.myroundimageview; import android.app.Activity; public class MainActivity extends Activity { private XCRoundImageViewByXfermode circleImageView;//圆形图片 } |
现在的智能手机都是触屏的,现在我们来学习一下Android开发的Touch(触屏)事件,看了本文章后你可以在30分钟之内快速明白Touch事件分发机制。
Touch事件分发中只有两个主角:ViewGroup和View。Activity的Touch事件事实上是调用它内部的ViewGroup的Touch事件,可以直接当成ViewGroup处理。
View在ViewGroup内,ViewGroup也可以在其他ViewGroup内,这时候把内部的ViewGroup当成View来分析。
ViewGroup的相关事件有三个:onInterceptTouchEvent、dispatchTouchEvent、onTouchEvent。View的相关事件只有两个:dispatchTouchEvent、onTouchEvent。
先分析 ViewGroup的处理流程:首先得有个结构模型概念:ViewGroup和View组成了一棵树形结构,最顶层为Activity的 ViewGroup,下面有若干的ViewGroup节点,每个节点之下又有若干的ViewGroup节点或者View节点,依次类推。如图:
当一个 Touch事件(触摸事件为例)到达根节点,即Acitivty的ViewGroup时,它会依次下发,下发的过程是调用子 View(ViewGroup)的dispatchTouchEvent方法实现的。简单来说,就是ViewGroup遍历它包含着的子View,调用每个View的dispatchTouchEvent方法,而当子View为ViewGroup时,又会通过调用ViwGroup的 dispatchTouchEvent方法继续调用其内部的View的dispatchTouchEvent方法。上述例子中的消息下发顺序是这样的:①-②-⑤-⑥-⑦-③-④。dispatchTouchEvent方法只负责事件的分发,它拥有boolean类型的返回值,当返回为true时,顺序下发会中断。在上述例子中如果⑤的dispatchTouchEvent返回结果为true,那么⑥-⑦-③-④将都接收不到本次Touch事件。来个简单版的代码加深理解:
代码如下 | 复制代码 |
/** * ViewGroup * @param ev * @return */ public boolean dispatchTouchEvent(MotionEvent ev){ ....//其他处理,在此不管 View[] views=getChildView(); for(int i=0;i<views.length;i++){ //判断下Touch到屏幕上的点在该子View上面 if(...){ if(views[i].dispatchTouchEvent(ev)) return true; } } ...//其他处理,在此不管 } /** * View * @param ev * @return */ public boolean dispatchTouchEvent(MotionEvent ev){ ....//其他处理,在此不管 return false; } |
在此可以看出,ViewGroup的dispatchTouchEvent是真正在执行“分发”工作,而View的dispatchTouchEvent方法,并不执行分发工作,或者说它分发的对象就是自己,决定是否把touch事件交给自己处理,而处理的方法,便是onTouchEvent事件,事实上子View 的dispatchTouchEvent方法真正执行的代码是这样的
代码如下 | 复制代码 |
/** * View * @param ev * @return */ public boolean dispatchTouchEvent(MotionEvent ev){ ....//其他处理,在此不管 return onTouchEvent(event); } |
一般情况下,我们不该在普通View内重写dispatchTouchEvent方法,因为它并不执行分发逻辑。当Touch事件到达View时,我们该做的就是是否在onTouchEvent事件中处理它。
那么,ViewGroup的onTouchEvent事件是什么时候处理的呢?当ViewGroup所有的子View都返回false 时,onTouchEvent事件便会执行。由于ViewGroup是继承于View的,它其实也是通过调用View的 dispatchTouchEvent方法来执行onTouchEvent事件。
在目前的情况看来,似乎只要我们把所有的onTouchEvent都返回false,就能保证所有的子控件都响应本次Touch事件了。但必须要说明的是,这里的 Touch事件,只限于Acition_Down事件,即触摸按下事件,而Aciton_UP和Action_MOVE却不会执行。事实上,一次完整的 Touch事件,应该是由一个Down、一个Up和若干个Move组成的。Down方式通过dispatchTouchEvent分发,分发的目的是为了找到真正需要处理完整Touch请求的View。当某个View或者ViewGroup的onTouchEvent事件返回true时,便表示它是真正要处理这次请求的View,之后的Aciton_UP和Action_MOVE将由它处理。当所有子View的onTouchEvent都返回false 时,这次的Touch请求就由根ViewGroup,即Activity自己处理了。
看看改进后的ViewGroup的dispatchTouchEvent方法
代码如下 | 复制代码 |
View mTarget=null;//保存捕获Touch事件处理的View //....其他处理,在此不管 if(!onInterceptTouchEvent()){ //...其他处理,在此不管 } |
ViewGroup还有个onInterceptTouchEvent,看名字便知道这是个拦截事件。这个拦截事件需要分两种情况来说明:
1.假如我们在某个ViewGroup的onInterceptTouchEvent中,将Action为Down的Touch事件返回true,那便表示将该 ViewGroup的所有下发操作拦截掉,这种情况下,mTarget会一直为null,因为mTarget是在Down事件中赋值的。由于mTarge 为null,该ViewGroup的onTouchEvent事件被执行。这种情况下可以把这个ViewGroup直接当成View来对待。
2.假如我们在某个ViewGroup的onInterceptTouchEvent中,将Acion为Down的Touch事件都返回false,其他的都返回 True,这种情况下,Down事件能正常分发,若子View都返回false,那mTarget还是为空,无影响。若某个子View返回了 true,mTarget被赋值了,在Action_Move和Aciton_UP分发到该ViewGroup时,便会给mTarget分发一个 Action_Delete的MotionEvent,同时清空mTarget的值,使得接下去的Action_Move(如果上一个操作不是UP)将由 ViewGroup的onTouchEvent处理。
情况一用到的比较多,情况二个人还未找到使用场景。
从头到尾总结一下:
1.Touch 事件分发中只有两个主角:ViewGroup和View。ViewGroup包含onInterceptTouchEvent、 dispatchTouchEvent、onTouchEvent三个相关事件。View包含dispatchTouchEvent、 onTouchEvent两个相关事件。其中ViewGroup又继承于View。
2.ViewGroup和View组成了一个树状结构,根节点为Activity内部包含的一个ViwGroup。
3.触摸事件由Action_Down、Action_Move、Aciton_UP组成,其中一次完整的触摸事件中,Down和Up都只有一个,Move有若干个,可以为0个。
4.当Acitivty接收到Touch事件时,将遍历子View进行Down事件的分发。ViewGroup的遍历可以看成是递归的。分发的目的是为了找到真正要处理本次完整触摸事件的View,这个View会在onTouchuEvent结果返回true。
5.当某个子 View返回true时,会中止Down事件的分发,同时在ViewGroup中记录该子View。接下去的Move和Up事件将由该子View直接进行处理。由于子View是保存在ViewGroup中的,多层ViewGroup的节点结构时,上级ViewGroup保存的会是真实处理事件的View所在的ViewGroup对象:如ViewGroup0-ViewGroup1-TextView的结构中,TextView返回了true,它将被保存在 ViewGroup1中,而ViewGroup1也会返回true,被保存在ViewGroup0中。当Move和UP事件来时,会先从 ViewGroup0传递至ViewGroup1,再由ViewGroup1传递至TextView。
6.当 ViewGroup中所有子View都不捕获Down事件时,将触发ViewGroup自身的onTouch事件。触发的方式是调用 super.dispatchTouchEvent函数,即父类View的dispatchTouchEvent方法。在所有子View都不处理的情况下,触发Acitivity的onTouchEvent方法。
7.onInterceptTouchEvent有两个作用:1.拦截Down事件的分发。2.中止Up和Move事件向目标View传递,使得目标View所在的ViewGroup捕获Up和Move事件。
另外,上文所列出的代码并非真正的源码,只是概括了源码在事件分发处理中的核心处理流程,真正源码各位可以自己去看,包含了更丰富的内容。
圆角图片在Android开发中比较常用,现在我们来介绍在Android如何实现圆形、圆角和椭圆自定义图片View,这时主要是使用BitmapShader图形渲染。一、概述
Android实现圆角矩形,圆形或者椭圆等图形,一般主要是个自定义View加上使用Xfermode实现的。实现圆角图片的方法其实不少,常见的就是利用Xfermode,Shader。本文直接继承ImageView,使用BitmapShader方法来实现圆形、圆角和椭圆的绘制,等大家看我本文的方法后,其他的类似形状也就都能举一反三来来画出来了。
二、效果图:
三、BitmapShader简介
BitmapShader是Shader的子类,可以通过Paint.setShader(Shader shader)进行设置、
我们这里只关注BitmapShader,构造方法:
mBitmapShader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP);
参数1:bitmap
参数2,参数3:TileMode;
TileMode的取值有三种:
CLAMP 拉伸
REPEAT 重复
MIRROR 镜像
如果大家给电脑屏幕设置屏保的时候,如果图片太小,可以选择重复、拉伸、镜像;
重复:就是横向、纵向不断重复这个bitmap
镜像:横向不断翻转重复,纵向不断翻转重复;
拉伸:这个和电脑屏保的模式应该有些不同,这个拉伸的是图片最后的那一个像素;横向的最后一个横行像素,不断的重复,纵项的那一列像素,不断的重复;
public BitmapShader(Bitmap bitmap,Shader.TileMode tileX,Shader.TileMode tileY)
调用这个方法来产生一个画有一个位图的渲染器(Shader)。
bitmap 在渲染器内使用的位图
tileX The tiling mode for x to draw the bitmap in. 在位图上X方向花砖模式
tileY The tiling mode for y to draw the bitmap in. 在位图上Y方向花砖模式
TileMode:(一共有三种)
CLAMP :如果渲染器超出原始边界范围,会复制范围内边缘染色。
REPEAT :横向和纵向的重复渲染器图片,平铺。
MIRROR :横向和纵向的重复渲染器图片,这个和REPEAT 重复方式不一样,他是以镜像方式平铺。
四、自定义圆形、圆角和椭圆的图片View的实现
1. 测量View的大小
代码如下 | 复制代码 |
@Override } |
2、设置BitmapShader和画笔Paint
代码如下 | 复制代码 |
/** } else if (mType == TYPE_ROUND || mType == TYPE_OVAL) { } |
3.最后就是绘制出来圆角、圆形和椭圆的图片,肯定在onDraw里面啦,根本原理就是使用了上面mBitmapShader渲染的画笔来绘制
代码如下 | 复制代码 |
@Override if (null == getDrawable()) { |
五、视图布局实现
这个很简单,就是3个自定义的view:
代码如下 | 复制代码 |
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout <com.czm.viewdrawtest.XCRoundAndOvalImageView <com.czm.viewdrawtest.XCRoundAndOvalImageView <com.czm.viewdrawtest.XCRoundAndOvalImageView </ScrollView> |
六、使用和测试自定义View
上面直接绘制的自定义View写完了,下面就是使用这个View了,使用方法和普通的ImageView一样,当作普通控件使用即可。
代码如下 | 复制代码 |
package com.czm.viewdrawtest;
private XCRoundAndOvalImageView circleImageView;//圆形图片 |
以下是本人整理出来的几篇关于Android Studio开发环境使用的教程,希望您通过这几篇文章的学习,能够掌握Android开发神器Android Studio的使用
[图文]Android Studio下载安装及配置开发环境教程
http://www.111cn.net/sj/android/74261.htm
win7X64下Android Stuido安装及搭建开发环境问题解决
http://www.111cn.net/sj/android/74265.htm
mac下载安装Android Studio配置开发环境教程
http://www.111cn.net/sj/android/74262.htm
总结android studio注意事项及打不开等问题解决方法
http://www.111cn.net/sj/android/74264.htm
小结Android Studio常用设置说明教程
http://www.111cn.net/sj/android/74263.htm
总结Android Studio导入项目的几种方法
http://www.111cn.net/sj/android/74260.htm
[最新图文版]如何将项目从eclipse迁移到android studio?
http://www.111cn.net/sj/android/74224.htm
实现系统重启的APK需要system的权限,在AndroidManifest.xml中增加android:sharedUserId="android.uid.system",再修改签名即可;
具体方法参考:
点击打开链接
1、使用PowerManager来实现:
代码:
private void rebootSystem(){
PowerManager pManager=(PowerManager) getSystemService(Context.POWER_SERVICE);
pManager.reboot("");
}
2、发送REBOOT广播:
代码:
private void rebootSystem(){
Intent reboot = new Intent(Intent.ACTION_REBOOT);
reboot.putExtra("nowait", 1);
reboot.putExtra("interval", 1);
reboot.putExtra("window", 0);
sendBroadcast(reboot);
}
相关文章
- 有时为了网站安全和版权问题,会对自己写的php源码进行加密,在php加密技术上最常用的是zend公司的zend guard 加密软件,现在我们来图文讲解一下。 下面就简单说说如何...2016-11-25
- 下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
- ps软件是现在很多人都会使用到的,HSL面板在ps软件中又有着非常独特的作用。这次文章就给大家介绍下ps怎么使用HSL面板,还不知道使用方法的下面一起来看看。  ...2017-07-06
- 这篇文章主要给大家介绍了关于C#创建自定义控件及添加自定义属性和事件使用的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用C#具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧...2020-06-25
- 本文实例讲述了JS实现自定义简单网页软键盘效果。分享给大家供大家参考,具体如下:这是一款自定义的简单点的网页软键盘,没有使用任何控件,仅是为了练习JavaScript编写水平,安全性方面没有过多考虑,有顾虑的可以不用,目的是学...2015-11-08
- 许多的朋友对于Plesk控制面板应用不是非常的了解特别是英文版的Plesk控制面板,在这里小编整理了一些关于Plesk控制面板常用的使用方案整理,具体如下。 本文基于Linu...2016-10-10
使用insertAfter()方法在现有元素后添加一个新元素
复制代码 代码如下: //在现有元素后添加一个新元素 function insertAfter(newElement, targetElement){ var parent = targetElement.parentNode; if (parent.lastChild == targetElement){ parent.appendChild(newEl...2014-05-31Android开发中findViewById()函数用法与简化
findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20- 如果我们的项目需要做来电及短信的功能,那么我们就得在Android模拟器开发这些功能,本来就来告诉我们如何在Android模拟器上模拟来电及来短信的功能。 在Android模拟...2016-09-20
jQuery 1.9使用$.support替代$.browser的使用方法
jQuery 从 1.9 版开始,移除了 $.browser 和 $.browser.version , 取而代之的是 $.support 。 在更新的 2.0 版本中,将不再支持 IE 6/7/8。 以后,如果用户需要支持 IE 6/7/8,只能使用 jQuery 1.9。 如果要全面支持 IE,并混合...2014-05-31- 大概有如下步骤 新建项目Bejs 新建文件package.json 新建文件Gruntfile.js 命令行执行grunt任务 一、新建项目Bejs源码放在src下,该目录有两个js文件,selector.js和ajax.js。编译后代码放在dest,这个grunt会...2014-06-07
使用percona-toolkit操作MySQL的实用命令小结
1.pt-archiver 功能介绍: 将mysql数据库中表的记录归档到另外一个表或者文件 用法介绍: pt-archiver [OPTION...] --source DSN --where WHERE 这个工具只是归档旧的数据,不会对线上数据的OLTP查询造成太大影响,你可以将...2015-11-24如何使用php脚本给html中引用的js和css路径打上版本号
在搜索引擎中搜索关键字.htaccess 缓存,你可以搜索到很多关于设置网站文件缓存的教程,通过设置可以将css、js等不太经常更新的文件缓存在浏览器端,这样访客每次访问你的网站的时候,浏览器就可以从浏览器的缓存中获取css、...2015-11-24- C#注释的一些使用方法浅谈,需要的朋友可以参考一下...2020-06-25
- 夜神android模拟器如何设置代理呢?对于这个问题其实操作起来是非常的简单,下面小编来为各位详细介绍夜神android模拟器设置代理的方法,希望例子能够帮助到各位。 app...2016-09-20
- 为了增强android应用的用户体验,我们可以在一些Button按钮上自定义动态的设置一些样式,比如交互时改变字体、颜色、背景图等。 今天来看一个通过重写Button来动态实...2016-09-20
- 一、下载 mysqlsla [root@localhost tmp]# wget http://hackmysql.com/scripts/mysqlsla-2.03.tar.gz--19:45:45-- http://hackmysql.com/scripts/mysqlsla-2.03.tar.gzResolving hackmysql.com... 64.13.232.157Conn...2015-11-24
- 如果我们要在Android应用APP中加载html5页面,我们可以使用WebView,本文我们分享两个WebView加载html5页面实例应用。 实例一:WebView加载html5实现炫酷引导页面大多...2016-09-20
安装和使用percona-toolkit来辅助操作MySQL的基本教程
一、percona-toolkit简介 percona-toolkit是一组高级命令行工具的集合,用来执行各种通过手工执行非常复杂和麻烦的mysql和系统任务,这些任务包括: 检查master和slave数据的一致性 有效地对记录进行归档 查找重复的索...2015-11-24- 深入理解Android中View和ViewGroup从组成架构上看,似乎ViewGroup在View之上,View需要继承ViewGroup,但实际上不是这样的。View是基类,ViewGroup是它的子类。本教程我们深...2016-09-20