日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

android自动跑马灯,Android-最强跑马灯

發布時間:2023/12/4 Android 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android自动跑马灯,Android-最强跑马灯 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Android--最強跑馬燈

Android 跑馬燈已經有很多版本,從最基本的TextView,到重寫TextView使TextView取消焦點限制,還有重寫TextView利用ScrollTo方法寫的,基本都能滿足一般需要。然而在使用過程中,發現一些意外---有時會不播放,刷新線程還在繼續但就是不播放,最后在github上找到一個用動畫實現跑馬燈的項目(項目地址:https://github.com/ened/Android-MarqueeView,再次對作者表示感謝),改造了一番,總算ok了。以后再也不用為跑馬燈煩惱了。

特點:

1. 文字長短都有跑馬燈效果。

2. 可以控制速度

代碼:

package com.example.test_marquee;

import android.content.Context;

import android.graphics.Paint;

import android.text.Editable;

import android.text.TextWatcher;

import android.util.AttributeSet;

import android.util.Log;

import android.view.Gravity;

import android.view.View;

import android.view.ViewGroup;

import android.view.animation.Animation;

import android.view.animation.Interpolator;

import android.view.animation.LinearInterpolator;

import android.view.animation.TranslateAnimation;

import android.widget.LinearLayout;

import android.widget.ScrollView;

import android.widget.TextView;

/**

* LinearLayout作為父View,必須有一個子TextView

*

* 利用動畫實現

*/

public class MarqueeView extends LinearLayout {

private static final int TEXTVIEW_VIRTUAL_WIDTH = 2000;/* TextView默認寬度 */

private static final int DEFAULT_SPEED = 35;/* 默認滾動速度 越大滾動越慢 */

private static final int DEFAULT_ANIMATION_PAUSE = 0;/* 出去動畫與進入動畫的時間間隔 */

private static final String TAG = MarqueeView.class.getSimpleName();

private TextView mTextField;/* 該跑馬燈的孫子View之TextView */

private ScrollView mScrollView;/* 該跑馬燈的子View之mScrollView */

private Animation mMoveTextOut = null;/* 作用于TextView的動畫 --出去 */

private Animation mMoveTextIn = null;/* 作用于TextView的動畫 --進入 */

private Paint mPaint;

private int mSpeed = DEFAULT_SPEED;

private int mAnimationPause = DEFAULT_ANIMATION_PAUSE;

private Interpolator mInterpolator = new LinearInterpolator();

private Runnable mAnimationStartRunnable;

/** 字符串之間的間隔 */

private String interval = " ";

private String stringOfItem = "";

/** str+interval的長度 */

private float widthOfItem = 0;

private float widthOfTextView;

private String stringOfTextView = "";

private float startXOfOut = 0;

private float endXOfOut = 0;

private float startXOfIn = 0;

private float endXOfIn = 0;

public MarqueeView(Context context) {

super(context);

init(context);

}

public MarqueeView(Context context, AttributeSet attrs) {

super(context, attrs);

init(context);

}

public MarqueeView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

init(context);

}

private void init(Context context) {

// init helper

mPaint = new Paint();

mPaint.setAntiAlias(true);

mPaint.setStrokeWidth(1);

mPaint.setStrokeCap(Paint.Cap.ROUND);

mInterpolator = new LinearInterpolator();

}

// 當給子View分配位置和尺寸時調用。

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

super.onLayout(changed, l, t, r, b);

Logcat.d(TAG, "onLayout called!" + "changed: " + changed);

if (getChildCount() == 0 || getChildCount() > 1) {

throw new RuntimeException(

"MarqueeView must have exactly one child element.");

}

//

if (changed) {

View v = getChildAt(0);

if (!(v instanceof TextView)) {

throw new RuntimeException(

"The child view of this MarqueeView must be a TextView instance.");

}

initView(getContext());

mTextField.setText(mTextField.getText());

}

}

/** Starts the configured marquee effect. */

public void startMarquee() {

Logcat.d(TAG, "startMarquee called");

startTextFieldAnimation();

}

// 一旦開始動畫,動畫結束開始由監聽器負責。

private void startTextFieldAnimation() {

mAnimationStartRunnable = new Runnable() {

public void run() {

mTextField.startAnimation(mMoveTextOut);

}

};

postDelayed(mAnimationStartRunnable, mAnimationPause);

}

/**

* Disables the animations.

*/

public void reset() {

if (mAnimationStartRunnable == null)

return;

removeCallbacks(mAnimationStartRunnable);

mTextField.clearAnimation();

mMoveTextOut.reset();

mMoveTextIn.reset();

invalidate();

}

private void prepareAnimation() {

// Measure

mPaint.setTextSize(mTextField.getTextSize());

mPaint.setTypeface(mTextField.getTypeface());

float mTextWidth = mPaint.measureText(mTextField.getText().toString());

float width = getMeasuredWidth();

startXOfOut = -(mTextWidth - width) % widthOfItem;

endXOfOut = -mTextWidth + width;

startXOfIn = -(mTextWidth - width) % widthOfItem;

endXOfIn = -mTextWidth + width;

final int duration = ((int) Math.abs(startXOfOut - endXOfOut) * mSpeed);

if (BuildConfig.DEBUG) {

Log.d(TAG, "(int) Math.abs(startXOfOut - endXOfOut) : "

+ (int) Math.abs(startXOfOut - endXOfOut));

Log.d(TAG, "mSpeed : " + mSpeed);

Log.d(TAG, "startXOfOut : " + startXOfOut);

Log.d(TAG, "endXOfOut : " + endXOfOut);

Log.d(TAG, "startXOfIn : " + startXOfIn);

Log.d(TAG, "endXOfIn : " + endXOfIn);

Log.d(TAG, "duration : " + duration);

}

mMoveTextOut = new TranslateAnimation(startXOfOut, endXOfOut, 0, 0);

mMoveTextOut.setDuration(duration);

mMoveTextOut.setInterpolator(mInterpolator);

mMoveTextOut.setFillAfter(true);

mMoveTextIn = new TranslateAnimation(startXOfIn, endXOfIn, 0, 0);

mMoveTextIn.setDuration(duration);

mMoveTextIn.setStartOffset(mAnimationPause);

mMoveTextIn.setInterpolator(mInterpolator);

mMoveTextIn.setFillAfter(true);

mMoveTextOut.setAnimationListener(new Animation.AnimationListener() {

public void onAnimationStart(Animation animation) {

}

public void onAnimationEnd(Animation animation) {

mTextField.startAnimation(mMoveTextIn);

}

public void onAnimationRepeat(Animation animation) {

}

});

mMoveTextIn.setAnimationListener(new Animation.AnimationListener() {

public void onAnimationStart(Animation animation) {

}

public void onAnimationEnd(Animation animation) {

startTextFieldAnimation();

}

public void onAnimationRepeat(Animation animation) {

}

});

}

/** 初始化子View */

private void initView(Context context) {

// Scroll View

LayoutParams sv1lp = new LayoutParams(LayoutParams.MATCH_PARENT,

LayoutParams.WRAP_CONTENT);

sv1lp.gravity = Gravity.CENTER_HORIZONTAL;

mScrollView = new ScrollView(context);

// Scroll View 1 - Text Field

mTextField = (TextView) getChildAt(0);

removeView(mTextField);

mScrollView.addView(mTextField, new ScrollView.LayoutParams(

TEXTVIEW_VIRTUAL_WIDTH, LayoutParams.WRAP_CONTENT));

mTextField.addTextChangedListener(new TextWatcher() {

@Override

public void beforeTextChanged(CharSequence charSequence, int i,

int i2, int i3) {

}

@Override

public void onTextChanged(CharSequence charSequence, int i, int i2,

int i3) {

}

@Override

public void afterTextChanged(Editable editable) {

Logcat.d(TAG, "afterTextChanged called");

// 如果提供的字符串未被加工過,就先加工,否則就開始動畫

if (!stringOfTextView.equals(editable.toString())) {

String str = editable.toString();

mPaint.setTextSize(mTextField.getTextSize());

mPaint.setTypeface(mTextField.getTypeface());

stringOfItem = str + interval;

widthOfItem = mPaint.measureText(stringOfItem);

stringOfTextView = stringOfItem;

widthOfTextView = widthOfItem;

while (widthOfTextView <= 2 * getMeasuredWidth()) {

stringOfTextView += stringOfItem;

widthOfTextView = mPaint.measureText(stringOfTextView);

}

Logcat.d(TAG, "string of TextView deal ok!###");

Logcat.d(TAG, "lengthOfll: " + getMeasuredWidth() + "###");

Logcat.d(TAG, "lengthOfTextView: " + widthOfTextView

+ "###");

Logcat.d(TAG, "CONTENT: " + stringOfTextView + "###");

// 設置起始

mTextField.setText(stringOfTextView);

return;

}

reset();

prepareAnimation();

expandTextView();

post(new Runnable() {

@Override

public void run() {

startMarquee();

}

});

}

});

addView(mScrollView, sv1lp);

}

private void expandTextView() {

ViewGroup.LayoutParams lp = mTextField.getLayoutParams();

lp.width = (int) widthOfTextView + 5;

mTextField.setLayoutParams(lp);

}

}

使用:

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

tools:context=".MainActivity" >

android:id="@+id/marqueeView"

android:layout_width="match_parent"

android:layout_height="wrap_content" >

android:id="@+id/tv_marquee"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:ellipsize="end"

android:singleLine="true"

android:text="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do."

android:textSize="20sp"

android:textStyle="bold" />

下載地址:

總結

以上是生活随笔為你收集整理的android自动跑马灯,Android-最强跑马灯的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。