public class MScollingTextView extends TextView implements IView {
private boolean mHasMFocus
= false;
private boolean mIsMSelected
= false;
public
MScollingTextView(Context context) {
super(context);
init();
}
public
MScollingTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public
MScollingTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs,
defStyleAttr);
init();
}
// layout params
@Override
public ViewGroup.LayoutParams
getMLayoutParams() {
return getLayoutParams();
}
@Override
public int getMHeight() {
return getHeight();
}
@Override
public int getMWidth() {
return getWidth();
}
@Override
public void
setMLayoutParams(ViewGroup.LayoutParams params) {
setLayoutParams(params);
}
// padding
@Override
public int getMPaddingBottom() {
return getPaddingBottom();
}
@Override
public int getMPaddingLeft() {
return getPaddingLeft();
}
@Override
public int getMPaddingRight() {
return getPaddingRight();
}
@Override
public int getMPaddingTop() {
return getPaddingTop();
}
@Override
public void setMPadding(int left, int top, int right, int bottom) {
setPadding((left),
(top),(right),
(bottom));
}
// focus
@Override
public
boolean hasMFocus() {
return
mHasMFocus;
}
@Override
public
void setMFocus(boolean focused) {
mHasMFocus = focused;
OnFocusChangeListener l =
getOnFocusChangeListener();
if
(null != l) {
l.onFocusChange(this, mHasMFocus);
}
}
// selected
@Override
public boolean isMSelected() {
return
mIsMSelected;
}
@Override
public void setMSelected(boolean selected) {
mIsMSelected = selected;
}
// text size
public float getMTextSize() {
return
Util.convertOut(getTextSize());
}
public void setMTextSize(float size) {
setTextSize(TypedValue.COMPLEX_UNIT_PX, Util.convertIn(size));
}
public void setMTextSize(int unit, float size) {
setTextSize(TypedValue.COMPLEX_UNIT_PX, Util.convertIn(size));
}
// init
private void init() {
setMTextSize(TypedValue.COMPLEX_UNIT_PX, getTextSize());
setMPadding(
getPaddingLeft(),
getPaddingTop(),
getPaddingRight(), getPaddingBottom());
setSingleLine(true);
setFocus(false);
mReseted = true;
mMeasureSpec =
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
@Override
public void setFlash(Flash flash) {
// TODO Auto-generated method
stub
}
@SuppressLint("Override") @Override
public float getCameraDistance() {
// TODO Auto-generated method
stub
return 0;
}
public void setFocus(boolean focused) {
mHasFocus = focused;
mReseted = true;
if (mHasFocus)
{
setEllipsize(TruncateAt.MARQUEE);
setMarqueeRepeatLimit(-1);
} else {
setEllipsize(TruncateAt.END);
}
invalidate();
}
// ---------------- override ----------------
@Override
public boolean requestFocus(int direction, Rect previouslyFocusedRect)
{
return false;
}
@Override
protected void onDraw(Canvas canvas) {
if
(mHasFocus) {
if
(mReseted) {
mStart
= System.currentTimeMillis();
mReseted = false;
}
scroll(canvas);
} else
{
super.onDraw(canvas);
}
}
@SuppressLint("WrongCall")
private void scroll(Canvas canvas) {
long current =
System.currentTimeMillis();
long delta;
delta = current - mStart;
measure(mMeasureSpec,
mMeasureSpec);
int measureWidth =
getMeasuredWidth();
if (delta>mScrollWait &&
measureWidth>getWidth()) {
int firstOffset = (int) ((delta-mScrollWait)
* mScrollRatio);
int threshold = measureWidth +
mTextGap;
if (firstOffset > threshold) {
firstOffset %= threshold;
mStart = current;
}
firstOffset = -firstOffset;
int secondOffsset = firstOffset +
measureWidth + mTextGap;
// first
setPadding(firstOffset, 0, 0, 0);
super.onDraw(canvas);
// second
setPadding(secondOffsset, 0, 0,
0);
super.onDraw(canvas);
} else {
super.onDraw(canvas);
}
setPadding(0, 0, 0, 0);
invalidate();
}
// ---------------- property ----------------
private boolean mHasFocus;
private boolean mReseted;
private long mStart;
private int mMeasureSpec;
private double mScrollRatio
= 0.04;
private int mTextGap
= 50;
private long mScrollWait = 1000;
}