I have this class that implement an AutoResizeTextView:
public class AutoResizeTv extends TextView {
private float minTextSize = 2;
private float maxTextSize = 25;
public AutoResizeTv(Context context) {
super(context);
init();
}
public AutoResizeTv(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
maxTextSize = this.getTextSize();
if (maxTextSize < 35) {
maxTextSize = 25;
}
minTextSize = 2;
}
private void refitText(String text, int textWidth) {
if (textWidth > 0) {
int availableWidth = textWidth - this.getPaddingLeft()
- this.getPaddingRight();
float trySize = maxTextSize;
this.setTextSize(TypedValue.COMPLEX_UNIT_PX, trySize);
while ((trySize > minTextSize)
&& (this.getPaint().measureText(text) > availableWidth)) {
trySize -= 1;
if (trySize <= minTextSize) {
trySize = minTextSize;
break;
}
this.setTextSize(TypedValue.COMPLEX_UNIT_PX, trySize);
}
this.setTextSize(TypedValue.COMPLEX_UNIT_PX, trySize);
}
}
#Override
protected void onTextChanged(final CharSequence text, final int start,
final int before, final int after) {
refitText(text.toString(), this.getWidth());
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (w != oldw) {
refitText(this.getText().toString(), w);
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
refitText(this.getText().toString(), parentWidth);
}
public float getMinTextSize() {
return minTextSize;
}
public void setMinTextSize(int minTextSize) {
this.minTextSize = minTextSize;
}
public float getMaxTextSize() {
return maxTextSize;
}
public void setMaxTextSize(int minTextSize) {
this.maxTextSize = minTextSize;
}
On most Android devices it works well, but i've noticed that on some old Android version (for example a tablet with sdk version 13) , text is not scaled to fit its container.
How can i fix it for get the same behavior on all android devices (i prefer to edit this class instead use a new AutoResizeTextView implementation)
Related
I have a problem that all of the customize progress didn't show progress in a ListView.
Here is mucustomize progress view below:
public class LProgressBar extends View {
private final int DEFAULT_HEIGHT = dp2px(10);
private static final int DEFAULT_REACHED_COLOR = 0xFFE66059;
private static final int DEFAULT_UNREACHED_COLOR = 0xFF7A9B5B;
private static final int DEFAULT_ANIMATE_DURATION = 1000;
private static final int DEFAULT_MAX_VALUE = 100;
private static final int DEFAULT_PROGRESS = 0;
private static final Boolean DEBUG = false;
private int mHeight;
private int mRealWidth;
private int mReachedColor;
private int mUnreachedColor;
private int mDuration;
private float mProgress;
private int mMaxValue;
private boolean debug;
private Paint mUnreachedPaint;
private Paint mReachedPaint;
public LProgressBar(Context context) {
this(context, null);
}
public LProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public LProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
obtainStyledAttributes(attrs);
reset();
}
private void obtainStyledAttributes(AttributeSet attrs) {
final TypedArray attr = getContext().obtainStyledAttributes(attrs, R.styleable.LProgressBar);
mHeight = (int) attr.getDimension(R.styleable.LProgressBar_ruman_height, DEFAULT_HEIGHT);
mReachedColor = attr.getColor(R.styleable.LProgressBar_ruman_reached_color, DEFAULT_REACHED_COLOR);
mUnreachedColor = attr.getColor(R.styleable.LProgressBar_ruman_unreached_color, DEFAULT_UNREACHED_COLOR);
debug = attr.getBoolean(R.styleable.LProgressBar_ruman_debug, DEBUG);
mDuration = (int) attr.getDimension(R.styleable.LProgressBar_ruman_duration, DEFAULT_ANIMATE_DURATION);
mProgress = (float) attr.getFloat(R.styleable.LProgressBar_ruman_progress, DEFAULT_PROGRESS);
mMaxValue = (int) attr.getDimension(R.styleable.LProgressBar_ruman_maxvalue, DEFAULT_MAX_VALUE);
attr.recycle();
}
#Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else {
width = 100;
if (widthMode == MeasureSpec.AT_MOST)
width = Math.min(widthSize, 100);
}
if (heightMode == MeasureSpec.EXACTLY)
height = heightSize;
else {
height = mHeight;
if (heightMode == MeasureSpec.AT_MOST)
height = Math.min(heightSize, mHeight);
}
setMeasuredDimension(width, height);
mRealWidth = getMeasuredWidth();
}
#Override
protected synchronized void onDraw(Canvas canvas) {
canvas.drawLine(0, 0, mRealWidth, 0, mUnreachedPaint);
canvas.drawLine(0, 0, mProgress, 0, mReachedPaint);
}
private void reset() {
initUnreachedPaint();
initReachedPaint();
}
private void initUnreachedPaint() {
mUnreachedPaint = new Paint();
mUnreachedPaint.setColor(mUnreachedColor);
mUnreachedPaint.setStrokeWidth(dp2px(mHeight));
}
private void initReachedPaint() {
mReachedPaint = new Paint();
mReachedPaint.setColor(mReachedColor);
mReachedPaint.setStrokeWidth(dp2px(mHeight));
}
public synchronized void setProgress(float progress) {
float radio = (float) progress * 1.0f / mMaxValue * 1.0f;
mProgress = (float) mRealWidth * radio * 1.0f;
invalidate();
}
private void startProgressAnim() {
ValueAnimator animator = ValueAnimator.ofFloat(0, mProgress);
animator.setDuration(mDuration);
animator.setInterpolator(new DecelerateInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
mProgress = value;
invalidate();
}
});
animator.start();
}
/**
* dp2px
*
* #param dpValue dp
* #return px
*/
private int dp2px(int dpValue) {
return (int) getContext().getResources().getDisplayMetrics().density * dpValue;
}
}
I put it in a ListView and i called lProgressBar.setProgress(50.0f); but not working, all of the progress is 0. I tried call notifyDataSetChanged() still not working. Help me plz.
I have a spinner in which I want to display several names.
I get the names based on a sqlite query. How I can reduce font size based on the length of the longest name? Shall I use and check with
textView.getText().length() ?
Naive:
Find longest string.
Measure TextView Max size.
Measure
text to fit inside TextView. (Using TextPaint, that provides measure text methods.)
You just need to figure out algorithm. Could be something like this.
size = TextView.getWidth();
paint = new TextPaint();
paint.setTextSize(SOME_BIG_NUMBER);
while(true){
if (paint.measureText(longest_text) < size){
break;
} else {
paint.setTextSize(paint.getTextSize() -1f);
}
}
result size = paint.getTextSize();
Another approach could be using AutoResizeTextView. After setting data, just go thru all AutoResizeTextViews, find minimum, then set it to all TextViews. But it's extremely expensive and user will notice drawing.
public class AutoResizeTextView extends TextView {
private interface SizeTester {
/**
* #param suggestedSize Size of text to be tested
* #param availableSpace available space in which text must fit
*
* #return an integer < 0 if after applying {#code suggestedSize} to
* text, it takes less space than {#code availableSpace}, > 0
* otherwise
*/
public int onTestSize(int suggestedSize, RectF availableSpace);
}
private RectF mTextRect = new RectF();
private RectF mAvailableSpaceRect;
private SparseIntArray mTextCachedSizes;
private TextPaint mPaint;
private float mMaxTextSize;
private float mSpacingMult = 1.0f;
private float mSpacingAdd = 0.0f;
private float mMinTextSize = 20;
private int mWidthLimit;
private Typeface mTypeFace;
private static final int NO_LINE_LIMIT = -1;
private int mMaxLines;
private boolean mEnableSizeCache = true;
private boolean mInitiallized;
public AutoResizeTextView(Context context) {
super(context);
initialize();
ArrayList<String> list = new ArrayList<>();
int index = -1;
for (String st : list) {
index = index < st.length() ? st.length() :index;
}
TextPaint paint = new TextPaint();
paint.measureText(list.get(index));
}
public AutoResizeTextView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize();
}
public AutoResizeTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initialize();
}
private void initialize() {
mPaint = new TextPaint(getPaint());
if (mTypeFace != null) {
mPaint.setTypeface(mTypeFace);
}
mMaxTextSize = getTextSize();
mAvailableSpaceRect = new RectF();
mTextCachedSizes = new SparseIntArray();
if (mMaxLines == 0) {
// no value was assigned during construction
mMaxLines = NO_LINE_LIMIT;
}
mInitiallized = true;
}
#Override
public void setText(final CharSequence text, BufferType type) {
super.setText(text, type);
adjustTextSize(text.toString());
}
#Override
public void setTextSize(float size) {
mMaxTextSize = size;
mTextCachedSizes.clear();
adjustTextSize(getText().toString());
}
#Override
public void setMaxLines(int maxlines) {
super.setMaxLines(maxlines);
mMaxLines = maxlines;
reAdjust();
}
public int getMaxLines() {
return mMaxLines;
}
#Override
public void setSingleLine() {
super.setSingleLine();
mMaxLines = 1;
reAdjust();
}
#Override
public void setSingleLine(boolean singleLine) {
super.setSingleLine(singleLine);
if (singleLine) {
mMaxLines = 1;
} else {
mMaxLines = NO_LINE_LIMIT;
}
reAdjust();
}
#Override
public void setLines(int lines) {
super.setLines(lines);
mMaxLines = lines;
reAdjust();
}
#Override
public void setTextSize(int unit, float size) {
Context c = getContext();
Resources r;
if (c == null) {
r = Resources.getSystem();
} else {
r = c.getResources();
}
mMaxTextSize = TypedValue.applyDimension(unit, size,
r.getDisplayMetrics());
mTextCachedSizes.clear();
adjustTextSize(getText().toString());
}
#Override
public void setLineSpacing(float add, float mult) {
super.setLineSpacing(add, mult);
mSpacingMult = mult;
mSpacingAdd = add;
}
/**
* Set the lower text size limit and invalidate the view
*
* #param minTextSize
*/
public void setMinTextSize(float minTextSize) {
mMinTextSize = minTextSize;
reAdjust();
}
private void reAdjust() {
adjustTextSize(getText().toString());
}
private void adjustTextSize(String string) {
if (!mInitiallized) {
return;
}
int startSize = (int) mMinTextSize;
int heightLimit = getMeasuredHeight() - getCompoundPaddingBottom()
- getCompoundPaddingTop();
mWidthLimit = getMeasuredWidth() - getCompoundPaddingLeft()
- getCompoundPaddingRight();
if (mWidthLimit < 0) {
mWidthLimit = 0;
}
mAvailableSpaceRect.right = mWidthLimit;
mAvailableSpaceRect.bottom = heightLimit;
super.setTextSize(
TypedValue.COMPLEX_UNIT_PX,
efficientTextSizeSearch(startSize, (int) mMaxTextSize,
mSizeTester, mAvailableSpaceRect));
}
private final SizeTester mSizeTester = new SizeTester() {
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
#Override
public int onTestSize(int suggestedSize, RectF availableSPace) {
mPaint.setTextSize(suggestedSize);
String text = getText().toString();
boolean singleline = getMaxLines() == 1;
if (singleline) {
mTextRect.bottom = mPaint.getFontSpacing();
mTextRect.right = mPaint.measureText(text);
} else {
StaticLayout layout = new StaticLayout(text, mPaint,
mWidthLimit, Layout.Alignment.ALIGN_NORMAL, mSpacingMult,
mSpacingAdd, true);
// return early if we have more lines
if (getMaxLines() != NO_LINE_LIMIT
&& layout.getLineCount() > getMaxLines()) {
return 1;
}
mTextRect.bottom = layout.getHeight();
int maxWidth = -1;
for (int i = 0; i < layout.getLineCount(); i++) {
if (maxWidth < layout.getLineWidth(i)) {
maxWidth = (int) layout.getLineWidth(i);
}
}
mTextRect.right = maxWidth;
}
mTextRect.offsetTo(0, 0);
if (availableSPace
.contains(mTextRect)) { // may be too small, don't worry we will find the best match
return -1;
} else {
if (mTextRect.bottom < availableSPace.bottom
&& mTextRect.right > availableSPace.right) {
// hack :O
return -1;
}
// too big
return 1;
}
}
};
/**
* Enables or disables size caching, enabling it will improve performance
* where you are animating a value inside TextView. This stores the font
* size against getText().length() Be careful though while enabling it as 0
* takes more space than 1 on some fonts and so on.
*
* #param enable enable font size caching
*/
public void enableSizeCache(boolean enable) {
mEnableSizeCache = enable;
mTextCachedSizes.clear();
adjustTextSize(getText().toString());
}
private int efficientTextSizeSearch(int start, int end,
SizeTester sizeTester, RectF availableSpace) {
if (!mEnableSizeCache) {
return binarySearch(start, end, sizeTester, availableSpace);
}
String text = getText().toString();
int key = text == null ? 0 : text.length();
int size = mTextCachedSizes.get(key);
if (size != 0) {
return size;
}
size = binarySearch(start, end, sizeTester, availableSpace);
mTextCachedSizes.put(key, size);
return size;
}
private static int binarySearch(int start, int end, SizeTester sizeTester,
RectF availableSpace) {
int lastBest = start;
int lo = start;
int hi = end - 1;
int mid = 0;
while (lo <= hi) {
mid = (lo + hi) >>> 1;
int midValCmp = sizeTester.onTestSize(mid, availableSpace);
if (midValCmp < 0) {
lastBest = lo;
lo = mid + 1;
} else if (midValCmp > 0) {
hi = mid - 1;
lastBest = hi;
} else {
return mid;
}
}
// make sure to return last best
// this is what should always be returned
return lastBest;
}
#Override
protected void onTextChanged(final CharSequence text, final int start,
final int before, final int after) {
super.onTextChanged(text, start, before, after);
reAdjust();
}
#Override
protected void onSizeChanged(int width, int height, int oldwidth,
int oldheight) {
mTextCachedSizes.clear();
super.onSizeChanged(width, height, oldwidth, oldheight);
if (width != oldwidth || height != oldheight) {
reAdjust();
}
}
#Override
public void setTypeface(Typeface tf) {
super.setTypeface(tf);
mTypeFace = tf;
if (mInitiallized) {
mPaint.setTypeface(tf);
mTextCachedSizes.clear();
reAdjust();
}
}
#Override
public CharSequence getAccessibilityClassName() {
return TextView.class.getName();
}
}
Best approach is to combine these approaches. Find longest text. Simplify the AutoResizeTextView to only calculate textSize. Set this size to you textViews.
I am trying to develop custom progress bar or view, where I can pass in section value and it will create a section in that and then I will fill as per my requirements.
I tired Progress bar with divider but it not in round one ..
Looking for some thing like this
Edit:-
i have edited code as per my need but it not able to do like given image
public class DashedCircularProgress extends RelativeLayout {
public DashedCircularProgress(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public DashedCircularProgress(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
/**
* All the children must have a max height and width, never bigger than the internal circle
*
* #param changed
* #param left
* #param top
* #param right
* #param bottom
*/
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
final int count = getChildCount();
int maxWidth = getWidth() / 2;
int maxHeight = getHeight() / 2;
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
int mesaureWidth = child.getMeasuredWidth();
int measureHeight = child.getMeasuredWidth();
ViewGroup.LayoutParams layoutParams = child.getLayoutParams();
child.setTranslationY(padingTop);
RelativeLayout.LayoutParams relativeLayoutParams =
(RelativeLayout.LayoutParams) child.getLayoutParams();
relativeLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
child.setLayoutParams(relativeLayoutParams);
if (mesaureWidth > maxWidth) {
layoutParams.width = maxWidth;
}
if (measureHeight > maxHeight) {
layoutParams.height = maxHeight;
}
}
}
private void init(Context context, AttributeSet attributeSet) {
setWillNotDraw(false);
TypedArray attributes = context.obtainStyledAttributes(attributeSet,
R.styleable.DashedCircularProgress);
initAttributes(attributes);
initPainters();
initValueAnimator();
}
private void initAttributes(TypedArray attributes) {
externalColor = attributes.getColor(R.styleable.DashedCircularProgress_external_color,
externalColor);
internalBaseColor = attributes.getColor(R.styleable.DashedCircularProgress_base_color,
internalBaseColor);
progressColor = attributes.getColor(R.styleable.DashedCircularProgress_progress_color,
progressColor);
max = attributes.getFloat(R.styleable.DashedCircularProgress_max, max);
duration = attributes.getInt(R.styleable.DashedCircularProgress_duration, duration);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
progressPainter.onSizeChanged(h, w);
// externalCirclePainter.onSizeChanged(h, w);
internalCirclePainter.onSizeChanged(h, w);
//iconPainter.onSizeChanged(h, w);
animateValue();
}
private void initPainters() {
progressPainter = new ProgressPainterImp(progressColor, min, max);
//externalCirclePainter = new ExternalCirclePainterImp(externalColor);
internalCirclePainter = new InternalCirclePainterImp(internalBaseColor);
//iconPainter = new IconPainter(image);
}
private void initValueAnimator() {
valueAnimator = new ValueAnimator();
valueAnimator.setInterpolator(interpolator);
valueAnimator.addUpdateListener(new ValueAnimatorListenerImp());
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//externalCirclePainter.draw(canvas);
internalCirclePainter.draw(canvas);
progressPainter.draw(canvas);
//iconPainter.draw(canvas);
invalidate();
}
public void setValue(float value) {
this.value = value;
if (value <= max || value >= min) {
animateValue();
}
}
private void animateValue() {
if (valueAnimator != null) {
valueAnimator.setFloatValues(last, value);
valueAnimator.setDuration(duration);
valueAnimator.start();
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec + heightNormalittation);
}
public void setOnValueChangeListener(OnValueChangeListener valueChangeListener) {
this.valueChangeListener = valueChangeListener;
}
public void setInterpolator(Interpolator interpolator) {
this.interpolator = interpolator;
if (valueAnimator != null) {
valueAnimator.setInterpolator(interpolator);
}
}
public float getMin() {
return min;
}
public void setMin(float min) {
this.min = min;
progressPainter.setMin(min);
}
public float getMax() {
return max;
}
public void setMax(float max) {
this.max = max;
progressPainter.setMax(max);
}
private class ValueAnimatorListenerImp implements ValueAnimator.AnimatorUpdateListener {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
Float value = (Float) valueAnimator.getAnimatedValue();
progressPainter.setValue(value);
if (valueChangeListener != null) {
valueChangeListener.onValueChange(value);
}
last = value;
}
}
public interface OnValueChangeListener {
void onValueChange(float value);
}
public void setIcon(int drawable) {
}
public void reset() {
last = min;
}
public int getProgressColor() {
return progressColor;
}
public void setProgressColor(int progressColor) {
this.progressColor = progressColor;
progressPainter.setColor(progressColor);
}
public int getInternalBaseColor() {
return internalBaseColor;
}
public void setInternalBaseColor(int internalBaseColor) {
this.internalBaseColor = internalBaseColor;
internalCirclePainter.setColor(progressColor);
}
public int getExternalColor() {
return externalColor;
}
public void setExternalColor(int externalColor) {
this.externalColor = externalColor;
// externalCirclePainter.setColor(externalColor);
}
public int getDuration() {
return duration;
}
public void setDuration(int duration) {
this.duration = duration;
}
}
I have a customview , inside it , i have one view slide up and down , when slide i draw fade background like this :
#Override
protected void dispatchDraw(Canvas canvas) {
canvas.drawARGB(alpha, 0, 0, 0);
super.dispatchDraw(canvas);
}
It work with my device android 4.2.2 but with android 4.4.2 or google nexus one android 2.3.7 ,it so bad.
2 images below show in my device 4.2.2(slide in and slide out):
http://imgur.com/p6i9gw8
http://imgur.com/9Sdzy7v
and 2 images below show in google nexus one android 2.3.7(slide in and slide out):
http://imgur.com/ZGKiRJi
http://imgur.com/Uf3vRdb
As you can see, in 2 image first, fade draw correct , and in other, it look bad.
Complete code for this view is :
public class SlideView extends ViewGroup {
private static final int MAXDURATIONSLIDE = 500;
protected View content;
private int childHeight;
private int childOffset;
private int childWidth;
private int alpha;
private Fillinger fillinger;
public ISlide getSlideChangeListener() {
return slideListener;
}
public void setSlideChangeListener(ISlide slideChangeListener) {
this.slideListener = slideChangeListener;
}
private ISlide slideListener;
public SlideView(Context context) {
super(context);
init(context, null);
}
private void init(Context context, AttributeSet attrs) {
if(attrs!=null){
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SlideView);
try {
int contentLayoutId = a.getResourceId(R.styleable.SlideView_slideView, 0);
DebugLog.d(contentLayoutId);
setContent(contentLayoutId);
} finally {
a.recycle();
}
}
fillinger = new Fillinger(context);
}
public SlideView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context,attrs);
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int width = r - l;
final int height = b - t;
DebugLog.d("width "+width+" height "+height);
childOffset = height;
content.layout(0, childOffset, childWidth, childOffset + childHeight);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = getDefaultSize(0, widthMeasureSpec);
int height = getDefaultSize(0, heightMeasureSpec);
measureChild(content, widthMeasureSpec, height);
childHeight = content.getMeasuredHeight();
childWidth = content.getMeasuredWidth();
DebugLog.d("childWidth "+childWidth+" childHeight "+childHeight);
setMeasuredDimension(width, height);
}
public void setContent(int resId) {
View view = LayoutInflater.from(getContext()).inflate(resId, this,false);
setContent(view);
}
public void setContent(View v) {
if (content != null)
removeView(content);
content = v;
addView(content);
}
private void moveViewByY(int diffY) {
childOffset += diffY;
alpha = (int) (Math.abs((getHeight()-childOffset)*255/(childHeight))*0.5f);
content.layout(0, childOffset, childWidth, childOffset + childHeight);
if(slideListener!=null){
slideListener.onSlide(childOffset,childHeight);
}
}
#Override
protected void dispatchDraw(Canvas canvas) {
canvas.drawARGB(alpha, 0, 0, 0);
super.dispatchDraw(canvas);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if(isIn()&&touchOutSide(event)){
toogle();
return true;
}
return false;
}
private boolean touchOutSide(MotionEvent event) {
final float x = event.getX();
final float y = event.getY();
if(x<content.getLeft()||x>content.getRight()||y<content.getTop()||y>content.getBottom()){
return true;
}
return false;
}
public void hide(){
if(isIn()){
fillinger.startScroll(content.getTop(),getHeight(),childHeight,MAXDURATIONSLIDE);
}
}
public void show(){
if(!isIn()){
fillinger.startScroll(content.getTop(),getHeight()-childHeight,childHeight,MAXDURATIONSLIDE);
}
}
public void toogle(){
fillinger.cancleAnimation();
if(isIn()){
hide();
}else{
show();
}
}
public boolean isIn(){
return content.getTop()<getHeight();
}
public class Fillinger implements Runnable {
private static final String tag = "Fillinger";
private Scroller mScroller;
private int lastY;
private boolean more;
private int currentY;
private int diffY;
public Fillinger(Context context) {
mScroller = new Scroller(context);
}
public void startScroll(float startY, float endY, float maxDistance, int maxDurationForFling) {
int duration = (int) Math.min(Math.abs((endY - startY)) / maxDistance * maxDurationForFling, maxDurationForFling);
lastY = (int) startY;
if(slideListener!=null){
slideListener.onStartSlide();
}
mScroller.startScroll(0, (int) startY, 0, -(int) (endY - startY), duration);
setDrawingCacheEnabled(true);
post(this);
}
public void cancleAnimation(){
removeCallbacks(this);
}
#Override
public void run() {
more = mScroller.computeScrollOffset();
currentY = mScroller.getCurrY();
diffY = lastY - currentY;
moveViewByY(diffY);
lastY = currentY;
if (more) {
post(this);
}else{
setDrawingCacheEnabled(false);
if(slideListener!=null){
slideListener.onSlideFinish(isIn());
}
}
}
}
}
What i missing?
Sorry for my bad english.
Thanks all.
Edit: finally , i must call invalidate in moveViewByY method like this
private void moveViewByY(int diffY) {
childOffset += diffY;
alpha = (int) (Math.abs((getHeight()-childOffset)*255/(childHeight))*0.5f);
content.layout(0, childOffset, childWidth, childOffset + childHeight);
invalidate();
if(slideListener!=null){
slideListener.onSlide(childOffset,childHeight);
}
}
I dont know why , may be invalidate , view tree redraw and old canvas cleared.
Expect best solution, thanks .
I am trying to set the TextView to be auto scale inside the dialog,
xml
<com.abc.abc.AutoResizeTextView
android:id="#+id/text_btn"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_above="#+id/view2"
android:layout_alignLeft="#+id/linear_layout_color1"
android:layout_alignRight="#+id/linear_layout_color1"
android:layout_alignTop="#+id/doodleView"
android:layout_margin="1dp"
android:background="#color/white"
android:gravity="center"
android:text="A"
android:textColor="#color/grey" />
AutoResizeTextView
and AutoResizeTextView as in
Auto Scale TextView Text to Fit within Bounds
and then in java code
AutoResizeTextView textView = (AutoResizeTextView ) writing_dialog.findViewById(R.id.text_btn);
textView.setText("B");
Question:
I do not know why the text B is still appearing very small and not auto-scaling...
Thanks for your advice!
I am using this version of auto fit text view, which works great:
public class AutoFitTextView extends TextView {
public AutoFitTextView(Context context) {
super(context);
init();
}
public AutoFitTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
maxTextSize = this.getTextSize();
if (maxTextSize < 35) {
maxTextSize = 30;
}
minTextSize = 20;
}
private void refitText(String text, int textWidth) {
if (textWidth > 0) {
int availableWidth = textWidth - this.getPaddingLeft()
- this.getPaddingRight();
float trySize = maxTextSize;
this.setTextSize(TypedValue.COMPLEX_UNIT_PX, trySize);
while ((trySize > minTextSize)
&& (this.getPaint().measureText(text) > availableWidth)) {
trySize -= 1;
if (trySize <= minTextSize) {
trySize = minTextSize;
break;
}
this.setTextSize(TypedValue.COMPLEX_UNIT_PX, trySize);
}
this.setTextSize(TypedValue.COMPLEX_UNIT_PX, trySize);
}
}
#Override
protected void onTextChanged(final CharSequence text, final int start,
final int before, final int after) {
refitText(text.toString(), this.getWidth());
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (w != oldw) {
refitText(this.getText().toString(), w);
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
refitText(this.getText().toString(), parentWidth);
}
public float getMinTextSize() {
return minTextSize;
}
public void setMinTextSize(int minTextSize) {
this.minTextSize = minTextSize;
}
public float getMaxTextSize() {
return maxTextSize;
}
public void setMaxTextSize(int minTextSize) {
this.maxTextSize = minTextSize;
}
private float minTextSize;
private float maxTextSize;
}
also set the width to:
android:layout_width="match_parent"