最近项目需求做个循环滚动字幕功能,自己找了相关资料,分别实现了垂直滚动和水平滚动方式,根据自己的风格用两种方法实现了该功能;
2015-12-15更新:以前实现效果并不理想(文字的格式排版,自定义颜色,大小字号等TextView原有属性都不能很好兼容实现),现改为ScrollView+TextView处理方式,
这个支持所有TextView属性,还支持速度,垂直滚动textview加ScrollView实现,水平滚动textview加HorizontalScrollView实现
具体实现:
public class TextPlayer extends BasePlayer {
private TextViewAttr attrs = null;
private View vroot = null;
private TextView txtView = null;
private Animation mMoveTextOut = null;
// private Animation mMoveTextIn = null;
private Animation mMoveTextUp = null;
// private Animation mMoveTextDown=null;
private boolean mMarqueeNeeded = false;
private static final String TAG = "TextMarqueeView112";
private static final int TEXTVIEW_VIRTUAL_WIDTH = 990000;
private static final int TEXTVIEW_HEIGHT = 990000;
/**
* Control the speed. The lower this value, the faster it will scroll.
*/
public static final int SPEED_NORMAL = 20;
public static final int SPEED_FAST = 12;
public static final int SPEED_LOW = 30;
/**
* Control the pause between the animations. Also, after starting this activity.
*/
private static final int DEFAULT_ANIMATION_PAUSE = 1000;
private int mSpeedHorizontal = SPEED_NORMAL;
private int mSpeedVertical = SPEED_NORMAL * 2;
private int mAnimationPause = DEFAULT_ANIMATION_PAUSE;
private boolean mAutoStart = true;
private Interpolator mInterpolator = new LinearInterpolator();
private boolean mCancelled = false;
private Runnable mAnimationStartRunnable;
private boolean mStarted = false;
private int currentScrollMode = Constance.SCROLL_VERTICAL_UP;
private boolean mOnLayoutEnd = false;
public TextPlayer(Context ctx ,TextViewAttr attr){
super(ctx);
this.attrs = attr;
intView();
}
@Override
public View getView() {
return vroot;
}
public void setHorizontalScrollView(View vroot){
this.vroot = vroot;
txtView = (TextView) vroot.findViewById(R.id.textViewHorizontal);
this.currentScrollMode = Constance.SCROLL_HORIZONTAL_LEFT;
}
public void setVerticalScrollView(View vroot){
this.vroot = vroot;
txtView = (TextView) vroot.findViewById(R.id.textViewVertical);
this.currentScrollMode = Constance.SCROLL_VERTICAL_UP;
}
private void intView() {
LayoutInflater inflater = (LayoutInflater) mCtx.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
if(null == vroot) {
if (attrs.getScrollDirection() == Constance.SCROLL_HORIZONTAL_LEFT) {
vroot = inflater.inflate(R.layout.text_horizontal_scroll, null);
txtView = (TextView) vroot.findViewById(R.id.textViewHorizontal);
this.currentScrollMode = Constance.SCROLL_HORIZONTAL_LEFT;
} else if (attrs.getScrollDirection() == Constance.SCROLL_VERTICAL_UP) {
vroot = inflater.inflate(R.layout.text_vertical_scroll, null);
txtView = (TextView) vroot.findViewById(R.id.textViewVertical);
this.currentScrollMode = Constance.SCROLL_VERTICAL_UP;
}
}
if (!TextUtils.isEmpty(attrs.getTextColor())) {
txtView.setTextColor(Color.parseColor(attrs.getTextColor()));
}
if (!TextUtils.isEmpty(attrs.getTextFontSize())) {
txtView.setTextSize(Float.parseFloat(attrs.getTextFontSize()));
}
}
private File[] res_files;
private int elementsCount;
@Override
public void setData(File resourceDir) {
if(null!=resourceDir && resourceDir.exists()){
// File[] eles = resourceDir.listFiles();
File[] elements = resourceDir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String filename) {
return filename.endsWith(".txt");
}
});
if(null!=elements && elements.length>0){
res_files = elements;
elementsCount = elements.length;
}
}
}
public void setTextContent(String content){
if(TextUtils.isEmpty(content)) return;
vroot.post(mPlayRun);
txtView.setText(content);
// Message m = Message.obtain();
// m.what = MSG_CHANGETEXT;
// m.obj = content;
// mHandler.sendMessageDelayed(m,2000);
}
// public void setTextAlign(int align){
// int gravity = Gravity.LEFT;
// switch (align){
// case Gravity.CENTER_HORIZONTAL:
// gravity = Gravity.CENTER_HORIZONTAL;
// break;
// case Gravity.CENTER_VERTICAL:
// gravity = Gravity.CENTER_VERTICAL;
// break;
// case Gravity.CENTER:
// gravity = Gravity.CENTER;
// break;
// }
// txtView.setGravity(gravity);
// }
Runnable mPlayRun = new Runnable() {
@Override
public void run() {
executeScroll();
}
};
private void executeScroll(){
if (this.currentScrollMode == Constance.SCROLL_HORIZONTAL_LEFT)
initHorizontalView();
else
initVerticalView();
prepareAnimation();
if (mAutoStart) {
String text = txtView.getText().toString();
if (TextUtils.isEmpty(text))
return;
startMarquee();
}
this.mOnLayoutEnd = true;
}
private Handler mHandler = new RefHandler(this);
private final static int MSG_CHANGETEXT = 11;
private final static int MSG_READTEXT = 12;
private static class RefHandler extends Handler{
Reference<TextPlayer> mTarget = null;
RefHandler(TextPlayer player) {
mTarget = new WeakReference<>(player);
}
@Override
public void handleMessage(Message msg) {
TextPlayer target = mTarget.get();
if(null == target) return;
switch (msg.what){
case MSG_CHANGETEXT:
target.setTextContent((String) msg.obj);
break;
case MSG_READTEXT:
WorkerThreadPool.getInstance().executeTask(target.readFileTask);
break;
}
}
}
private int currentIndex =0;
Runnable readFileTask = new Runnable() {
@Override
public void run() {
String content = FileUtils.readSDFile(res_files[currentIndex]);
Message m = Message.obtain(mHandler);
m.what = MSG_CHANGETEXT;
m.obj = content;
m.sendToTarget();
if(++currentIndex >= elementsCount){
currentIndex = 0;
}
}
};
@Override
public void startPlay() {
if(0== elementsCount) return;
mHandler.sendEmptyMessage(MSG_READTEXT);
vroot.post(mPlayRun);
}
@Override
public void pausePlay() {
}
@Override
public void continuePlay() {
}
@Override
public void stopPlay() {
mHandler.removeCallbacksAndMessages(null);
}
@Override
public void completePlay() {
}
@Override
public void destroyPlay() {
mHandler.removeCallbacksAndMessages(null);
}
public void startMarquee() { //Log.d(TAG, "startMarquee()");
if (this.currentScrollMode == Constance.SCROLL_HORIZONTAL_LEFT) {
if (mMarqueeNeeded && mMoveTextOut != null)
startHorizontalAnimation();
} else if (this.currentScrollMode == Constance.SCROLL_VERTICAL_UP) {
if (mMarqueeNeeded && mMoveTextUp != null)
startVerticalAnimation();
}
mCancelled = false;
mStarted = true;
}
private void startHorizontalAnimation() {
mAnimationStartRunnable = new Runnable() {
@Override
public void run() {
Log.d(TAG, "startHorizontalAnimation");
txtView.startAnimation(mMoveTextOut);
}
};
vroot.postDelayed(mAnimationStartRunnable, mAnimationPause);
}
private void startVerticalAnimation() {
mAnimationStartRunnable = new Runnable() {
@Override
public void run() {
Log.d(TAG, "startVerticalAnimation");
txtView.startAnimation(mMoveTextUp);
}
};
vroot.postDelayed(mAnimationStartRunnable, mAnimationPause);
}
/**
* Disables the animations.
*/
public void reset() {
mCancelled = true;
if (mAnimationStartRunnable != null) {
vroot.removeCallbacks(mAnimationStartRunnable);
}
txtView.clearAnimation();
mStarted = false;
if (mMoveTextOut != null)
mMoveTextOut.reset();
if (mMoveTextUp != null)
mMoveTextUp.reset();
// mAnimationStartRunnable=null;
vroot.invalidate();
}
private void prepareAnimation() {
String text = txtView.getText().toString();
if (TextUtils.isEmpty(text))
return;
Paint mPaint = txtView.getPaint();
mPaint.setTextSize(txtView.getTextSize());
mPaint.setTypeface(txtView.getTypeface());
Rect mBounds = new Rect();
mPaint.getTextBounds(text, 0, text.length(), mBounds);
float textWidth = mBounds.width();
float textHeight = mBounds.height();
// Log.d(TAG, "Rect calucate w h="+textWidth+" :"+textHeight);
// Log.d(TAG, "measuredWidth : " + vroot.getMeasuredWidth()+" measuredHeight :"+vroot.getMeasuredHeight());
float padTextWidth = mPaint.measureText(text, 0, 1);
/* float mTextWidth = mPaint.measureText(mTextField.getText().toString());
Log.d(TAG, "mTextWidth : " + mTextWidth);*/
if (currentScrollMode == Constance.SCROLL_HORIZONTAL_LEFT) {
mMarqueeNeeded = textWidth > vroot.getMeasuredWidth();
//垂直居中坐标
int centerPosY = Math.round(vroot.getMeasuredHeight() / 2 - textHeight / 2);
if (false == mMarqueeNeeded || false == attrs.IsScrollMode()) {
if (attrs.getTextGravity() == Gravity.RIGHT)
txtView.setPadding(Math.round(vroot.getMeasuredWidth() - textWidth - padTextWidth), centerPosY, 0, 0);
else if (attrs.getTextGravity() == Gravity.CENTER)
txtView.setPadding(Math.round(vroot.getMeasuredWidth() / 2 - textWidth / 2), centerPosY, 0, 0);
return;
}
int duration = (int) Math.ceil(textWidth * mSpeedHorizontal);
initHorizontalAnim(vroot.getMeasuredWidth() - padTextWidth,
-(textWidth + padTextWidth), centerPosY, duration);
// Log.d(TAG, "get w h left top="+vroot.getWidth()+" "+vroot.getHeight()+" "+vroot.getLeft()+" "+vroot.getTop());
// initHorizontalAnim(getLeft()+getMeasuredWidth()/2,getLeft(),8*1000);
} else if (currentScrollMode == Constance.SCROLL_VERTICAL_UP) {
// int lines=txtView.getLineCount();
int lines = (int) Math.ceil(textWidth / vroot.getMeasuredWidth());
mMarqueeNeeded = lines * textHeight > vroot.getMeasuredHeight();//mTextField.getHeight();
if (false == mMarqueeNeeded || false == attrs.IsScrollMode()) {
return;
}
// Log.d(TAG, "verticalView line count="+lines);
// Log.d(TAG, " getView w h"+txtView.getWidth()+", "+txtView.getHeight());
//滚动完最后一行
lines++;
float moveHeight = lines * textHeight;
int duration = (int) Math.ceil(moveHeight * mSpeedVertical);
// Log.d(TAG, "moveDistance="+moveHeight);
initVerticalAnim(vroot.getMeasuredHeight() + textHeight * 2,
-(moveHeight), duration);// - textHeight * 3
}
}
private void initHorizontalAnim(float fromX, float toX, float posY, int duration) {//,float locationY
// Log.d(TAG, "initHorizontalAnim fromx="+fromX+" toX="+toX);
mMoveTextOut = new TranslateAnimation(fromX, toX, posY, posY);
mMoveTextOut.setDuration(duration);
mMoveTextOut.setInterpolator(mInterpolator);
mMoveTextOut.setFillAfter(true);
mMoveTextOut.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) { // Log.d(TAG, "mMoveTextOut_onAnimationStart");
expandHorizontalTextView();
}
@Override
public void onAnimationEnd(Animation animation) { //Log.d(TAG, "mMoveTextOut_animEnd");
cutHorizontalTextView();
completePlay();
if (mCancelled) {
return;
}
startHorizontalAnimation();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
private void initVerticalAnim(float fromY, float toY, int duration) {
mMoveTextUp = new TranslateAnimation(0, 0, fromY, toY);
mMoveTextUp.setDuration(duration);
mMoveTextUp.setInterpolator(mInterpolator);
mMoveTextUp.setFillAfter(true);
mMoveTextUp.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {// Log.d(TAG, "mMoveTextUp_onAnimationStart");
expandVerticalTextView();
}
@Override
public void onAnimationEnd(Animation animation) { //Log.d(TAG, "mMoveTextUp_AnimEnd");
cutVerticalTextView();
completePlay();
if (mCancelled) {
return;
}
startVerticalAnimation();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
private void initHorizontalView() {
txtView.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) { //Log.d(TAG, "afterTextChanged");
if (!mOnLayoutEnd)
return;
final boolean continueAnimation = mStarted;
reset();
prepareAnimation();
cutHorizontalTextView();
/* if (continueAnimation) { Log.d(TAG, "TextChange Restart play");
startMarquee();
}*/
vroot.post(new Runnable() {
@Override
public void run() {
if (continueAnimation) { //Log.d(TAG, "TextChange Restart play");
startMarquee();
}
}
});
}
});
}
private void expandHorizontalTextView() {
ViewGroup.LayoutParams lp = txtView.getLayoutParams();
lp.width = TEXTVIEW_VIRTUAL_WIDTH;
txtView.setLayoutParams(lp);
}
private void cutHorizontalTextView() {
if (txtView.getWidth() != vroot.getMeasuredWidth()) {
ViewGroup.LayoutParams lp = txtView.getLayoutParams();
lp.width = vroot.getMeasuredWidth();
txtView.setLayoutParams(lp);
}
}
private void initVerticalView() {
txtView.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) { //Log.d(TAG, "afterTextChanged");
if (!mOnLayoutEnd)
return;
final boolean continueAnimation = mStarted;
reset();
prepareAnimation();
cutVerticalTextView();
/* if (continueAnimation) { Log.d(TAG, "TextChange Restart play");
startMarquee();
}*/
vroot.post(new Runnable() {
@Override
public void run() {
if (continueAnimation) { //Log.d(TAG, "TextChange Restart play");
startMarquee();
}
}
});
}
});
}
private void expandVerticalTextView() { //Log.d(TAG, "expandVerticalTextView");
ViewGroup.LayoutParams lp = txtView.getLayoutParams();
lp.height = TEXTVIEW_HEIGHT;
txtView.setLayoutParams(lp);
}
private void cutVerticalTextView() {// Log.d(TAG, "cutVerticalTextView");
if (txtView.getHeight() != vroot.getMeasuredHeight()) {
ViewGroup.LayoutParams lp = txtView.getLayoutParams();
lp.height = vroot.getMeasuredHeight();
txtView.setLayoutParams(lp);
}
}
}
控制播放器实现
public abstract class BasePlayer implements IPlayer {
public abstract View getView();
public abstract void setData(File resourceDir);
protected Context mCtx;
private PlayerAttr mPlayerAttr;
public BasePlayer(Context ctx){
this.mCtx = ctx;
}
public void setPlayerAttr(PlayerAttr attr){
this.mPlayerAttr = attr;
}
public Rect getRegion() {
return mPlayerAttr.region;
}
@Override
public void startPlay() {
}
@Override
public void pausePlay() {
}
@Override
public void continuePlay() {
}
@Override
public void stopPlay() {
}
@Override
public void completePlay() {
}
@Override
public void destroyPlay() {
}
}
public interface IPlayer {
public void startPlay();
public void pausePlay();
public void continuePlay();
public void stopPlay();
public void completePlay();
public void destroyPlay();
}
文本属性相关:
public class TextViewAttr {
// 5.backgroundOpacity: 透明属性,backgroundOpacity="0%"; 此时,不允许出现backgroundColor属性
// 6.backgroundColor: 背景色, backgroundColor="色彩值"; 此时,不允许出现backgroundOpacity属性
// 7.textAlign: 文本对齐方式,支持(start|left|inherit,end|right,center)
// 8.textMode:滚动模式,支持动态(crawl),静态(inherit)
// 9.textFontSize:文本字体大小,平台控制范围 1-64号字 【SIGMA平台受限制】
// 10.textFontStyle:文本字体,参加字体名称与字库的对应表的邮件及相应文档,其中有描述平台支持的几种字体类型
// {SimHei,SimSun,NSimSun,FangSong,KaiTi,Microsoft YaHe,WenQuanYi Micro Hei Mono(wqy-microhei.ttc)}
// 11.textColor:字体颜色;
// 12.textWritingMode :动态文本的滚动模式,支持从右到左滚动(lr),从左到右滚动(rl),从下到上滚动(tb-lr),从上到下滚动(tb-rl);
// 13.textFontWeight:字体加粗模式,支持(light,normal,bold,black),与字号有关,字号超过64,貌似加粗无效 【SIGMA平台受限制】
private String backgroundOpacity;
private String backgroundColor;
private String textAlign;
private String textMode;
private String textFontSize;
private String textFontStyle;
private String textColor;
private String textWritingMode;
private String textFontWeight;
private String clkdisplayMode;
public static final String SROLL_DYNIMICMODEL="crawl";
public static final String SROLL_NOTMOVE="inherit";
public TextViewAttr(){
}
public TextViewAttr(NamedNodeMap attrs){
backgroundOpacity = getAttribute(attrs,"backgroundOpacity");
backgroundColor=getAttribute(attrs,"backgroundColor");
textAlign = getAttribute(attrs,"textAlign");
textMode = getAttribute(attrs,"textMode");
textFontSize = getAttribute(attrs,"textFontSize");
textFontStyle = getAttribute(attrs,"textFontStyle");
textColor = getAttribute(attrs,"textColor");
textWritingMode = getAttribute(attrs,"textWritingMode");
textFontWeight = getAttribute(attrs,"textFontWeight");
clkdisplayMode = getAttribute(attrs,"clkdisplayMode");
}
private int scrollMode = Constance.SCROLL_VERTICAL_UP;
public void setHorizontalScrollDirection(){
scrollMode = Constance.SCROLL_HORIZONTAL_LEFT;
}
public int getScrollDirection(){
// scrollMode = Constance.SCROLL_VERTICAL_UP;
/*if("lr".equals(textWritingMode)){
mode = AutoScrollTextView.SCROLL_LEFT_TO_RIGHT;
}else if("rl".equals(textWritingMode)){
mode = MarqueeText.SCROLL_RIGHT_TO_LEFT;
}else if("tb-lr".equals(textWritingMode)){
mode = MarqueeText.SCROLL_BOTTOM_TO_TOP;
}else if("tb-rl".equals(textWritingMode)){
mode = MarqueeText.SCROLL_TOP_TO_BOTTOM;
}*/
if("lr".equals(textWritingMode)||"rl".equals(textWritingMode)){
scrollMode = Constance.SCROLL_HORIZONTAL_LEFT;
}else if("tb-lr".equals(textWritingMode)||"tb-rl".equals(textWritingMode)){
scrollMode = Constance.SCROLL_VERTICAL_UP;
}
return scrollMode;
}
public String getAttribute(NamedNodeMap attrs,String name) {
Attr attrNode = (Attr)attrs.getNamedItem(name);
String attrValue = "";
if (attrNode != null) {
attrValue = attrNode.getValue();
}
return attrValue;
}
public String getBackgroundOpacity() {
return backgroundOpacity;
}
public boolean IsScrollMode() {
boolean isScroll=true;
//是否为静止
if(false==TextUtils.isEmpty(textMode)&&true==textMode.equals("inherit")){
isScroll=false;
}
return isScroll;
}
//文本字体,参加字体名称与字库的对应表
public String getTextFontStyle() {
return textFontStyle;
}
public int getDisplayMode(){
int mode = 0;
try{
mode = Integer.parseInt(clkdisplayMode);
}catch(Exception e){
}
return mode;
}
public Align getTextAlign(){
Align a = Align.LEFT;
if(!TextUtils.isEmpty(textAlign)){
if(textAlign.contains("right")){
a = Align.RIGHT;
}else if(textAlign.contains("center")){
a = Align.CENTER;
}
}
return a;
}
/*
public String getStringTextAlign(){
return textAlign;
}*/
public int getTextGravity(){
/*if(!TextUtils.isEmpty(textAlign)){
String[] gravitys = textAlign.split("\\|");
int gravityInit = Gravity.NO_GRAVITY;
for(int i = 0; i < gravitys.length; i++){
String gravity = gravitys[i];
if("left".equals(gravity)){
gravityInit = Gravity.LEFT | gravityInit;
}else if("right".equals(gravity)){
gravityInit = Gravity.RIGHT | gravityInit;
}else if("top".equals(gravity)){
gravityInit = Gravity.TOP | gravityInit;
}else if("start".equals(gravity)){
gravityInit = Gravity.TOP | gravityInit;
}else if("end".equals(gravity)){
gravityInit = Gravity.BOTTOM | gravityInit;
}else if("center".equals(gravity)){
gravityInit = Gravity.CENTER | gravityInit;
}
}
return gravityInit;
}else{
return Gravity.CENTER;
}*/
int textGravity=Gravity.CENTER_HORIZONTAL;
if(!TextUtils.isEmpty(textAlign)){
/*if("start".equals(textAlign))
textGravity=Gravity.TOP;
else if("end".equals(textAlign))
textGravity=Gravity.BOTTOM;
else*/ if("left".equals(textAlign))
textGravity=Gravity.LEFT;
else if("right".equals(textAlign))
textGravity=Gravity.RIGHT;
else if("center".equals(textAlign))
textGravity=Gravity.CENTER;
}
return textGravity;
}
//字体加粗模式
public int getTextFontWeight(){
int tf = Typeface.NORMAL;
if(!TextUtils.isEmpty(textFontWeight)){
if(textFontWeight.contains("bold")){
tf = Typeface.BOLD;
}else if(textFontWeight.contains("italic")){
tf = Typeface.ITALIC;
}
}
return tf;
}
/*
public boolean isBold(){
boolean bold = false;
if(!TextUtils.isEmpty(textFontWeight) && textFontWeight.contains("bold")){
bold = true;
}
return bold;
}
*/
public String getBackgroundColor(){
if(TextUtils.isEmpty(backgroundColor)){
return "";
}else{
return backgroundColor;
}
}
public String getTextColor(){
if(TextUtils.isEmpty(textColor)){
return "#000000";
}else{
return textColor;
}
}
public String getTextFontSize(){
if(TextUtils.isEmpty(textFontSize)){
return "20";
}else{
return textFontSize;
}
}
}
横向滚动布局:text_horizontal_scroll.xml
<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="1000dip"
android:layout_height="match_parent"
android:scrollbars="none">
<TextView
android:id="@+id/textViewHorizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textColor="@android:color/white"
android:textSize="13sp"/>
</HorizontalScrollView>
垂直滚动布局:text_vertical_scroll.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="1000dip"
android:scrollbars="none">
<!--
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"> android:maxHeight="800000dp"-->
<TextView
android:id="@+id/textViewVertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:gravity="center_vertical"
android:textColor="@android:color/white"
android:lineSpacingMultiplier="1.2"
android:textSize="16sp"/>
</ScrollView>
使用:
TextPlayer txtPlayerVer = new TextPlayer(this,new TextViewAttr());
txtPlayerVer.setVerticalScrollView(layout);
txtPlayerVer.setTextContent(getString(R.string.notice_test));
layoutContainer.addView(txtPlayerVer.getView());
txtPlayerVer.startPlay();