zoukankan      html  css  js  c++  java
  • android显示TextView文字的倒影效果

      今天记录一下TextView的倒影效果,显示一串文字,然后在文字的下方显示出它的倒影,先上效果图:

                            

      最重要的就是View中getDrawingCache()方法,该方法可以获取cache中的图像,然后绘制出来。

      废话不多说,我是想写一个带有倒影的时间,时间可以走动。首先先写一个带有时间走动的View,这个很简单,获取当前时间,然后开启一个线程,隔一秒获取当前时间一次,然后显示在TextView上,当然,我们写控件,就需要继承TextView,代码如下:

      

     1 package com.alex.reflecttextview;
     2 
     3 import java.util.Calendar;
     4 
     5 import android.content.Context;
     6 import android.os.Handler;
     7 import android.os.Message;
     8 import android.text.format.DateFormat;
     9 import android.util.AttributeSet;
    10 import android.widget.TextView;
    11 
    12 public class TimeView extends TextView {
    13 
    14     private static final int MESSAGE_TIME = 1;
    15     
    16     public TimeView(Context context, AttributeSet attrs) {
    17         super(context, attrs);
    18         new TimeThread().start();
    19     }
    20     
    21     public class TimeThread extends Thread {
    22         @Override
    23         public void run() {
    24             do {
    25                 try {
    26                     Message msg = new Message();
    27                     msg.what = MESSAGE_TIME;
    28                     mHandler.sendMessage(msg);
    29                     Thread.sleep(1000);
    30                 } catch (InterruptedException e) {
    31                     e.printStackTrace();
    32                 }
    33             } while (true);
    34         }
    35     }
    36     
    37     private Handler mHandler = new Handler() {
    38 
    39         @Override
    40         public void handleMessage(Message msg) {
    41             super.handleMessage(msg);
    42             switch (msg.what) {
    43             case MESSAGE_TIME:
    44                 setTime();
    45                 break;
    46 
    47             default:
    48                 break;
    49             }
    50         }
    51     };
    52     
    53     public void setTime() {
    54         long sysTime = System.currentTimeMillis();
    55         Calendar calendar = Calendar.getInstance();
    56         calendar.setTimeInMillis(sysTime);
    57         String sysTimeStr = DateFormat.format("hh:mm", sysTime).toString();
    58         if(calendar.get(Calendar.AM_PM) == 0) {
    59             sysTimeStr += " AM";
    60         } else {
    61             sysTimeStr += " PM";
    62         }
    63         setText(sysTimeStr.replace("1", " 1"));
    64     }
    65 }

      现在只需要在布局文件中调用该控件就可以实现一个走动的时间了。

      第二步就是需要给这个走动的时间加上倒影了,我们就需要写一个控件来继承上面一个时间走动的控件,就可以实现带有倒影的时间走动的View了,下面是带有倒影的代码:

      

     1 package com.alex.reflecttextview;
     2 
     3 
     4 import android.content.Context;
     5 import android.graphics.Bitmap;
     6 import android.graphics.Canvas;
     7 import android.graphics.LinearGradient;
     8 import android.graphics.Matrix;
     9 import android.graphics.Paint;
    10 import android.graphics.PorterDuff.Mode;
    11 import android.graphics.PorterDuffXfermode;
    12 import android.graphics.Shader.TileMode;
    13 import android.util.AttributeSet;
    14 
    15 public class ReflectTextView extends TimeView {
    16 
    17     private Matrix mMatrix;
    18     private Paint mPaint;
    19     
    20     public ReflectTextView(Context context, AttributeSet attrs) {
    21         super(context, attrs);
    22         init();
    23     }
    24 
    25     private void init() {
    26         mMatrix = new Matrix();
    27         mMatrix.preScale(1, -1);
    28     }
    29     
    30     @Override
    31     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    32         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    33         setMeasuredDimension(getMeasuredWidth(), (int)(getMeasuredHeight()*1.67));
    34     }
    35     
    36     @Override
    37     protected void onDraw(Canvas canvas) {
    38         super.onDraw(canvas);
    39         int height = getHeight();
    40         int width = getWidth();
    41         setDrawingCacheEnabled(true);
    42         Bitmap originalImage = Bitmap.createBitmap(getDrawingCache());
    43         Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0, height/5, width, height/2, mMatrix, false);
    44         canvas.drawBitmap(reflectionImage, 0, height/3f, null);
    45         if(mPaint == null)  {
    46             mPaint = new Paint();   
    47             LinearGradient shader = new LinearGradient(0, height/2, 0,
    48                     height, 0x7fffffff, 0x0fffffff, TileMode.CLAMP);
    49             mPaint.setShader(shader);
    50             mPaint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));   
    51         }
    52         canvas.drawRect(0, height/2f, width, height, mPaint);
    53     }
    54     
    55     @Override
    56     protected void onTextChanged(CharSequence text, int start,
    57             int lengthBefore, int lengthAfter) {
    58         super.onTextChanged(text, start, lengthBefore, lengthAfter);
    59         buildDrawingCache();
    60         postInvalidate();
    61     }
    62 }

      主要功能在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了,先写一个布局文件:

      

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     android:background="#000000"
     6     android:paddingTop="@dimen/activity_vertical_margin" >
     7     
     8     <com.alex.reflecttextview.ReflectTextView
     9             android:id="@+id/timeView"
    10              android:textSize="@dimen/reflect_size"
    11               android:layout_width="match_parent"
    12               android:layout_height="wrap_content"
    13               android:layout_alignParentBottom="true"
    14               android:gravity="top|center_horizontal" />
    15 </RelativeLayout>

      然后在Activity中显示这个布局,我把这个控件的字体从新设置了一下,让它显示的方方正正。

      

     1 package com.alex.reflecttextview;
     2 
     3 import android.app.Activity;
     4 import android.graphics.Typeface;
     5 import android.os.Bundle;
     6 import android.view.Window;
     7 import android.view.WindowManager;
     8 
     9 public class MainActivity extends Activity {
    10 
    11     @Override
    12     protected void onCreate(Bundle savedInstanceState) {
    13         super.onCreate(savedInstanceState);
    14         final Window win = getWindow();
    15         win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
    16                 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
    17         win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
    18                 | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
    19         setContentView(R.layout.activity_main);
    20         TimeView tv = (TimeView) findViewById(R.id.timeView);
    21         tv.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/DS-DIGII.TTF"));
    22     }
    23 }

      

      运行代码,手机上就回显示一个带有倒影的时间View,时间还会走动,是不是很好玩。

      好了,就到这里吧。

      源代码下载请点我。

      

  • 相关阅读:
    什么样的代码称得上是好代码?
    九年程序人生 总结分享
    Docker入门 第一课 --.Net Core 使用Docker全程记录
    阿里云 Windows Server 2012 r2 部署asp.net mvc网站 平坑之旅
    Visual studio 2015 Community 安装过程中遇到问题的终极解决
    Activiti6.0 spring5 工作流引擎 java SSM流程审批 项目框架
    java 进销存 库存管理 销售报表 商户管理 springmvc SSM crm 项目
    Leetcode名企之路
    24. 两两交换链表中的节点
    21. 合并两个有序链表
  • 原文地址:https://www.cnblogs.com/shang53880/p/3549513.html
Copyright © 2011-2022 走看看