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

更多相关文章

  1. android源码解析(十七)-->Activity布局加载流程
  2. Android(安卓)Hook Activity 的几种姿势
  3. 十分钟学会kotlin实现Android(安卓)MVP模式开发
  4. Android(安卓)Fragment学习笔记(二)----Fragment界面添加和管理
  5. 线程方法Android:异步调用详解
  6. Android查看数据库方法及工具
  7. [转]android解决apk编译方法数超过64k的问题
  8. Android(安卓)Handler 作用以及使用
  9. Android(安卓)四大组件 ————Service(生命周期)

随机推荐

  1. kernel 及 ramdisk 移植
  2. android sdcard文件存储 + 媒体库更新方
  3. android 图表引擎AChartEngine(柱状图)
  4. Android(安卓)显示大图片
  5. Android(安卓)SDcard目录文件操作
  6. 【Android】使用ConnectivityManager与Ne
  7. Android动态设置控件高度
  8. Android(安卓)Studio 打包方式
  9. [转]Android文字跑马灯控件
  10. 各种奇妙的hack