国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android自定義View實現仿1號店垂直滾動廣告條代碼

2019-12-12 03:59:12
字體:
來源:轉載
供稿:網友

效果圖展示,圖片有點卡,耐心看會,原程序是很流暢的

實現步驟:

  • 聲明變量
  • 初始化畫筆、文本大小和坐標
  • 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], 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, 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();}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, 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; 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], 0, text[0].length(), 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], 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(); } 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號店垂直滾動廣告條代碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 松溪县| 揭西县| 庄河市| 安泽县| 木里| 东城区| 建始县| 黑河市| 富阳市| 奇台县| 扎兰屯市| 德阳市| 汉中市| 中牟县| 门头沟区| 黑山县| 曲松县| 孝感市| 湖州市| 台中市| 湘阴县| 景宁| 无为县| 石景山区| 驻马店市| 拜城县| 曲沃县| 富顺县| 河北省| 科技| 尚志市| 珲春市| 五寨县| 彩票| 昌乐县| 镇赉县| 七台河市| 惠安县| 安阳县| 平远县| 攀枝花市|