android显示TextView文字的倒影效果实现代码
今天记录一下textview的倒影效果,显示一串文字,然后在文字的下方显示出它的倒影,先上效果图:
最重要的就是view中getdrawingcache()方法,该方法可以获取cache中的图像,然后绘制出来。
废话不多说,我是想写一个带有倒影的时间,时间可以走动。首先先写一个带有时间走动的view,这个很简单,获取当前时间,然后开启一个线程,隔一秒获取当前时间一次,然后显示在textview上,当然,我们写控件,就需要继承textview,代码如下:
package com.alex.reflecttextview;
import java.util.calendar;
import android.content.context;
import android.os.handler;
import android.os.message;
import android.text.format.dateformat;
import android.util.attributeset;
import android.widget.textview;
public class timeview extends textview {
private static final int message_time = 1;
public timeview(context context, attributeset attrs) {
super(context, attrs);
new timethread().start();
}
public class timethread extends thread {
@override
public void run() {
do {
try {
message msg = new message();
msg.what = message_time;
mhandler.sendmessage(msg);
thread.sleep(1000);
} catch (interruptedexception e) {
e.printstacktrace();
}
} while (true);
}
}
private handler mhandler = new handler() {
@override
public void handlemessage(message msg) {
super.handlemessage(msg);
switch (msg.what) {
case message_time:
settime();
break;
default:
break;
}
}
};
public void settime() {
long systime = system.currenttimemillis();
calendar calendar = calendar.getinstance();
calendar.settimeinmillis(systime);
string systimestr = dateformat.format("hh:mm", systime).tostring();
if(calendar.get(calendar.am_pm) == 0) {
systimestr += " am";
} else {
systimestr += " pm";
}
settext(systimestr.replace("1", " 1"));
}
}
现在只需要在布局文件中调用该控件就可以实现一个走动的时间了。
第二步就是需要给这个走动的时间加上倒影了,我们就需要写一个控件来继承上面一个时间走动的控件,就可以实现带有倒影的时间走动的view了,下面是带有倒影的代码:
package com.alex.reflecttextview;
import android.content.context;
import android.graphics.bitmap;
import android.graphics.canvas;
import android.graphics.lineargradient;
import android.graphics.matrix;
import android.graphics.paint;
import android.graphics.porterduff.mode;
import android.graphics.porterduffxfermode;
import android.graphics.shader.tilemode;
import android.util.attributeset;
public class reflecttextview extends timeview {
private matrix mmatrix;
private paint mpaint;
public reflecttextview(context context, attributeset attrs) {
super(context, attrs);
init();
}
private void init() {
mmatrix = new matrix();
mmatrix.prescale(1, -1);
}
@override
protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {
super.onmeasure(widthmeasurespec, heightmeasurespec);
setmeasureddimension(getmeasuredwidth(), (int)(getmeasuredheight()*1.67));
}
@override
protected void ondraw(canvas canvas) {
super.ondraw(canvas);
int height = getheight();
int width = getwidth();
setdrawingcacheenabled(true);
bitmap originalimage = bitmap.createbitmap(getdrawingcache());
bitmap reflectionimage = bitmap.createbitmap(originalimage, 0, height/5, width, height/2, mmatrix, false);
canvas.drawbitmap(reflectionimage, 0, height/3f, null);
if(mpaint == null) {
mpaint = new paint();
lineargradient shader = new lineargradient(0, height/2, 0,
height, 0x7fffffff, 0x0fffffff, tilemode.clamp);
mpaint.setshader(shader);
mpaint.setxfermode(new porterduffxfermode(mode.dst_in));
}
canvas.drawrect(0, height/2f, width, height, mpaint);
}
@override
protected void ontextchanged(charsequence text, int start,
int lengthbefore, int lengthafter) {
super.ontextchanged(text, start, lengthbefore, lengthafter);
builddrawingcache();
postinvalidate();
}
}
主要功能在ondraw方法里面,先调用setdrawingcacheenabled(true);让cache可用,然后通过cache创建一个和原图片一样的图像,通过mmatrix.prescale(1, -1);使图片倒过来,调用bitmap.createbitmap(originalimage, 0, height/5, width, height/2, mmatrix, false);创建一个倒过来的图像,调用canvas.drawbitmap(reflectionimage, 0, height/3f, null);把倒过来的图像画到画布上。通过调用lineargradient shader = new lineargradient(0, height/2, 0,
height, 0x7fffffff, 0x0fffffff, tilemode.clamp);
mpaint.setshader(shader);
mpaint.setxfermode(new porterduffxfermode(mode.dst_in));使倒影的图像的颜色渐变,由灰色变为黑色。
时间走动时调用builddrawingcache();
postinvalidate();
让倒影从新绘制。
调用setmeasureddimension(getmeasuredwidth(), (int)(getmeasuredheight()*1.67));设置图像的宽度和高度。
好了,控件已经写完了,现在只要在布局中调用这个控件就可以在activity中显示一个带有倒影的时间的view了,先写一个布局文件:
<?xml version="1.0" encoding="utf-8"?>
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:paddingtop="@dimen/activity_vertical_margin" >
<com.alex.reflecttextview.reflecttextview
android:id="@+id/timeview"
android:textsize="@dimen/reflect_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignparentbottom="true"
android:gravity="top|center_horizontal" />
</relativelayout>
然后在activity中显示这个布局,我把这个控件的字体从新设置了一下,让它显示的方方正正。
package com.alex.reflecttextview;
import android.app.activity;
import android.graphics.typeface;
import android.os.bundle;
import android.view.window;
import android.view.windowmanager;
public class mainactivity extends activity {
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
final window win = getwindow();
win.addflags(windowmanager.layoutparams.flag_show_when_locked
| windowmanager.layoutparams.flag_dismiss_keyguard);
win.addflags(windowmanager.layoutparams.flag_keep_screen_on
| windowmanager.layoutparams.flag_turn_screen_on);
setcontentview(r.layout.activity_main);
timeview tv = (timeview) findviewbyid(r.id.timeview);
tv.settypeface(typeface.createfromasset(getassets(), "fonts/ds-digii.ttf"));
}
}
运行代码,手机上就回显示一个带有倒影的时间view,时间还会走动,是不是很好玩。
好了,就到这里吧。
源码下载地址:http://xiazai.jb51.net/201402/yuanma/reflecttextview(jb51.net).rar