Giter VIP home page Giter VIP logo

marqueeview's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

marqueeview's Issues

关于循环滚动

考虑一下用两个画笔,一个画笔开始滚动绘制的时候另个画笔的xLocation设置成控件宽度,并禁止绘制;当第一个画笔绘制到需要的位置,启动第二个画笔绘制,然后根据需要重置第一个画笔并停止绘制,以此循环。这个方法还没有验证。

希望可以去除onDraw中的日志打印

E/MarqueeView: onDraw: ---5802--------1165486.0------200
E/MarqueeView: onDraw: ---5802--------1165492.0------200
E/MarqueeView: onDraw: ---5802--------1165494.0------200

辛苦作者大大

建议不要使用该库。。

有bug。在当前这个页面启动滚动后,然后跳转下一个页面。当关闭下一个页面时,OnDestroy将出现延迟调用的问题。

改了一下内存问题,增加了文字阴影功能,单纯实现REPET_CONTINUOUS的方式

public class MarqueeView extends View {

private String string;//最终绘制的文本
private float speed = 1;//移动速度
private int textColor = Color.BLACK;//文字颜色,默认黑色
private float textSize = 12;//文字颜色,默认黑色
private float startLocationDistance = 0.5f;//开始的位置选取,百分比来的,距离左边,0~1,0代表不间距,1的话代表,从右面,1/2代表中间。
private int itemDistance = 4; //默认item间隔4个空格

private boolean hasShadow = false;
private float shadowDy = 0f;
private float shadowDx = 0f;
private float shadowRadius = 0f;
private int shadowColor = Color.BLACK;

private boolean isResetLocation = true;//默认为true
private float xLocation = 0;//文本的x坐标
private int contentWidth;//内容的宽度

private volatile boolean isRoll = false;//是否继续滚动

private TextPaint paint;//画笔
private Rect rect;

private boolean resetInit = true;

private String content = "";

private float textHeight;


private Handler mHandler = new Handler(new Handler.Callback() { //替换Thread,采用handler,推荐使用 WeakHandler,这里就不更换了
    @Override
    public boolean handleMessage(Message msg) {
        if (msg.what == 1) {
            if (isRoll && !TextUtils.isEmpty(content)) {
                xLocation = xLocation - speed;
                postInvalidate();//每隔10毫秒重绘视图
                mHandler.sendEmptyMessageDelayed(1, 30);
            }
            return true;
        }
        return false;

    }
});


public MarqueeView(Context context) {
    this(context, null);
}

public MarqueeView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public MarqueeView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    initAttrs(attrs);
    initPaint();
}

@SuppressLint("RestrictedApi")
private void initAttrs(AttributeSet attrs) {
    TintTypedArray tta = TintTypedArray.obtainStyledAttributes(getContext(), attrs,
            R.styleable.MarqueeView);

    textColor = tta.getColor(R.styleable.MarqueeView_marqueeview_text_color, textColor);
    isResetLocation = tta.getBoolean(R.styleable.MarqueeView_marqueeview_is_resetLocation, isResetLocation);
    speed = tta.getFloat(R.styleable.MarqueeView_marqueeview_text_speed, speed);
    textSize = tta.getFloat(R.styleable.MarqueeView_marqueeview_text_size, textSize);
    startLocationDistance = tta.getFloat(R.styleable.MarqueeView_marqueeview_text_startlocationdistance, startLocationDistance);
    itemDistance = tta.getInt(R.styleable.MarqueeView_marqueeview_text_distance, itemDistance);
    hasShadow = tta.getBoolean(R.styleable.MarqueeView_marqueeview_text_shadow, false);
    shadowDx = tta.getFloat(R.styleable.MarqueeView_marqueeview_text_shadow_dx, 0);
    shadowDy = tta.getFloat(R.styleable.MarqueeView_marqueeview_text_shadow_dy, 0);
    shadowRadius = tta.getFloat(R.styleable.MarqueeView_marqueeview_text_shadow_radius, 0);
    shadowColor = tta.getColor(R.styleable.MarqueeView_marqueeview_text_shadow_color, shadowColor);
    tta.recycle();
}


/**
 * 刻字机修改
 */
private void initPaint() {
    rect = new Rect();
    paint = new TextPaint(Paint.ANTI_ALIAS_FLAG);//初始化文本画笔
    paint.setStyle(Paint.Style.FILL);
    paint.setColor(textColor);//文字颜色值,可以不设定
    paint.setTextSize(PixelUtil.sp2px(textSize));//文字大小
    if (hasShadow) {
        paint.setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor);
    }
}


@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if (resetInit) {
        if (startLocationDistance < 0) {
            startLocationDistance = 0;
        } else if (startLocationDistance > 1) {
            startLocationDistance = 1;
        }
        xLocation = startLocationDistance;
        resetInit = false;
    }
    if (isRoll) {
        if (xLocation <= -(contentWidth + getBlankWidth() * itemDistance)) {
            xLocation = xLocation + contentWidth + getBlankWidth() * itemDistance;
            string = string + content;
            //调用pattern.quote ,防止replaceFirst中含有特殊字符比如完整的(),导致的crash
            string = string.replaceFirst(pattern.quote(""+content), "");   //修改内存问题,防止文字长度不断增加导致内存溢出的情况,
        }
    }

    //把文字画出来
    if (string != null) {
        canvas.drawText(string, xLocation, getHeight() / 2 + textHeight / 2, paint);
    }

}

/**
 * 继续滚动
 */
public void continueRoll() {
    postInvalidate();
    mHandler.removeMessages(1);
    isRoll = true;
    mHandler.sendEmptyMessage(1);
}

/**
 * 停止滚动
 */
public void stopRoll() {
    isRoll = false;
    resetInit = true;
    mHandler.removeMessages(1);
    postInvalidate();
}

public void setTextColor(int color) {
    textColor = color;
    paint.setColor(color);
    postInvalidate();
}

private float getContentWidth(String black) {
    if (TextUtils.isEmpty(black)) {
        return 0;
    }

    if (rect == null) {
        rect = new Rect();
    }
    paint.getTextBounds(black, 0, black.length(), rect);
    textHeight = getContentHeight();

    return rect.width();
}

/**
 * http://blog.csdn.net/u014702653/article/details/51985821
 * 详细解说了
 *
 * @param
 * @return
 */
private float getContentHeight() {
    Paint.FontMetrics fontMetrics = paint.getFontMetrics();
    return Math.abs((fontMetrics.bottom - fontMetrics.top)) / 2;
}


/**
 * 计算出一个空格的宽度
 */
private float getBlankWidth() {
    String text1 = "en en";
    String text2 = "enen";
    return getContentWidth(text1) - getContentWidth(text2);

}

/**
 * 添加文字
 * @param content 显示文字的内容
 * @param needRoll 是否需要滚动,如果不需要,就把文字定位到startLocationDistance的位置,而且不重复
 */
public void setContent(String content, boolean needRoll) {
    if (TextUtils.isEmpty(content)) {
        return;
    }

    isResetLocation = true;
    resetInit = true;
    if (needRoll) {
        for (int i = 0; i < itemDistance; i++) {
            content = content + " ";
        }
        this.content = content;
        contentWidth = (int) (getContentWidth(content));//可以理解为一个单元内容的长度
        int contentCount = (getWidth() / contentWidth) + 2;
        this.string = "";
        for (int i = 0; i <= contentCount + 2; i++) {
            this.string = String.format("%s%s", this.string, this.content);//根据重复次数去叠加。
        }
        postInvalidate();
    } else {
        stopRoll();
        resetInit = true;
        getContentWidth(content);
        this.content = content;  //如果不需要滚动,就直接走这里了
        this.string = content;
        postInvalidate();
    }

}

}

========================== attrs.xml================

    <attr name="marqueeview_text_speed" format="float" /><!--播放速度 也就是文字滚动速度-->
    <attr name="marqueeview_text_color" format="color|reference" /><!-- 文字颜色 -->
    <attr name="marqueeview_text_size" format="float" /><!-- 文字大小 -->

    <attr name="marqueeview_is_resetLocation" format="boolean" /><!--重新改变内容的时候 , 是否初始化 位置,默认为true,改变-->


    <attr name="marqueeview_text_shadow" format="boolean" /> <!---是否设置阴影-->
    <attr name="marqueeview_text_shadow_radius" format="float" /> <!---是否设置阴影-->
    <attr name="marqueeview_text_shadow_dx" format="float" /> <!---是否设置阴影-->
    <attr name="marqueeview_text_shadow_dy" format="float" /> <!---是否设置阴影-->
    <attr name="marqueeview_text_shadow_color" format="color" /> <!---是否设置阴影-->

</declare-styleable>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.