Android 文本滚动效果的几种实现方式(二)

这一篇文章介绍了通过自定义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

    }

你可能感兴趣的:(安卓)