refactor(TextDrawable.java): add back TextDrawable.java
This commit is contained in:
@@ -0,0 +1,242 @@
|
|||||||
|
package org.joinmastodon.android.ui.utils;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2016 Ali Muzaffar
|
||||||
|
* <p/>
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* <p/>
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* <p/>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.ColorFilter;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.PixelFormat;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.TextWatcher;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
|
public class TextDrawable extends Drawable implements TextWatcher {
|
||||||
|
private WeakReference<TextView> ref;
|
||||||
|
private String mText;
|
||||||
|
private Paint mPaint;
|
||||||
|
private Rect mHeightBounds;
|
||||||
|
private boolean mBindToViewPaint = false;
|
||||||
|
private float mPrevTextSize = 0;
|
||||||
|
private boolean mInitFitText = false;
|
||||||
|
private boolean mFitTextEnabled = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a TextDrawable using the given paint object and string
|
||||||
|
*
|
||||||
|
* @param paint
|
||||||
|
* @param s
|
||||||
|
*/
|
||||||
|
public TextDrawable(Paint paint, String s) {
|
||||||
|
mText = s;
|
||||||
|
mPaint = new Paint(paint);
|
||||||
|
mHeightBounds = new Rect();
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a TextDrawable. This uses the given TextView to initialize paint and has initial text
|
||||||
|
* that will be drawn. Initial text can also be useful for reserving space that may otherwise
|
||||||
|
* not be available when setting compound drawables.
|
||||||
|
*
|
||||||
|
* @param tv The TextView / EditText using to initialize this drawable
|
||||||
|
* @param initialText Optional initial text to display
|
||||||
|
* @param bindToViewsText Should this drawable mirror the text in the TextView
|
||||||
|
* @param bindToViewsPaint Should this drawable mirror changes to Paint in the TextView, like textColor, typeface, alpha etc.
|
||||||
|
* Note, this will override any changes made using setColorFilter or setAlpha.
|
||||||
|
*/
|
||||||
|
public TextDrawable(TextView tv, String initialText, boolean bindToViewsText, boolean bindToViewsPaint) {
|
||||||
|
this(tv.getPaint(), initialText);
|
||||||
|
ref = new WeakReference<>(tv);
|
||||||
|
if (bindToViewsText || bindToViewsPaint) {
|
||||||
|
if (bindToViewsText) {
|
||||||
|
tv.addTextChangedListener(this);
|
||||||
|
}
|
||||||
|
mBindToViewPaint = bindToViewsPaint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a TextDrawable. This uses the given TextView to initialize paint and the text that
|
||||||
|
* will be drawn.
|
||||||
|
*
|
||||||
|
* @param tv The TextView / EditText using to initialize this drawable
|
||||||
|
* @param bindToViewsText Should this drawable mirror the text in the TextView
|
||||||
|
* @param bindToViewsPaint Should this drawable mirror changes to Paint in the TextView, like textColor, typeface, alpha etc.
|
||||||
|
* Note, this will override any changes made using setColorFilter or setAlpha.
|
||||||
|
*/
|
||||||
|
public TextDrawable(TextView tv, boolean bindToViewsText, boolean bindToViewsPaint) {
|
||||||
|
this(tv, tv.getText().toString(), bindToViewsText, bindToViewsPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the provided TextView/EditText to initialize the drawable.
|
||||||
|
* The Drawable will copy the Text and the Paint properties, however it will from that
|
||||||
|
* point on be independant of the TextView.
|
||||||
|
*
|
||||||
|
* @param tv a TextView or EditText or any of their children.
|
||||||
|
*/
|
||||||
|
public TextDrawable(TextView tv) {
|
||||||
|
this(tv, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the provided TextView/EditText to initialize the drawable.
|
||||||
|
* The Drawable will copy the Paint properties, and use the provided text to initialise itself.
|
||||||
|
*
|
||||||
|
* @param tv a TextView or EditText or any of their children.
|
||||||
|
* @param s The String to draw
|
||||||
|
*/
|
||||||
|
public TextDrawable(TextView tv, String s) {
|
||||||
|
this(tv, s, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas) {
|
||||||
|
if (mBindToViewPaint && ref.get() != null) {
|
||||||
|
Paint p = ref.get().getPaint();
|
||||||
|
canvas.drawText(mText, 0, getBounds().height(), p);
|
||||||
|
} else {
|
||||||
|
if (mInitFitText) {
|
||||||
|
fitTextAndInit();
|
||||||
|
}
|
||||||
|
canvas.drawText(mText, 0, getBounds().height(), mPaint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAlpha(int alpha) {
|
||||||
|
mPaint.setAlpha(alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setColorFilter(ColorFilter colorFilter) {
|
||||||
|
mPaint.setColorFilter(colorFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOpacity() {
|
||||||
|
int alpha = mPaint.getAlpha();
|
||||||
|
if (alpha == 0) {
|
||||||
|
return PixelFormat.TRANSPARENT;
|
||||||
|
} else if (alpha == 255) {
|
||||||
|
return PixelFormat.OPAQUE;
|
||||||
|
} else {
|
||||||
|
return PixelFormat.TRANSLUCENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
Rect bounds = getBounds();
|
||||||
|
//We want to use some character to determine the max height of the text.
|
||||||
|
//Otherwise if we draw something like "..." they will appear centered
|
||||||
|
//Here I'm just going to use the entire alphabet to determine max height.
|
||||||
|
mPaint.getTextBounds("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 0, 1, mHeightBounds);
|
||||||
|
//This doesn't account for leading or training white spaces.
|
||||||
|
//mPaint.getTextBounds(mText, 0, mText.length(), bounds);
|
||||||
|
float width = mPaint.measureText(mText);
|
||||||
|
bounds.top = mHeightBounds.top;
|
||||||
|
bounds.bottom = mHeightBounds.bottom;
|
||||||
|
bounds.right = (int) width;
|
||||||
|
bounds.left = 0;
|
||||||
|
setBounds(bounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPaint(Paint paint) {
|
||||||
|
mPaint = new Paint(paint);
|
||||||
|
//Since this can change the font used, we need to recalculate bounds.
|
||||||
|
if (mFitTextEnabled && !mInitFitText) {
|
||||||
|
fitTextAndInit();
|
||||||
|
} else {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
invalidateSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Paint getPaint() {
|
||||||
|
return mPaint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(String text) {
|
||||||
|
mText = text;
|
||||||
|
//Since this can change the bounds of the text, we need to recalculate.
|
||||||
|
if (mFitTextEnabled && !mInitFitText) {
|
||||||
|
fitTextAndInit();
|
||||||
|
} else {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
invalidateSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return mText;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
setText(s.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make the TextDrawable match the width of the View it's associated with.
|
||||||
|
* <p/>
|
||||||
|
* Note: While this option will not work if bindToViewPaint is true.
|
||||||
|
*
|
||||||
|
* @param fitText
|
||||||
|
*/
|
||||||
|
public void setFillText(boolean fitText) {
|
||||||
|
mFitTextEnabled = fitText;
|
||||||
|
if (fitText) {
|
||||||
|
mPrevTextSize = mPaint.getTextSize();
|
||||||
|
if (ref.get() != null) {
|
||||||
|
if (ref.get().getWidth() > 0) {
|
||||||
|
fitTextAndInit();
|
||||||
|
} else {
|
||||||
|
mInitFitText = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mPrevTextSize > 0) {
|
||||||
|
mPaint.setTextSize(mPrevTextSize);
|
||||||
|
}
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fitTextAndInit() {
|
||||||
|
float fitWidth = ref.get().getWidth();
|
||||||
|
float textWidth = mPaint.measureText(mText);
|
||||||
|
float multi = fitWidth / textWidth;
|
||||||
|
mPaint.setTextSize(mPaint.getTextSize() * multi);
|
||||||
|
mInitFitText = false;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user