效果图

原理分析

整个过程都是基于坐标Y的增加和交换进行处理的,Y值都会一直增加到endY,然后进行交换逻辑

实现步骤

1、初始化变量

由于1号店是两句话的滚动,所以我们也是使用两句话来实现的

public class VerTextView extends View {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;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], 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;}
}

2、获取宽和高

@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;
}

3、绘制图形

  • 通过Handler来改变速度
  • 通过isScroll控制Handler只发送一次
  • 通过invalidate一直重绘两句话的文字
private Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) {case CHANGE_SPEECH:speech = 1f;break;}}
};@Override
protected void onDraw(Canvas canvas) {super.onDraw(canvas);//启动滚动if (!isScroll) {mHandler.sendEmptyMessageDelayed(CHANGE_SPEECH, 2000);isScroll = true;}canvas.drawText(text[0], x, startY, mPaint);canvas.drawText(text[1], x, nextStartY, 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();
}

4、监听点击事件

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;
}

5、实现点击事件

public class VerTextViewActivity extends AppCompatActivity {@Overrideprotected 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() {@Overridepublic void touchListener(String s) {Toast.makeText(VerTextViewActivity.this, s, Toast.LENGTH_LONG).show();}});}
}

6、布局实现

<?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>

7、源码下载

滚动广告View下载

Android自定义View——仿1号店垂直滚动广告条实现相关推荐

  1. Android基础控件——ViewFlipper的使用,仿淘宝头条垂直滚动广告条

    ViewFlipper的使用,仿淘宝头条垂直滚动广告条 学习,学习,学以致用 ViewFlipper是安卓自带的控件,很多人可能很少知道这个控件,这个控件很简单,也很好理解,能不能用上实战就看你们的本 ...

  2. Android仿支付宝UI功能开发,Android 自定义view仿支付宝咻一咻功能

    支付宝上有一个咻一咻的功能,就是点击图片后四周有水波纹的这种效果,今天也写一个类似的功能. 效果如下所示: 思路: 就是几个圆的半径不断在变大,这个可以使用动画缩放实现,还有透明动画 还有就是这是好几 ...

  3. android 高仿 探探卡片滑动,Android自定义View仿探探卡片滑动效果

    Android自定义View仿探探卡片滑动这种效果网上有很多人已经讲解了实现思路,大多都用的是RecyclerView来实现的,但是我们今天来换一种实现思路,只用一个自定义的ViewGroup来搞定这 ...

  4. android wear支付宝6,Android自定义View仿支付宝输入六位密码功能

    跟选择银行卡界面类似,也是用一个PopupWindow,不过输入密码界面是一个自定义view,当输入六位密码完成后用回调在Activity中获取到输入的密码并以Toast显示密码.效果图如下: 自定义 ...

  5. android的动态tab,Android自定义view仿QQ的Tab按钮动画效果(示例代码)

    话不多说 先上效果图 实现其实很简单,先用两张图 一张是背景的图,一张是笑脸的图片,笑脸的图片是白色,可能看不出来.实现思路:主要是再触摸view的时候同时移动这两个图片,但是移动的距离不一样,造成的 ...

  6. Android控件——ViewFlipper的使用,垂直滚动广告条

    1 前言 之前开发过一个TextView的滚动显示,但是局限性比较大,只能显示文字,不能显示图片等其他View.对比淘宝App的淘宝头条,发现显示的内容挺丰富的.网上搜索了下资料发现android自带 ...

  7. oracle number型步数,Android自定义View仿QQ计步器

    自定义计步器 Android自定义View是Android开发中比较重要的一项,也是很多开发者比较怕的一个东西.其实只要认真去学习,自定义View其实没有那么可怕:相反的,我们还能从自定义View中找 ...

  8. Android自定义View——仿ViVO X6 极速闪充动画效果

    一直都在看自定义View,经过一个星期的坚持,基本上能够写出一些比较实用的控件效果了,今天天气太热,就待在家里玩手机,然后手机没电了,在充电的时候,看到了手机的充电动画,觉得挺酷,然后自己我就仔细的分 ...

  9. Android 垂直滚动广告条,仿淘宝头条垂直滚动展示最新消息

    最新的项目有个新需求,就是要去垂直滚动去展示最新发布的消息,类似淘宝头条的那种 1.功能实现其实很简单,就用到Android 的原生控件ViewFlipper <ViewFlipperandro ...

最新文章

  1. 24点游戏c语言链表做法,C语言实现24点程序(示例代码)
  2. c语言单片机求最小公倍数,单片机常用的14个C语言算法,要熟记在心哦!
  3. ThinkPHP下隐藏index.php以及URL伪静态
  4. oracle数据库两表数据比较
  5. vba显示正在加载_利用VBA代码显示工作簿的路径及完全路径的方案及对工作薄的操作...
  6. 我想开一家美团外卖店,不做堂食,有什么好的建议吗?
  7. 移动硬盘常见故障分析
  8. Intellig idea导入项目第一次运行报错- Error running ‘Application‘: Command line is too long—— 解决方法
  9. 禅道备份功能_禅道数据库备份
  10. 详解电脑换主板需要重装系统吗
  11. linux系统USB转网卡驱动异常,usb 网卡驱动安装问题(芯片AX88772B)
  12. BAT转EXE 小程序
  13. 如何从gitbub上clone代码
  14. excel多个表格数据汇总怎么做?
  15. 13个创意爆棚的广告图片
  16. Q版京剧脸谱来喽——武生
  17. SQL 的一点简单的面试题求助
  18. 【Cesium】根据两点坐标获取Heading(朝向),Pitch(俯仰角)和模型矩阵
  19. BestCoder Round #85 (hdu5804,hdu5805,hdu5806,hdu5807)
  20. 【自动控制原理】【计算机控制技术】通俗易懂地理解Z变换

热门文章

  1. 想学习SharePoint,需要准备哪些方面的准备?--写给SharePoint新人
  2. 中国人的“门当户对”还那么重要吗?
  3. 国产手机:2022疑无路,2023又一村?
  4. 杂谈——探秘字节流与字符流
  5. html5plus 学习摘要
  6. 一封黑客写给黑客的信
  7. python decode函数的用法_Oracle DECODE函数的用法详解
  8. IBM X3650 服务器使用SERVERAID 8K-1做RAID1更换硬盘
  9. 更新数据限制条数 mysql_mysql update limit mysql更新限制语句用法
  10. iOS【IOS视频直播:高仿腾讯旗下NOW直播映客直播类型】