android显示TextView文字的倒影效果 – 尚弦月 – 博客园

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

                        

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

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

  

复制代码

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

复制代码

 

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

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

  

复制代码

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

复制代码

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

  

复制代码

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

复制代码

 

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

  

复制代码

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

复制代码

  

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

  好了,就到这里吧。

  源代码下载请点我。

来源URL:http://www.cnblogs.com/shang53880/p/3549513.html