在一些欢迎界面中,我们可能会遇到这样的需求,界面中的某一部分文字或者图像,渐渐变亮显示出来,或者变暗隐藏。或许你首先想到的是,自定义view,然后在ondraw方法中,启动一个线程,对部分控件进行操作等等。是的,开始我也是这么想的。但是,自定义控件还停留在拼凑阶段的我,实在是不想这样做。恩,我比较懒。于是,查了一些简单的方法,看到一篇文章中有关于图片渐变的。原理也很简单,在工作线程中,不断的改变图片的通透度,在用handler通知主线程界面更新。首先,简单说明下32位图的四个颜色值,rgb代表颜色的组成,不多说,alpha值,表示图片的透明度,为0,透明,为255,不透明,中间值,半透明。
然而,我们的需求并不是整个界面全部变明或变暗,怎么办呢?投机取巧下,准备俩张图片,第一张,做背景图,这张图包含了你所有不需要变化的部分,这张图,不透明。第二张图,大小和第一张一样,只是比第一张多了要变化的部分,或者干脆只有要变化的部分。一个imageview标签,铺满全屏,图片就是这张,透明。ok,我们只需要在代码里更改第二张图的通透度就搞定了。
接下来,就是布局,可以用framelayout,当然,相对布局也没什么问题。
<?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="@drawable/abc2" >
<ImageView
android:id="@+id/imageView1"
android:contentDescription="@string/app_name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/printing"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:textSize="18sp"
android:textColor="@color/white"
android:layout_marginBottom="18dp"
android:gravity="center_horizontal"
android:text="@string/version_welcome" />
</RelativeLayout>
效果图,就是这样了。然后我们去写代码。
public class WelcomeActivity extends Activity{
// 声明ImageView对象
ImageView imageView;
// 声明TextView
TextView textView;
// ImageView的alpha值
int image_alpha = 0;
// Handler对象用来给UI_Thread的MessageQueue发送消息
Handler mHandler;
// 线程是否运行判断变量
boolean isrung = false,isOk=false;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.welcome_activity);
//获得imageview的对象
imageView=(ImageView) findViewById(R.id.imageView1);
// 设置imageView的Alpha值
imageView.setAlpha(image_alpha);
// 开启一个线程来让Alpha值递增
new Thread(new Runnable() {
@Override
public void run() {
while (!isrung&&image_alpha<255) {
try {
Thread.sleep(100);
// 更新Alpha值
updateAlpha();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
// 接受消息之后更新imageview视图
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
try {
imageView.setAlpha(image_alpha);
imageView.invalidate();
// 刷新视图 ,当isok为true,表示已经完全不透明,线程中死循环该结束。
if (isrung&&!isOk) {
Thread.sleep(500);
Intent intent=new Intent(WelcomeActivity.this, SelectActivity.class);
intent.putExtra("isfrist", true);
startActivity(intent);
WelcomeActivity.this.finish();
isOk=true;
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
}
protected void updateAlpha() {
// TODO Auto-generated method stub
if (image_alpha +13<=255) {
image_alpha += 13;
} else {
image_alpha = 255;
isrung = true;
}
// 发送需要更新imageview视图的消息-->这里是发给主线程
mHandler.sendMessage(mHandler.obtainMessage());
}
}
效果图的中间的一行小字,在程序启动后,就会渐渐变亮,显现出来。效果吗,还可以的。不过有几点是需要注意的,也是我摸索出来的。
1.首先,你的a值得递增弧度要选择合适的值不要太大,线程休眠的事件也不能太长,最好低于人眼能看出的梅秒24帧,不然,效果会比较突兀,颜色就不是渐变了,是跳着变。
2.a值定义成全局变量,handler中用来更新的a值,不要通过handler.sendmsg传递在读取,那样会报错。原因吗,我觉得是响应超时造成的,没有细究。我这样写,a值永远是最新的改变后的值,而且,我只要接受到handler通知我改变,我就执行,不需要还去解析出msg中的值,也省去了传递参数这一步。这样写的好处我在别的业务中也深有体会。实时状态监控中,你会发现,全局变量,你不用他不行,不然,就还要弄个消息队列,然后一个一个去读,读了还要取这个msg对象的消息,多了好多步无用的操作。而且很难做到你实时,同步。
好了,这些东西仅供和我一样,基础还不是很好,还懒的同学借鉴。最后,自己还是去写自定义的,毕竟高大上,对自己也是锻炼。