Android自定义View实现仿1号店垂直滚动广告条代码

Android自定义View实现仿1号店垂直滚动广告条代码,第1张

概述效果图展示,图片有点卡,耐心看会,原程序是很流畅的实现步骤:声明变量

效果图展示,图片有点卡,耐心看会,原程序是很流畅的

实现步骤:

声明变量 初始化画笔、文本大小和坐标 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号店垂直滚动广告条代码所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/web/1147190.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存