如果我们的应用需要显示时间,可能首先想到大街上LED显示的绿色的发光字体, 想到 使用时钟控件显示时间,这种效果,我们用 TextView 就可以实现。
这个效果图费了好大劲才把他贴上来
效果图:
很酷吧,细心的会发现,有上下两层字体重叠而成
其实很简单,发光的字体被看作一个主阴影层。然后在主层下面画一个暗层。
上面绿色发光的字体,下面的字体要设好透明度,
用textview实现,大家很容易想到要实现TextView类,覆写其方法,扩展其功能,实际上也是这么做的。我们创建LedTextView类继承TextView类,
下面要使用LedTextView来布局,所以一定要实现TextView(Context context ,AttributeSet atts)构造方法
发光的字体代码:
package com.manning.androidhacks.hack011.view;
import java.io.File;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.TextView;
public class LedTextView extends TextView {
private static final String FONTS_FOLDER = "fonts";
private static final String FONT_DIGITAL_7 = FONTS_FOLDER
+ File.separator + "digital-7.ttf";
public LedTextView(Context context) {
super(context);
init(context);
}
public LedTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public LedTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context) {
AssetManager assets = context.getAssets();
//加载字体,FONT_DIGITAL_7为assets的字体文件
final Typeface font = Typeface.createFromAsset(assets,
FONT_DIGITAL_7);
//设置字体
setTypeface(font);
}
}
给字体加发光效果,我们可以看做是阴影
阴影制作涉及到一个重要函数:setShadowLayer
public void setShadowLayer (float radius, float dx, float dy, int color)
radius:阴影半径
dx:X轴方向的偏移量
dy:Y轴方向的偏移量
color:阴影颜色
注意:如果半径被设置为0,意思就是去掉阴影。
也可以在xml中定义:
shadowRadius, shadowDx,shadowDy,shadowColor
第一个LedTextView为下层,字体颜色设定透明度
第二个LedTextView为上层,为了体现发光shadowRadius设置大一些,字体颜色,阴影颜色相同
两个叠加文字视图的xml布局:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
<com.manning.androidhacks.hack011.view.LedTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/default_time"
android:textColor="#3300ff00"
android:textSize="80sp" />
<com.manning.androidhacks.hack011.view.LedTextView
android:id="@+id/main_clock_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:shadowColor="#00ff00"
android:shadowDx="0"
android:shadowDy="0"
android:shadowRadius="10"
android:textColor="#00ff00"
android:textSize="80sp" />
</merge>
说明: 因为叠加会想到用framelayout布局,那这样就有出现了两个framelayout节点,因为所有的Activity视图的根节点都是frameLayout,为了去掉多余的frameLayout节点,减少冗余的层次,我们使用<merge>标签,可以理解为将merge标签中的子集直接加到Activity的FrameLayout跟节点下,从而达到优化UI的目的!
进一步理解可以参考:
【Android】Merge讲解与实例_MacroCheng_新浪博客
http://blog.sina.com.cn/s/blog_62f987620100sf13.html
还是看原书注释吧:
最后要想实现时间不停变化效果,用Handler.postDelayed(Runnable r,long delayMillis) 开启一个线程来不断刷新, 其中 r :将要执行的线程 ,delayMillis :延迟多久后执行。 在线程中再次调用 mHandler.postDelayed(this, REFRESH_DELAY);使其执行完REFRESH_DELAYms后再次执行,这样轮番执行。就像一个发动机,只要启动它,他就会不停地执行,显示当前时间, 退出后要结束线程:void android.os.Handler.removeCallbacks(Runnable r)。
主程序代码:
package com.manning.androidhacks.hack011;
import java.util.Date;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;
public class MainActivity extends Activity {
private static final String DATE_FORMAT = "%02d:%02d:%02d";
private static final int REFRESH_DELAY = 500;
private final Handler mHandler = new Handler();
private final Runnable mTimeRefresher = new Runnable() {
@Override
public void run() {
final Date d = new Date();
mTextView.setText(String.format(DATE_FORMAT, d.getHours(),
d.getMinutes(), d.getSeconds()));
mHandler.postDelayed(this, REFRESH_DELAY);
}
};
private TextView mTextView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTextView = (TextView) findViewById(R.id.main_clock_time);
}
@Override
protected void onResume() {
super.onResume();
mHandler.post(mTimeRefresher);
}
@Override
protected void onStop() {
super.onStop();
mHandler.removeCallbacks(mTimeRefresher);
}
}
textview的字体阴影用起来很简单,却会是我们的view看起来出色,这种小改进会为我们的应用增色。
源码下载:
Android textview实现led效果的字体 - 下载频道 - youkuaiyun.com
点击打开链接
待续。。。。。