Androidテキストスクロール効果のいくつかの実現方法(二)
この記事では,surfaceviewメソッドをカスタマイズすることで通知スクロール効果を実現する方法を紹介した.この方法の利点は、メインスレッドの影響を受けずにAndroidのすべてのペイントインタフェース操作がメインスレッドのみで許可されていることを知っているはずですが、surfaceviewはサブスレッドでペイントできます.メインスレッドの描画作業量が大きいカートン現象を避けるためにsurfaceviewでスクロールを実現する考えがある.
カスタムsurfaceviewによるスクロール効果
この方法は比較的簡単で,surfaceviewをカスタマイズし,SurfaceHolderによってキャンバスを取得し,サブスレッドによって文字を絶えず描画することである.直接コードをつける.
カスタムsurfaceviewによるスクロール効果
この方法は比較的簡単で,surfaceviewをカスタマイズし,SurfaceHolderによってキャンバスを取得し,サブスレッドによって文字を絶えず描画することである.直接コードをつける.
public class PlayNotifyInnerWindow extends SurfaceView implements SurfaceHolder.Callback {
/** * */
public static Typeface addTypeface;
public static Typeface berTypeface;
public static Typeface daiTypeface;
public static Typeface dejTypeface;
public static Typeface droTypeface;
SurfaceHolder holder;
public PlayNotifyInnerWindow(Context context, int width, int height) {
super(context);
mContext = context;
// TODO Auto-generated constructor stub
rate = (((float) 1920) / ((float) 1080))
/ (((float) height) / ((float) width));
this.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
holder = getHolder();
holder.addCallback(this); // Surface
}
public void setPath(String path) {
this.setVisibility(View.VISIBLE);
paint = new Paint();
isStop = true;
i = 0;
currentScrollX = 0;
if (timer != null)
timer.cancel();
LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
try {
filePath = path;
manager = getContext().getAssets();
String fileContent = readFile(path);// ,json
JSONObject object = new JSONObject(fileContent);
content = object.getString("content") + " ";
left = object.getString("left");
right = object.getString("right");
mspeed = object.getString("speed");
bottom = object.getString("bottom");
cicrle = object.getString("cicrle");
isTran = object.getBoolean("isTransparent");
stopTime = object.getInt("stoptime");
isB = object.getBoolean("isBold");
isI = object.getBoolean("isItalic");
isU = object.getBoolean("isUnderline");
bgColor = object.getInt("bgColor");
bgZiti = object.getInt("bgFont");
zihao = object.getString("fontsize");
ziti = object.getString("font");
effect = object.getInt("effect");
if (!"".equals(left)) {
// layoutParams.leftMargin=Integer.parseInt(left);
layoutParams.setMargins(Integer.parseInt(left), 0, 0, 0);
}
if (!"".equals(right)) {
layoutParams.setMargins(0, 0, Integer.parseInt(right), 0);
}
if (!"".equals(left) && !"".equals(right)) {
layoutParams.setMargins(Integer.parseInt(left), 0,
Integer.parseInt(right), 0);
}
if (!"".equals(bottom)) {
layoutParams.bottomMargin = Integer.parseInt(bottom);
} else {
layoutParams.bottomMargin = 0;
}
msp = new SpannableString(content);
if (isB == true) {
paint.setFakeBoldText(true);
} else {
paint.setFakeBoldText(false);
}
if (isI == true) {
paint.setTextSkewX(-0.5f);
} else {
paint.setTextSkewX(0f);
}
if (isU == true) {
paint.setUnderlineText(true);
} else {
paint.setUnderlineText(false);
}
if (mspeed != null && !"".equals(mspeed)) {
speed = Integer.parseInt(mspeed);
} else {
speed = 5;
}
if (cicrle != null && !"".equals(cicrle)) {
cicle = Integer.parseInt(cicrle);
} else {
cicle = 10000;
}
if (bgZiti != 0) {
//
msp.setSpan(new ForegroundColorSpan(bgZiti), 0,
content.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //
} else {
msp.setSpan(new StyleSpan(android.graphics.Typeface.NORMAL), 0,
content.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //
}
if (!"".equals(zihao)) {
fontSize = px2sp(mContext,
sp2px(mContext, Integer.parseInt(zihao)) * rate);
paint.setTextSize(fontSize);
} else {
fontSize = px2sp(mContext, sp2px(mContext, 24) * rate);
paint.setTextSize(fontSize);
}
if (!"".equals(ziti)) {
Typeface tf;
tf = choiceTypeface(ziti);// Typeface
paint.setTypeface(tf);//
} else {
msp.setSpan(new TypefaceSpan("monospace"), 0, content.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
FontEffects mFontEffects = new FontEffects(paint, null);
mFontEffects.setFontEffects(effect);
i = 0;
this.setVisibility(View.VISIBLE);
isStop = false;
new Thread(new ScrollRunnable()).start();
this.setLayoutParams(layoutParams);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//
public void startScroll() {
Canvas c = null;
while (!isStop) {
currentScrollX += 10;//
synchronized (holder) {
paint.setColor(bgZiti);
c = holder.lockCanvas();
c.drawColor(bgColor); // , 。
c.drawText(content, currentScrollX, 100, paint);// ,
holder.unlockCanvasAndPost(c);
}
if (currentScrollX >= this.getWidth()) {
currentScrollX = 0;
// return;
if (i >= cicle) {
isStop = true;
} else {
i++;
}
}
}
}
class ScrollRunnable implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
startScroll();
}
}
public void stopScroll() {
isStop = true;
this.setVisibility(View.GONE);
// scrollTo(0, 0);
// File file = new File(filePath);
// if (file.exists()) {
// file.delete();
// }
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
setPath("/mnt/external_sd/notify/notify_android.xml");
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
}