android 滾動字幕實現

來源:互聯網
上載者:User

最近項目需求做個迴圈滾動字幕功能,自己找了相關資料,根據自己的風格用兩種方法實現了該功能;

(備忘:本人只實現了滾動效果,對於文字的格式排版沒做處理,格式可能會亂,文字排版還在研究中)

具體如下;

方法一:橫向滾動字幕繼承TextView

package com.example.playpic;import com.example.playpic.AutoScrollTextView.SavedState;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Typeface;import android.graphics.Paint.FontMetrics;import android.os.Parcel;import android.os.Parcelable;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.util.Log;import android.view.WindowManager;import android.view.View.BaseSavedState;import android.widget.TextView;public class AutoText extends TextView {private int width,height;private Paint paintText;private float posx,posy;private float speed=0.0f;private String text="hello haha";private float textWidth=0;private float moveDistance=0.0f;private boolean isStarting=false;public AutoText(Context context) {super(context);}public AutoText(Context context, AttributeSet attrs) {super(context, attrs);}private void initView(){paintText=new Paint();paintText.setTextSize(50.0f);paintText.setColor(Color.BLACK);paintText.setTypeface(Typeface.DEFAULT_BOLD);paintText.setAntiAlias(true);text=getText().toString();textWidth=paintText.measureText(text);Log.e("msg", "textWidth= "+textWidth);this.speed=textWidth;moveDistance=textWidth*2+width;}public void initDisplayMetrics(WindowManager windowManager){   /* 取得螢幕解析度大小 */     DisplayMetrics dm=new DisplayMetrics();     windowManager.getDefaultDisplay().getMetrics(dm);     this.width=dm.widthPixels;     this.height=dm.heightPixels;          initView();     this.posx=width+textWidth;     FontMetrics fm = paintText.getFontMetrics();       float baseline = fm.descent - fm.ascent;     this.posy=height/2-baseline; }public void startScroll() {isStarting = true;invalidate();}public void stopScroll() {isStarting = false;invalidate();}@Overrideprotected void onDraw(Canvas canvas) {//super.onDraw(canvas);canvas.drawText(text, posx-speed, posy, paintText);if (!isStarting) {return;}speed += 2.0f;if (speed > moveDistance)speed = textWidth;invalidate();}}

布局檔案;

<?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="vertical" >        <com.example.playpic.AutoText        android:id="@+id/autoTxt"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:background="#ffffff"        android:textColor="#00ff00"        android:textSize="35sp" /></LinearLayout>

方法二:繼承sufaceView實現縱向文字滾動功能

package com.example.playpic;import java.util.ArrayList;import java.util.List;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Paint.FontMetrics;import android.graphics.Rect;import android.graphics.Typeface;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.WindowManager;public class ScrollText extends SurfaceView implements SurfaceHolder.Callback ,Runnable{private int width,height;private SurfaceHolder sfh;private Thread th;private boolean flag;private Paint backPaint,textPaint;/**文字開始出現的位置座標*/private float posx,posy;/**每行文本 當前移動文本距離以及文本的原始移動位置*/private Float[] step,stepBack;private String txtContent;/**儲存每行文本原始縱座標位置*/private Float[] tposy;/**儲存每行常值內容*/private String[] texts;public ScrollText(Context context) {super(context);initView();}public ScrollText(Context context, AttributeSet attrs) {super(context, attrs);initView();}private void initView(){sfh=this.getHolder();sfh.addCallback(this);this.setKeepScreenOn(true);this.setFocusable(true);//this.setFocusableInTouchMode(true);backPaint=new Paint();backPaint.setColor(Color.BLACK);textPaint=new Paint();textPaint.setTextSize(30.0f);textPaint.setColor(Color.BLUE);textPaint.setTypeface(Typeface.DEFAULT_BOLD);textPaint.setTextAlign(Paint.Align.LEFT);textPaint.setAntiAlias(true);}public void initDisplayMetrics(WindowManager windowManager){   /* 取得螢幕解析度大小 */        DisplayMetrics dm=new DisplayMetrics();        windowManager.getDefaultDisplay().getMetrics(dm);        this.width=dm.widthPixels;        this.height=dm.heightPixels;        this.posx=width/6;      /*  FontMetrics fm = textPaint.getFontMetrics();          float baseline = fm.descent - fm.ascent;*/        this.posy=height-100;        }public void setTxtContent(String txt){this.txtContent=txt;}@Overridepublic void surfaceCreated(SurfaceHolder holder) {this.flag=true;if(th==null||!th.isAlive()){th=new Thread(this);th.start();}}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {this.flag=false;}/** * 調用所有繪製方法 */private void drawAll(){Canvas canvas=null;try{canvas=sfh.lockCanvas();drawText(canvas, txtContent);}catch(Exception e){e.printStackTrace();}finally{if(canvas!=null){sfh.unlockCanvasAndPost(canvas);}}}private void drawText(Canvas canvas,String text){//clear screencanvas.drawRect(new Rect(0,0,getWidth(),getHeight()), backPaint);initDrawText(text);int len=tposy.length;// draw text contentfor(int n=0;n<len;n++){if(texts[n]==null)return;float ty=tposy[n]-step[n];canvas.drawText(texts[n], posx, ty, textPaint);step[n]+=5.0f;if(n==len-1&&ty<0){step=stepBack.clone();}/*if (ty<0){Log.e("msgreset", "back step");step[n] = stepBack[n].floatValue();}*/}postInvalidate();}/** * 在文字資訊繪製前對文本資訊進行文字分割,文字間距,文字位置計算處理 * @param text */private void initDrawText(String text){if(texts==null){texts=getTexts(text);}if(tposy==null){tposy=getTextLinePosy();}if(stepBack==null){stepBack=new Float[tposy.length];int i=0;float interval=0.0f;FontMetrics fm = textPaint.getFontMetrics();          float baseline = fm.descent - fm.ascent;while(i<stepBack.length){stepBack[i]=interval;interval-=baseline;i++;}}if(step==null){step=stepBack.clone();}}/** * 擷取分割後的文本資訊 * @param text * @return */private String[] getTexts(String text){List<String> totalList=new ArrayList<String>(10);String[] str=text.split("\n");int len=str.length;for(int i=0;i<len;i++){String[] ss=autoSplit(str[i], textPaint, getWidth()/3*2);for(String s:ss){totalList.add(s);}}if(texts==null)texts=(String[]) totalList.toArray(new String[0]);/*if(texts==null)        texts = autoSplit(text, textPaint, getWidth()/3*2); */return texts;}/** * 擷取每行文本的縱座標資訊 * @return */private Float[] getTextLinePosy(){ FontMetrics fm = textPaint.getFontMetrics();           float baseline = fm.descent - fm.ascent;            float y =  posy+baseline;  //由於系統基於字型的底部來繪製文本,所有需要加上字型的高度                            int len=texts.length;         Float[] groups=new Float[len];                           for(int i=0;i<len;i++) {                   groups[i]=y;                y =y+ baseline + fm.leading; //添加字型行間距              }              return groups;}/** * 自動分割文本 * @param content 需要分割的文本 * @param p  畫筆,用來根據字型測量文本的寬度 * @param width 最大的可顯示像素(一般為控制項的寬度) * @return 一個字串數組,儲存每行的文本 */private String[] autoSplit(String content, Paint p, float width) {          /* String[] lineTexts = new String[1000];     int lenStr=0;    int lineNum=0,w=0,start=0,end=1,n=0;        lenStr=content.length();    for(int j=0;j<lenStr;j++){    char ch=content.charAt(j);    String str_ch=String.valueOf(ch);    float[] ch_w=new float[1];    p.getTextWidths(str_ch, ch_w);        if(str_ch=="\n"){    lineNum++;    //start=j+1;    end=j+1;    w=0;        lineTexts[n++] = (String) content.subSequence(start, end);    start=end;    }else{    w+=(int)(Math.ceil(ch_w[0]));    if(w>width){    lineNum++;    //start=j;    end=j;    j--;    w=0;        lineTexts[n++] = (String) content.subSequence(start, end);    start=end;    }else{    if(j==(lenStr-1)){    lineNum++;    lineTexts[n++] = (String) content.subSequence(start, end);    break;    }    }    }    }    Log.e("msg", "lineNum= "+lineNum);*/       float textWidth = p.measureText(content);    if(textWidth <= width) {        return new String[]{content};    }        int length = content.length();    int start = 0, end = 1, i = 0;    int lines = (int) Math.ceil(textWidth / width); //計算行數    String[] lineTexts = new String[lines];        while(start < length) {    if(p.measureText(content, start, end) > width) { //文本寬度超出控制項寬度時            lineTexts[i++] = content.substring(start, end);//(String) content.subSequence(start, end);            start = end;        }        if(end == length) { //不足一行的文本            lineTexts[i] = content.substring(start, end);//(String) content.subSequence(start, end);            break;        }        end += 1;    }        return lineTexts;}@Overridepublic void run() {while(flag){drawAll();try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}}}}

package com.example.playpic;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.FileReader;import java.io.IOException;import java.io.InputStreamReader;import android.app.Activity;import android.os.Bundle;import android.os.Environment;import android.text.method.ScrollingMovementMethod;import android.util.Log;import android.widget.TextView;import com.sample.fun.R;public class ScrollTextActivity extends Activity{String str="";String str11="促進青年教師全面發展,\n引導廣大高校青年教師為實現中華民族偉大複興的中國夢貢獻力" +"\n"+"促進青年教師全面發展,\n引導廣大高校青年教師為實現中華民族偉大複興的中國夢貢獻力"+"\n"+"  djsdnhkshdfjks \n\r\t ";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);scroll3();}void scroll2(){ScrollText v=new ScrollText(getApplicationContext());setContentView(v);v.setTxtContent(str11);v.initDisplayMetrics(getWindowManager());}void scroll3(){setContentView(R.layout.scrollview1);AutoText auto=(AutoText)findViewById(R.id.autoTxt);auto.setText(str11);auto.initDisplayMetrics(getWindowManager());auto.startScroll();}}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.