Android 自定义TextView,水平滚动
程序员文章站
2022-04-12 22:07:19
package com.my.androidtext.view;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Paint;import android.os.Parcel;import android.os.Parcelable;import android.text.TextPaint;import ....
package com.my.androidtext.view; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.os.Parcel; import android.os.Parcelable; import android.text.TextPaint; import android.util.AttributeSet; import android.view.View; import androidx.appcompat.widget.AppCompatTextView; public class HorizontalTextView extends AppCompatTextView { private float textLength = 0f; private float viewWidth = 0f; private float viewHeight = 0f; private float step = 0f; private float y = 0f; public boolean isStarting = false; private Paint paint = null; private Paint mBitPaint = null; private Bitmap mBitmap; private String text = ""; private boolean isInit = false; private boolean isCanScroll = true; private static final String POINT = "..."; private boolean textMarginRight = false; public HorizontalTextView(Context context) { super(context); initTextView(); } public HorizontalTextView(Context context, AttributeSet attrs) { super(context, attrs); initTextView(); } public HorizontalTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initTextView(); } @Override public Parcelable onSaveInstanceState() { Parcelable superState = super.onSaveInstanceState(); SavedState ss = new SavedState(superState); ss.step = step; ss.isStarting = isStarting; return ss; } @Override public void onRestoreInstanceState(Parcelable state) { if (!(state instanceof SavedState)) { super.onRestoreInstanceState(state); return; } SavedState ss = (SavedState) state; super.onRestoreInstanceState(ss.getSuperState()); step = ss.step; isStarting = ss.isStarting; } public static class SavedState extends View.BaseSavedState { public boolean isStarting = false; public float step = 0.0f; SavedState(Parcelable superState) { super(superState); } @Override public void writeToParcel(Parcel out, int flags) { super.writeToParcel(out, flags); out.writeBooleanArray(new boolean[]{isStarting}); out.writeFloat(step); } public static final Creator<SavedState> CREATOR = new Creator<SavedState>() { public SavedState[] newArray(int size) { return new SavedState[size]; } @Override public SavedState createFromParcel(Parcel in) { return new SavedState(in); } }; private SavedState(Parcel in) { super(in); try { boolean[] b = null; in.readBooleanArray(b); if (b != null && b.length > 0) isStarting = b[0]; step = in.readFloat(); } catch (Exception e) { } } } public void setCanScroll(boolean canScroll) { isCanScroll = canScroll; } public void setTextMarginRight(boolean textMarginRight) { this.textMarginRight = textMarginRight; } private void startScroll() { isStarting = true; invalidate(); } private void stopScroll() { isStarting = false; invalidate(); } @Override public void onDraw(Canvas canvas) { if (!isInit) { initTextView(); } canvas.drawText(text, step, y, paint); if (!isStarting) { return; } step -= 1; if (-step > textLength) step = viewWidth; invalidate(); } @Override protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) { super.onTextChanged(text, start, lengthBefore, lengthAfter); isInit = false; } private void initTextView() { paint = this.getPaint(); paint.setColor(getCurrentTextColor()); paint.setTextSize(getTextSize()); text = this.getText().toString().trim(); textLength = paint.measureText(text); step = 0; Paint.FontMetrics fontMetrics = paint.getFontMetrics(); ///文字一半的高度再减去基线到bottom的高度, float halfHeight = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom; y = getHeight() / 2 + (int) halfHeight; if (textLength > viewWidth) { if (isCanScroll) { startScroll(); } else { reInitTextWithPoint(); stopScroll(); } } else { if (textMarginRight) { step = viewWidth - textLength; } stopScroll(); } isInit = true; } private void reInitTextWithPoint() { TextPaint textPaint = new TextPaint(); textPaint.setTextSize(this.getTextSize()); while (textPaint.measureText(text) >= (viewWidth - textPaint.measureText(POINT))) { text = text.substring(0, text.length() - 1); } text += POINT; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); viewWidth = View.MeasureSpec.getSize(widthMeasureSpec); viewHeight = View.MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension((int) viewWidth, (int) viewHeight); } }
本文地址:https://blog.csdn.net/winskyan/article/details/108736794
推荐阅读
-
解析在Android中为TextView增加自定义HTML标签的实现方法
-
android实现上下滚动的TextView
-
Android开发实现自定义水平滚动的容器示例
-
Android开发自定义TextView省略号样式的方法
-
android listview 水平滚动和垂直滚动的小例子
-
Android自定义TextView跑马灯效果
-
Android中实现多行、水平滚动的分页的Gridview实例源码
-
Android使用Recyclerview实现图片水平自动循环滚动效果
-
Android自定义竖排TextView实现实例
-
Android开发技巧之在a标签或TextView控件中单击链接弹出Activity(自定义动作)