最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

android自定義View實(shí)現(xiàn)跑馬燈效果

 更新時(shí)間:2018年04月26日 08:31:25   作者:Railshiqian  
這篇文章主要為大家詳細(xì)介紹了android自定義View實(shí)現(xiàn)跑馬燈效果,實(shí)現(xiàn)連續(xù)滾動(dòng)的效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

android自帶的TextView可以實(shí)現(xiàn)跑馬燈效果,但是有很多的局限性;比如需要設(shè)置ellipsize=”marquee”,獲取 focusable=”true”,設(shè)置singleLine=”true”,控件里的內(nèi)容需要超過控件本身的長(zhǎng)度,無法控制滾動(dòng)速度和滾動(dòng)暫停和繼續(xù)滾動(dòng)功能,各種限制導(dǎo)致用起來特別不順手,幾乎無法使用到生產(chǎn)環(huán)境中,在此背景下,需要自定義View實(shí)現(xiàn)跑馬燈效果。

使用主要方法:自定義View重寫onDraw方法,通過canvas.drawText()方法來顯示文字,利用Handler不斷地繪制文字,并控制文字開始繪制的X軸的位置,來實(shí)現(xiàn)連續(xù)滾動(dòng)的效果。

實(shí)現(xiàn)步驟:

1、自定義view的class:

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.Rect;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;

public class MarqueenView extends View {

 /*
  * 1、自定義View的屬性 2、在View的構(gòu)造方法中獲得我們自定義的屬性 [ 3、重寫onMesure ] 4、重寫onDraw
  */

 /*
  * 文本
  */
 private String mTitleText;

 /**
  * 文本的顏色
  */
 private int mTitleTextColor;

 /**
  * 文本的大小
  */
 private int mTitleTextSize;

 /**
  * 繪制時(shí)控制文本繪制的范圍
  */
 private Rect mBound, usualBound;

 // 畫筆
 private Paint mPaint;

 private int spead = 15;

 private int length = 3;

 private int currentLength;

 @SuppressLint("HandlerLeak")
 private Handler handler = new Handler() {
  @Override
  public void handleMessage(android.os.Message msg) {
   if (mBound.width() <= getWidth()) {
    if (currentLength >= 120 + (getWidth() / length) * length) {
     currentLength = length;
    } else {
     currentLength = currentLength + length;
    }
   } else {
    if (currentLength >= (mBound.width() + 120)) {
     currentLength = length;
    } else {
     currentLength = currentLength + length;
    }
   }

   invalidate();
   handler.sendEmptyMessageDelayed(0, spead);

  };
 };

 public MarqueenView(Context context, AttributeSet attrs) {
  this(context, attrs, 0);
  currentLength = length;
 }

 public MarqueenView(Context context) {
  this(context, null);
 }

 public MarqueenView(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);

  TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTitleView, defStyle, 0);

  int n = a.getIndexCount();
  for (int i = 0; i < n; i++) {
   int attr = a.getIndex(i);

   switch (attr) {
   case R.styleable.CustomTitleView_titleText:
    mTitleText = a.getString(attr);
    break;
   case R.styleable.CustomTitleView_titleTextColor:
    mTitleTextColor = a.getColor(attr, Color.BLACK);
    break;
   case R.styleable.CustomTitleView_titleTextSize:
    mTitleTextSize = a.getDimensionPixelSize(attr,
      (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
    break;
   }

  }
  a.recycle();

  mPaint = new Paint();
  mPaint.setTextSize(mTitleTextSize);

  mBound = new Rect();
  usualBound = new Rect();
  mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);
  mPaint.getTextBounds("1234567890QqYy你好", 0, 16, usualBound);
 }


 /*
  * EXACTLY:一般是設(shè)置了明確的值或者是MATCH_PARENT AT_MOST:表示子布局限制在一個(gè)最大值內(nèi),一般為WARP_CONTENT
  * UNSPECIFIED:表示子布局想要多大就多大,很少使用
  */

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

  int widthMode = MeasureSpec.getMode(widthMeasureSpec);
  int widthSize = MeasureSpec.getSize(widthMeasureSpec);

  int heightMode = MeasureSpec.getMode(heightMeasureSpec);
  int heightSize = MeasureSpec.getSize(heightMeasureSpec);
  int width;
  int height;
  if (widthMode == MeasureSpec.EXACTLY) {
   width = widthSize;
  } else {
   mPaint.setTextSize(mTitleTextSize);
   mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);
   float textWidth = mBound.width();// 字體寬度

   // 控件padding
   int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight());
   width = desired;
  }

  if (heightMode == MeasureSpec.EXACTLY) {
   height = heightSize;
  } else {
   mPaint.setTextSize(mTitleTextSize);
   mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);
   float textHeight = mBound.height();
   int desired = (int) (getPaddingTop() + textHeight + getPaddingBottom());
   height = desired;
  }
  // setMeasuredDimension((width / length) * length, height);
  setMeasuredDimension(width, height + usualBound.bottom);
 }

 @Override
 protected void onDraw(Canvas canvas) {


  mPaint.setColor(mTitleTextColor);
  if (mBound.width() <= getWidth()) {


   if (currentLength < mBound.width()) {
    canvas.drawText(mTitleText, getPaddingLeft() - currentLength, getHeight() - usualBound.bottom, mPaint);
   }

   if (currentLength >= 120) {
    canvas.drawText(mTitleText, getWidth() - currentLength + 120, getHeight() - usualBound.bottom, mPaint);
   }

  } else {


   if (currentLength < mBound.width()) {
    canvas.drawText(mTitleText, getPaddingLeft() - currentLength, getHeight() - usualBound.bottom, mPaint);
   }

   if (currentLength >= mBound.width() - getWidth() + 120) {
    canvas.drawText(mTitleText, 120 - currentLength + mBound.width(), getHeight() - usualBound.bottom, mPaint);
   }

  }

 }

 public static int getFontHeight(Integer textSize) {
  Paint paint = new Paint();
  if (textSize != null) {
   paint.setTextSize(textSize);
  }
  FontMetrics fm = paint.getFontMetrics();
  return (int) (fm.descent - fm.ascent);
 }

 public void startScroll() {
  handler.removeMessages(0);
  handler.sendEmptyMessage(0);
 }

 public void stopScroll() {
  handler.removeMessages(0);
  currentLength = 0;
  invalidate();
 }

 public void setScrollLength(int length) {
  this.length = length;
  currentLength = length;
 }

 public void setSpead(int spead) {
  this.spead = spead;
 }

 public void setText(String msg) {
  mTitleText = msg;
  mBound = new Rect();
  mPaint.getTextBounds(msg, 0, mTitleText.length(), mBound);
 }


}

2、在values的attrs.xml文件中需要加入自定義的屬性,字體大小、顏色、和初始內(nèi)容,這里有待改進(jìn)

<?xml version="1.0" encoding="utf-8"?>
<resources>

 <attr name="titleText" format="string" />
 <attr name="titleTextColor" format="color" />
 <attr name="titleTextSize" format="dimension" />

 <declare-styleable name="CustomTitleView">
  <attr name="titleText" />
  <attr name="titleTextColor" />
  <attr name="titleTextSize" />
 </declare-styleable>
</resources>

3、在layout的布局文件中引用此控件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:custom="http://schemas.android.com/apk/res/***這里寫上自己的包名***"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical" >

 <com.example.MarqueenView
 android:id="@+id/main_marquee_view"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 custom:titleText=" "
 custom:titleTextColor="#666666"
 custom:titleTextSize="14sp"/>
 </LinearLayout>

4、上面準(zhǔn)備好后,就可以在activity中設(shè)置跑馬燈并開始滾動(dòng)了

mv = (MarqueenView) findViewById(R.id.main_marquee_view);
mv.stopScroll();
mv.setText("滾動(dòng)內(nèi)容");// 設(shè)置顯示內(nèi)容
//mv.setSpead(15);//滾動(dòng)頻率,默認(rèn)15毫秒一次,數(shù)值太小會(huì)影響效率
//mv.setScrollLength(3);//默認(rèn)每次左移3px,數(shù)值太大會(huì)有停頓感,數(shù)值太小滾動(dòng)會(huì)變慢
mv.startScroll();

//記得在Ondestroy中停止?jié)L動(dòng),方便回收
@Override
 protected void onDestroy() {
  try {
   mv.stopScroll();
   mv = null;
  } catch (Throwable e) {
   e.printStackTrace();
  }
  super.onDestroy();
 }

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android利用WindowManager生成懸浮按鈕及懸浮菜單

    Android利用WindowManager生成懸浮按鈕及懸浮菜單

    這篇文章主要為大家詳細(xì)介紹了Android利用WindowManager生成懸浮按鈕及懸浮菜單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • Android編程簡(jiǎn)單解析JSON格式數(shù)據(jù)的方法示例

    Android編程簡(jiǎn)單解析JSON格式數(shù)據(jù)的方法示例

    這篇文章主要介紹了Android編程簡(jiǎn)單解析JSON格式數(shù)據(jù)的方法,結(jié)合實(shí)例形式分析了Android編程解析json格式數(shù)據(jù)的實(shí)現(xiàn)方法與相關(guān)操作技巧,需要的朋友可以參考下
    2017-08-08
  • Android獲得當(dāng)前正在顯示的activity類名的方法

    Android獲得當(dāng)前正在顯示的activity類名的方法

    這篇文章主要介紹了Android獲得當(dāng)前正在顯示的activity類名的方法,分析了權(quán)限的修改與Java代碼的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-01-01
  • Android車載空調(diào)系統(tǒng)(HVAC)開發(fā)方法分析

    Android車載空調(diào)系統(tǒng)(HVAC)開發(fā)方法分析

    HVAC?全稱:供暖通風(fēng)與空氣調(diào)節(jié)(Heating?Ventilation?and?Air?Conditioning),用戶可以通過他來控制整個(gè)汽車的空調(diào)系統(tǒng),是汽車中非常重要的一個(gè)功能,汽車的空調(diào)HMI雖然并不復(fù)雜,但是大多都是用符號(hào)來表示功能,必須理解空調(diào)的各個(gè)符號(hào)表示的含義
    2023-12-12
  • 安卓(Android)ListView 顯示圖片文字

    安卓(Android)ListView 顯示圖片文字

    本文主要介紹Android中重要組件ListView,在編程中經(jīng)常會(huì)用到ListView 顯示圖片和文字,這里給大家一個(gè)小例子,希望能幫助有需要的同學(xué)
    2016-07-07
  • Android手機(jī)保持屏幕高亮方法

    Android手機(jī)保持屏幕高亮方法

    這篇文章主要介紹了Android手機(jī)保持屏幕高亮方法,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2015-06-06
  • android滑動(dòng)解鎖震動(dòng)效果的開啟和取消

    android滑動(dòng)解鎖震動(dòng)效果的開啟和取消

    在4.0的圓環(huán)滑動(dòng)解鎖中,我們點(diǎn)擊下去的時(shí)候會(huì)有震動(dòng)效果,因?yàn)檫@個(gè)控件設(shè)置的震動(dòng)效果沒有綁定設(shè)置中設(shè)置的觸摸振動(dòng)開關(guān)來取消振動(dòng)效果,下邊這個(gè)例子實(shí)現(xiàn)了開啟和取消的方法
    2013-06-06
  • AndroidStuio插件開發(fā)適用于jetbrains全家桶

    AndroidStuio插件開發(fā)適用于jetbrains全家桶

    這篇文章主要介紹了AndroidStuio插件開發(fā)適用于jetbrains全家桶,本文通過實(shí)例給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • Android RenderScript高斯模糊

    Android RenderScript高斯模糊

    這篇文章主要介紹了Android RenderScript高斯模糊的相關(guān)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • Android從相冊(cè)選擇圖片剪切和上傳

    Android從相冊(cè)選擇圖片剪切和上傳

    這篇文章主要為大家詳細(xì)介紹了Android從相冊(cè)選擇一個(gè)圖片剪切、上傳的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-02-02

最新評(píng)論

岳西县| 黎川县| 社旗县| 友谊县| 元谋县| 黔西| 余庆县| 图们市| 罗源县| 大荔县| 错那县| 江源县| 敖汉旗| 洞口县| 连平县| 奉节县| 镇平县| 绥江县| 额尔古纳市| 金阳县| 银川市| 合江县| 石棉县| 睢宁县| 偃师市| 大丰市| 康乐县| 临城县| 页游| 湖北省| 齐河县| 澄城县| 昭平县| 湖北省| 微博| 福清市| 嵊州市| 应城市| 武功县| 尼勒克县| 莱州市|