效果图同上:
(修复了bug)
1. 不在setText中new Thread,而是直接让它实现ruunable接口
2. 在进入应用之后,按电源键让手机休眠,等一会再进去,水波纹会异常,这是由于线程一直在运行,会不断修改Delta和step的值,但是却没有重绘视图导致的。
3. 结合listivew使用以下。
package com.example.wavedemo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetrics;
import android.graphics.Path;
import android.graphics.Rect;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
/**
* 水波纹数字
*
* @author huozhenpeng
*
*/
public class WaveTextView extends View implements Runnable {
private TextPaint textPaint;
private TextPaint textPaint2;
private int textSize = 200;
private int textPaintWidth = 50;
private int width;
private int height;
private int Delta;
private int step;
private Path path;
private FontMetrics fontMetrics;
private String text = "85";
private int baseline;
private int max;
private float controlY1;// 两个控制点的纵坐标
private float controlY2;
private int fraction = 1;// 1或者-1
private Rect bounds;
public WaveTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public WaveTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public WaveTextView(Context context) {
this(context, null);
}
public void init() {
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
textPaint.setColor(Color.parseColor("#0e92ca"));
textPaint.setTextSize(textSize);
textPaint.setStrokeWidth(textPaintWidth);
textPaint.setTextAlign(Align.CENTER);
fontMetrics = textPaint.getFontMetrics();
textPaint2 = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
textPaint2.setColor(Color.parseColor("#efefef"));
textPaint2.setTextSize(textSize);
textPaint2.setStrokeWidth(textPaintWidth);
textPaint2.setTextAlign(Align.CENTER);
path = new Path();
bounds = new Rect();
textPaint.getTextBounds(text, 0, text.length(), bounds);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY) {
widthMeasureSpec = MeasureSpec.makeMeasureSpec(
(int) textPaint.measureText(text), MeasureSpec.EXACTLY);
}
if (MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(
(int) (bounds.height()), MeasureSpec.EXACTLY);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
width = w;
height = h;
baseline = (int) ((fontMetrics.descent + fontMetrics.ascent) / 2);
// max = (int) (Integer.parseInt(text) / 100.0f * height);
}
@Override
protected void onDraw(Canvas canvas) {
Delta += 1;
step += 1 * fraction;
max = (int) (Integer.parseInt(text) / 100.0f * height);
if (Delta >= max) {
Delta = max;
}
path.reset();
path.moveTo(0, 0);
path.lineTo(width, 0);
path.lineTo(width, height - Delta);
controlY1 = step + (height - Delta);
controlY2 = -step + (height - Delta);
if (controlY1 - (height - Delta) >= height * 1.0f / 4) {
fraction = -1;
}
if (controlY1 - (height - Delta) <= -height * 1.0f / 4) {
fraction = 1;
}
path.cubicTo(width * 3.0f / 4, controlY1, width * 1.0f / 4, controlY2,
0, height - Delta);
Log.e("abc", "h:" + (height - Delta) + "controlY1:" + controlY1
+ "controlY2:" + controlY2);
path.close();
canvas.drawColor(Color.parseColor("#ffffff"));
canvas.drawText(text, width / 2, height / 2 - baseline, textPaint);
canvas.save();
canvas.clipPath(path);
canvas.drawText(text, width / 2, height / 2 - baseline, textPaint2);
canvas.restore();
super.onDraw(canvas);
}
public void setText(int text) {
this.text = text + "";
Delta = 0;
step = 0;
fraction = 1;
}
@Override
public void run() {
while (true) {
try {
Log.e("abc", "running");
Thread.sleep(20);
// 这两行代码一定要放到onDraw中,要不然手机屏幕睡眠之后,线程还会走,但是不执行重绘操作,会导致Delta和step无限大和小
// Delta += 1;
// step += 1 * fraction;
postInvalidate();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
package com.example.wavedemo;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivityc extends Activity {
private ListView listview;
private MyAdapter1 adapter;
private List lists;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_mainc);
listview=(ListView) this.findViewById(R.id.listview);
lists=new ArrayList();
lists.add(new WaveBean("aaaaaaaaaaaa",90));
lists.add(new WaveBean("bbbbbbbbbbbbb",80));
lists.add(new WaveBean("ccccccccccc",70));
lists.add(new WaveBean("dddddddddddddd",10));
lists.add(new WaveBean("eeeeeeeeeeee",20));
lists.add(new WaveBean("fffffffff",30));
lists.add(new WaveBean("hhhhhhhhhh",40));
lists.add(new WaveBean("iiiiiiiii",60));
lists.add(new WaveBean("ggggggggggg",13));
lists.add(new WaveBean("kkkkkkkkkkk",15));
lists.add(new WaveBean("llllllllllll",24));
lists.add(new WaveBean("mmmmmmmmmmm",27));
lists.add(new WaveBean("nnnnnnnnnnnnnn",56));
lists.add(new WaveBean("ooooooooooo",78));
lists.add(new WaveBean("ppppppppppp",98));
lists.add(new WaveBean("qqqqqqqqqqq",100));
lists.add(new WaveBean("rrrrrrrrrrrr",0));
lists.add(new WaveBean("ssssssssssssss",54));
lists.add(new WaveBean("tttttttttttt",87));
lists.add(new WaveBean("uuuuuuuuuuuu",54));
lists.add(new WaveBean("vvvvvvvvvvvvv",3));
lists.add(new WaveBean("wwwwwwwwwwwwww",67));
lists.add(new WaveBean("xxxxxxxxxxxxxx",97));
lists.add(new WaveBean("yyyyyyyyyyyyyyyy",4));
lists.add(new WaveBean("zzzzzzzzzzzzzzz",50));
adapter=new MyAdapter1(lists, this);
listview.setAdapter(adapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
public void click(View view)
{
}
}
package com.example.wavedemo;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
/**
* Created by ${huozhenpeng} on 15/9/23.
* Company : www.miduo.com
*/
public class MyAdapter1 extends BaseAdapter {
private List list=new ArrayList();
private Context context;
public MyAdapter1(List list,Context context) {
this.context=context;
this.list = list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder=null;
if(convertView==null)
{
convertView= LayoutInflater.from(context).inflate(R.layout.waveitem,null);
holder=new ViewHolder();
holder.textView= (TextView) convertView.findViewById(R.id.textview);
holder.wavetext=(WaveTextView) convertView.findViewById(R.id.waveText);
new Thread(holder.wavetext).start();
convertView.setTag(holder);
}
else
{
holder= (ViewHolder) convertView.getTag();
}
holder.textView.setText(list.get(position).getText());
if(holder.wavetext==null)
{
Log.e("abc", "nullllllll");
}
holder.wavetext.setText(list.get(position).getData());
return convertView;
}
class ViewHolder
{
private TextView textView;
private WaveTextView wavetext;
}
}
package com.example.wavedemo;
import java.io.Serializable;
public class WaveBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String text;
private int data;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
@Override
public String toString() {
return "WaveBean [text=" + text + ", data=" + data + "]";
}
public WaveBean(String text, int data) {
super();
this.text = text;
this.data = data;
}
}