public class VerticalScrollTextView extends TextView implements Runnable{
//绘制歌词画笔
private Paint mContentPaint;
//绘制基线画笔
private Paint mLinePaint;
//绘制滑动进度背景画笔
private Paint mRectPaint;
//歌词数据
private List<Sentence> mDataList;
//行数
private int index = 0 ;
//当前view的宽
private float mX;
//当前view的高
private float mY;
//当前view垂直方向中线
private float middleY;
//行与行之间的间距
private final static int DY = 80 ;
//歌词文字大小
private int mTextSize = 35;
//歌词中间字体的大小
private int mBigTextSize = 45;
//当前是否按下
private boolean isTouch = false ;
//上一次触摸view的y轴坐标
private float mLastY;
//是否正在滑动
private boolean isMoving;
//记录上一次滑动的时间
private long lastMoveTime;
//滑动速度追踪类
private VelocityTracker mVelocityTracker;
//滑动最大速度
private int mMaximumVelocity;
//歌词是否为空
private boolean isEmpty;
public VerticalScrollTextView(Context context) {
this(context,null);
}
public VerticalScrollTextView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public VerticalScrollTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//获取最大的滑动速度值
mMaximumVelocity = ViewConfiguration.get(context)
.getScaledMaximumFlingVelocity();
init();
}
private void init(){
setFocusable(true);
setClickable(true);
//歌词为空设置默认值
if(mDataList==null){
mDataList = new ArrayList<>();
Sentence sentence = new Sentence(0,"没有获取到歌词",0);
mDataList.add(sentence);
isEmpty = true ;
}
//初始化歌词画笔
mContentPaint = new Paint();
mContentPaint.setTextSize(mTextSize);
mContentPaint.setAntiAlias(true);
mContentPaint.setColor(Color.parseColor("#e5e2e2"));
//设置为serif字体
mContentPaint.setTypeface(Typeface.SERIF);
//设置字体为居中
mContentPaint.setTextAlign(Paint.Align.CENTER);
//初始化基线画笔
mLinePaint = new Paint();
mLinePaint.setAntiAlias(true);
mLinePaint.setStrokeWidth(1);
mLinePaint.setColor(Color.WHITE);
//进度背景颜色画笔
mRectPaint = new Paint();
mLinePaint.setAntiAlias(true);
mRectPaint.setColor(Color.parseColor("#66666666"));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//如果当前进度为-1,直接返回,不用绘制
if (index == -1)
return;
Sentence sentence = mDataList.get(index);
//绘制中间行的歌词,设置为高亮白色,大字体
mContentPaint.setColor(Color.WHITE);
mContentPaint.setTextSize(mBigTextSize);
canvas.drawText(sentence.getName(), mX/2, middleY, mContentPaint);
//当前为歌词不为空并且按下的情况下,绘制基线和进度
if(!isEmpty&&isTouch){
//获取中间行字体最高的位置
float baseLine = middleY-Math.abs(mContentPaint.ascent());
//绘制进度背景
canvas.drawRect(10.0f,baseLine-70,150.0f,baseLine,mRectPaint);
//绘制基线
canvas.drawLine(10.0f,baseLine,mX-10,baseLine,mLinePaint);
//设置进度字体大小
mContentPaint.setTextSize(mTextSize);
//绘制进度字体
canvas.drawText(String.valueOf(index),85,baseLine-35,mContentPaint);
}
//初始化isEmpty
isEmpty = false ;
//初始化歌词内容画笔
mContentPaint.setColor(Color.parseColor("#e5e2e2"));
mContentPaint.setTextSize(mTextSize);
//暂时保存中间线位置,来绘制中间线以上的行数字体
float tempY = middleY;
//绘制中间线以上的歌词
for (int i = index - 1; i >= 0; i--) {
tempY = tempY - DY;
if (tempY < 0) {
break;
}
Sentence preSentence = mDataList.get(i);
canvas.drawText(preSentence.getName(), mX/2, tempY, mContentPaint);
}
tempY = middleY;
//绘制中间线以下的歌词
for (int i = index + 1; i < mDataList.size(); i++) {
tempY = tempY + DY;
if (tempY > mY) {
break;
}
Sentence nexeSentence = mDataList.get(i);
canvas.drawText(nexeSentence.getName(), mX/2, tempY, mContentPaint);
}
//初始化isMoving,到这里表示滑动结束
isMoving = false ;
}
protected void onSizeChanged(int w, int h, int ow, int oh) {
super.onSizeChanged(w, h, ow, oh);
//获取view的宽和高
mX = w;
mY = h;
middleY = h * 0.5f;
}
public long updateIndex(int index) {
if (index == -1)
return -1;
this.index=index;
return index;
}
public List<Sentence> getDataList() {
return mDataList;
}
public void setDataList(List<Sentence> mDataList){
this.mDataList = mDataList ;
}
public void updateUI(){
new Thread(this).start();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action){
case MotionEvent.ACTION_DOWN:
isTouch =true;
mLastY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
//创建速度追踪器
initVelocityTrackerIfNotExists();
mVelocityTracker.addMovement(event);
mVelocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
//获取当前速度。默认为100
float velocity = mVelocityTracker.getYVelocity()==0?100:mVelocityTracker.getYVelocity();
long currentTime = System.currentTimeMillis();
//设置一个固定值和速度结合决定滑动更新的快慢
if(!isMoving&¤tTime-lastMoveTime>20000/Math.abs(velocity)){
isMoving = true ;
lastMoveTime = System.currentTimeMillis();
float currentY = event.getY();
float mMoveY = currentY - mLastY;
//向上滑动-1向下滑动+1
int newIndex = mMoveY>0?index - 1:index+1;
//循环滚动
newIndex=newIndex<0?mDataList.size()-1:newIndex>=mDataList.size()?0:newIndex;
updateIndex(newIndex);
invalidate();
mLastY = currentY;
}
break;
case MotionEvent.ACTION_UP:
isTouch = false ;
recycleVelocityTracker();
break;
}
return super.onTouchEvent(event);
}
@Override
public void run() {
//自动滚动刷新的时间间隔
long time = 1000;
//控制进度
int i=0;
while (true) {
//当前不在按下的情况下自动滚动
if(!isTouch){
//设置当前的进度值
long sleeptime = updateIndex(i);
//使用handle刷新ui
mHandler.post(mUpdateResults);
if (sleeptime == -1)
return;
try {
Thread.sleep(time);
i++;
//当到了最后一行的时候自动跳转到第一行
if(i==getDataList().size())
i=0;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Handler mHandler = new Handler();
Runnable mUpdateResults = new Runnable() {
public void run() {
invalidate();
}
};
//创建速度追踪器
private void initVelocityTrackerIfNotExists() {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
}
//释放
private void recycleVelocityTracker() {
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
}
}
public class VerticalScrollTextActivity extends Activity {
VerticalScrollTextView mSampleView;
String[] str = {"你在南方的艳阳里 大雪纷飞",
"我在北方的寒夜里 四季如春",
"如果天黑之前来的及",
"我要忘了你的眼睛",
"穷极一生 做不完一场梦",
"他不在和谁谈论相逢的孤岛",
"因为心里早已荒无人烟",
"他的心里在装不下一个家",
"做一个只对自己说谎的哑巴",
"他说你任何为人称道的美丽",
"不及他第一次遇见你",
"时光苟延残喘 无可奈何",
"如果所有土地连在一起",
"走上一生只为拥抱你",
"喝醉了他的梦 晚安",
"你在南方的艳阳里 大雪纷飞",
"我在北方的寒夜里 四季如春",
"如果天黑之前来的及",
"我要忘了你的眼睛",
"穷极一生 做不完一场梦",
"他不在和谁谈论相逢的孤岛",
"因为心里早已荒无人烟",
"他的心里在装不下一个家",
"做一个只对自己说谎的哑巴",
"他说你任何为人称道的美丽",
"不及他第一次遇见你",
"时光苟延残喘 无可奈何",
"如果所有土地连在一起",
"走上一生只为拥抱你",
"喝醉了他的梦 晚安"
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSampleView = (VerticalScrollTextView) findViewById(R.id.sampleView1);
List lst=new ArrayList<>();
for(int i=0;i<str.length;i++){
Sentence sen=new Sentence(i,str[i],i+1202034);
lst.add(i, sen);
}
mSampleView.setDataList(lst);
mSampleView.updateUI();
}
}
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <com.goach.lib.VerticalScrollTextView android:id="@+id/sampleView1" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg" /> </RelativeLayout>
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有