Androidテキストスクロール効果のいくつかの実現方法(二)

14262 ワード

この記事では,surfaceviewメソッドをカスタマイズすることで通知スクロール効果を実現する方法を紹介した.この方法の利点は、メインスレッドの影響を受けずにAndroidのすべてのペイントインタフェース操作がメインスレッドのみで許可されていることを知っているはずですが、surfaceviewはサブスレッドでペイントできます.メインスレッドの描画作業量が大きいカートン現象を避けるためにsurfaceviewでスクロールを実現する考えがある.
カスタム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

    }