效果图展示,图片有点卡,耐心看会,原程序是很流畅的
实现步骤:
声明变量 初始化画笔、文本大小和坐标 onMeasure()适配wrap_content的宽高 onDraw()画出根据坐标画出两段Text 监听点击事件 在Activity中实现点击事件实现原理(坐标变换原理):整个过程都是基于坐标Y的增加和交换进行处理的,Y值都会一直增加到endY,然后进行交换逻辑
步骤一:声明变量
由于1号店是两句话的滚动,所以我们也是使用两句话来实现的
private Paint mPaint;private float x,startY,endY,firstY,nextStartY,secondY;//整个VIEw的宽高是以第一个为标准的,所以第二句话长度必须小于第一句话private String[] text = {"今日特卖:毛衣3.3折>>>","公告:全场半价>>>"};private float textWIDth,textHeight;//滚动速度private float speech = 0;private static final int CHANGE_SPEECH = 0x01;//是否已经在滚动private boolean isScroll = false;
步骤二:初始化画笔、文本大小和坐标
以第一句话为标准来做控件的宽高标准
//初始化画笔mPaint = new Paint();mPaint.setcolor(color.RED);mPaint.setTextSize(30);//测量文字的宽高,以第一句话为标准Rect rect = new Rect();mPaint.getTextBounds(text[0],text[0].length(),rect);textWIDth = rect.wIDth();textHeight = rect.height();//文字开始的x,y坐标//由于文字是以基准线为基线的,文字底部会突出一点,所以向上收5pxx = getX() + getpaddingleft();startY = gettop() + textHeight + getpaddingtop() - 5;//文字结束的x,y坐标endY = startY + textHeight + getpaddingBottom();//下一个文字滚动开始的y坐标//由于文字是以基准线为基线的,文字底部会突出一点,所以向上收5pxnextStartY = gettop() - 5;//记录开始的坐标firstY = startY;secondY = nextStartY;
步骤三:onMeasure()适配wrap_content的宽高
如果学习过自定义view的话,下面的代码应该很熟悉,就是适配warp_content的模板代码:
@OverrIDeprotected voID onMeasure(int wIDthMeasureSpec,int heightmeasureSpec) { super.onMeasure(wIDthMeasureSpec,heightmeasureSpec); int wIDth = measureWIDth(wIDthMeasureSpec); int height = measureHeight(heightmeasureSpec); setMeasuredDimension(wIDth,height);}private int measureHeight(int heightmeasureSpec) { int result = 0; int size = MeasureSpec.getSize(heightmeasureSpec); int mode = MeasureSpec.getMode(heightmeasureSpec); if (mode == MeasureSpec.EXACTLY) { result = size; } else { result = (int) (getpaddingtop() + getpaddingBottom() + textHeight); if (mode == MeasureSpec.AT_MOST) { result = Math.min(result,size); } } return result;}private int measureWIDth(int wIDthMeasureSpec) { int result = 0; int size = MeasureSpec.getSize(wIDthMeasureSpec); int mode = MeasureSpec.getMode(wIDthMeasureSpec); if (mode == MeasureSpec.EXACTLY) { result = size; } else { result = (int) (getpaddingleft() + getpaddingRight() + textWIDth); if (mode == MeasureSpec.AT_MOST) { result = Math.min(result,size); } } return result;}
步骤四:onDraw()画出根据坐标画出两段Text(已修复:Text停下来时闪一下的BUG)
通过Handler来改变速度
通过isScroll锁,来控制Handler只改变一次
通过invalIDate一直重绘两句话的文字
@OverrIDeprotected voID onDraw(Canvas canvas) { super.onDraw(canvas); //启动滚动 if (!isScroll) { mHandler.sendEmptyMessageDelayed(CHANGE_SPEECH,2000); isScroll = true; } canvas.drawText(text[0],x,mPaint); canvas.drawText(text[1],mPaint); startY += speech; nextStartY += speech; //超出VIEw的控件时 if (startY > endY || nextStartY > endY) { if (startY > endY) { //第一次滚动过后交换值 startY = secondY; nextStartY = firstY; } else if (nextStartY > endY) { //第二次滚动过后交换值 startY = firstY; nextStartY = secondY; } speech = 0; isScroll = false; } invalIDate();}private Handler mHandler = new Handler() { @OverrIDe public voID handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case CHANGE_SPEECH: speech = 1f; break; } }};
步骤五:监听点击事件(已修复:点击事件错乱的问题)
在自定义view重写dispatchtouchEvent处理点击事件,这个也是模板代码:
public ontouchListener Listener;public interface ontouchListener { voID touchListener(String s);}public voID setListener(ontouchListener Listener) { this.Listener = Listener;}@OverrIDepublic boolean dispatchtouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: //点击事件 if (Listener != null) { if (startY >= firstY && nextStartY < firstY) { Listener.touchListener(text[0]); } else if (nextStartY >= firstY && startY < firstY) { Listener.touchListener(text[1]); } } break; } return true;}
步骤六:在Activity中实现点击事件
public class VerTextVIEwActivity extends AppCompatActivity { @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_ver_text_vIEw); VerTextVIEw tv_ver = (VerTextVIEw) findVIEwByID(R.ID.tv_ver); tv_ver.setListener(new VerTextVIEw.ontouchListener() { @OverrIDe public voID touchListener(String s) { Toast.makeText(VerTextVIEwActivity.this,s,Toast.LENGTH_LONG).show(); } }); }}
布局文件
<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:orIEntation="horizontal"> <ImageVIEw androID:layout_wIDth="120dp" androID:layout_height="30dp" androID:background="@drawable/vertextvIEw" /> <com.handsome.app3.Custom.VerTextVIEw.VerTextVIEw androID:ID="@+ID/tv_ver" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:background="#ffffff" androID:padding="8dp" /></linearLayout>
整个类的源码:
/** * =====作者===== * 许英俊 * =====时间===== * 2016/10/11. */public class VerTextVIEw extends VIEw { private Paint mPaint; private float x,secondY; //整个VIEw的宽高是以第一个为标准的,所以第二句话长度必须小于第一句话 private String[] text = {"今日特卖:毛衣3.3折>>>","公告:全场半价>>>"}; private float textWIDth,textHeight; //滚动速度 private float speech = 0; private static final int CHANGE_SPEECH = 0x01; //是否已经在滚动 private boolean isScroll = false; private Handler mHandler = new Handler() { @OverrIDe public voID handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case CHANGE_SPEECH: speech = 1f; break; } } }; public VerTextVIEw(Context context,AttributeSet attrs) { super(context,attrs); //初始化画笔 mPaint = new Paint(); mPaint.setcolor(color.RED); mPaint.setTextSize(30); //测量文字的宽高,以第一句话为标准 Rect rect = new Rect(); mPaint.getTextBounds(text[0],rect); textWIDth = rect.wIDth(); textHeight = rect.height(); //文字开始的x,y坐标 //由于文字是以基准线为基线的,文字底部会突出一点,所以向上收5px x = getX() + getpaddingleft(); startY = gettop() + textHeight + getpaddingtop() - 5; //文字结束的x,y坐标 endY = startY + textHeight + getpaddingBottom(); //下一个文字滚动开始的y坐标 //由于文字是以基准线为基线的,文字底部会突出一点,所以向上收5px nextStartY = gettop() - 5; //记录开始的坐标 firstY = startY; secondY = nextStartY; } @OverrIDe protected voID onMeasure(int wIDthMeasureSpec,int heightmeasureSpec) { super.onMeasure(wIDthMeasureSpec,heightmeasureSpec); int wIDth = measureWIDth(wIDthMeasureSpec); int height = measureHeight(heightmeasureSpec); setMeasuredDimension(wIDth,height); } private int measureHeight(int heightmeasureSpec) { int result = 0; int size = MeasureSpec.getSize(heightmeasureSpec); int mode = MeasureSpec.getMode(heightmeasureSpec); if (mode == MeasureSpec.EXACTLY) { result = size; } else { result = (int) (getpaddingtop() + getpaddingBottom() + textHeight); if (mode == MeasureSpec.AT_MOST) { result = Math.min(result,size); } } return result; } private int measureWIDth(int wIDthMeasureSpec) { int result = 0; int size = MeasureSpec.getSize(wIDthMeasureSpec); int mode = MeasureSpec.getMode(wIDthMeasureSpec); if (mode == MeasureSpec.EXACTLY) { result = size; } else { result = (int) (getpaddingleft() + getpaddingRight() + textWIDth); if (mode == MeasureSpec.AT_MOST) { result = Math.min(result,size); } } return result; } @OverrIDe protected voID onDraw(Canvas canvas) { super.onDraw(canvas); //启动滚动 if (!isScroll) { mHandler.sendEmptyMessageDelayed(CHANGE_SPEECH,2000); isScroll = true; } canvas.drawText(text[0],mPaint); canvas.drawText(text[1],mPaint); startY += speech; nextStartY += speech; //超出VIEw的控件时 if (startY > endY || nextStartY > endY) { if (startY > endY) { //第一次滚动过后交换值 startY = secondY; nextStartY = firstY; } else if (nextStartY > endY) { //第二次滚动过后交换值 startY = firstY; nextStartY = secondY; } speech = 0; isScroll = false; } invalIDate(); } public ontouchListener Listener; public interface ontouchListener { voID touchListener(String s); } public voID setListener(ontouchListener Listener) { this.Listener = Listener; } @OverrIDe public boolean dispatchtouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: //点击事件 if (Listener != null) { if (startY >= firstY && nextStartY < firstY) { Listener.touchListener(text[0]); } else if (nextStartY >= firstY && startY < firstY) { Listener.touchListener(text[1]); } } break; } return true; }}
以上所述是小编给大家介绍的AndroID自定义view实现仿1号店垂直滚动广告条代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持!
总结以上是内存溢出为你收集整理的Android自定义View实现仿1号店垂直滚动广告条代码全部内容,希望文章能够帮你解决Android自定义View实现仿1号店垂直滚动广告条代码所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)