Skip to content

Instantly share code, notes, and snippets.

@zerobranch
Last active February 27, 2019 19:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zerobranch/9ae69984c8b7ab6bb166b0247a5e07f1 to your computer and use it in GitHub Desktop.
Save zerobranch/9ae69984c8b7ab6bb166b0247a5e07f1 to your computer and use it in GitHub Desktop.
ProgressTextView is a FrameLayout consisting of TextView and ProgressBar elements. It displays either text or download animation. It is also possible to specify the border of the element (color, width, radius) directly from the layout.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ProgressTextView">
<attr name="isProgress" format="boolean" />
<attr name="progressColor" format="color" />
<attr name="progressSize" format="dimension" />
<attr name="enabledRipple" format="boolean" />
<attr name="rippleColor" format="color" />
<attr name="cornerRadiusTopLeft" format="dimension" />
<attr name="cornerRadiusTopRight" format="dimension" />
<attr name="cornerRadiusBottomRight" format="dimension" />
<attr name="cornerRadiusBottomLeft" format="dimension" />
<attr name="cornerRadius" format="dimension" />
<attr name="solidColor" format="color" />
<attr name="borderWidth" format="dimension" />
<attr name="borderColor" format="color" />
<attr name="dashWidth" format="dimension" />
<attr name="dashGap" format="dimension" />
<attr name="text" format="reference|string" />
<attr name="maxLength" format="integer" />
<attr name="textColor" format="color" />
<attr name="textSize" format="dimension" />
<attr name="font" format="reference" />
<attr name="lineSpacingExtra" format="dimension" />
<attr name="lineSpacingMultiplier" format="float" />
<attr name="letterSpacing" format="float" />
<attr name="lines" format="integer" />
<attr name="maxLines" format="integer" />
<attr name="minLines" format="integer" />
<attr name="textAllCaps" format="boolean" />
<attr name="width" format="dimension" />
<attr name="maxWidth" format="dimension" />
<attr name="minWidth" format="dimension" />
<attr name="maxHeight" format="dimension" />
<attr name="minHeight" format="dimension" />
<attr name="height" format="dimension" />
<attr name="drawableStart" format="reference" />
<attr name="drawableEnd" format="reference" />
<attr name="drawableTop" format="reference" />
<attr name="drawableBottom" format="reference" />
<attr name="drawablePadding" format="dimension" />
<attr name="drawableTint" format="color" />
<attr name="textGravity" format="integer">
<flag name="center" value="17"/>
<flag name="start" value="8388611"/>
<flag name="end" value="8388613"/>
<flag name="center_vertical" value="16"/>
<flag name="top" value="48"/>
<flag name="center_horizontal" value="1"/>
<flag name="bottom" value="80"/>
<flag name="clip_horizontal" value="8"/>
<flag name="clip_vertical" value="128"/>
<flag name="fill" value="119"/>
<flag name="fill_horizontal" value="7"/>
<flag name="fill_vertical" value="112"/>
<flag name="left" value="3"/>
<flag name="right" value="5"/>
</attr>
<attr name="progressGravity" format="integer">
<flag name="center" value="17"/>
<flag name="start" value="8388611"/>
<flag name="end" value="8388613"/>
<flag name="center_vertical" value="16"/>
<flag name="top" value="48"/>
<flag name="center_horizontal" value="1"/>
<flag name="bottom" value="80"/>
<flag name="clip_horizontal" value="8"/>
<flag name="clip_vertical" value="128"/>
<flag name="fill" value="119"/>
<flag name="fill_horizontal" value="7"/>
<flag name="fill_vertical" value="112"/>
<flag name="left" value="3"/>
<flag name="right" value="5"/>
</attr>
<attr name="ellipsize" format="enum">
<enum name="none" value="-1"/>
<enum name="start" value="0"/>
<enum name="middle" value="1"/>
<enum name="end" value="2"/>
<enum name="marquee" value="3"/>
</attr>
</declare-styleable>
</resources>
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Arman
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package mobile.sarproj.com.view;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.RippleDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.AttrRes;
import android.support.annotation.ColorInt;
import android.support.annotation.ColorRes;
import android.support.annotation.DrawableRes;
import android.support.annotation.FontRes;
import android.support.annotation.Nullable;
import android.support.annotation.Px;
import android.support.annotation.StringRes;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.text.InputFilter;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
/**
* This project combines elements of TextView and ProgressBar.
* Allows you to use ProgressBar and TextView in the same layout.
* It also extends the capabilities of TextView, allowing you to specify the element border and radius.
* <p>
* Date: 2019-02-17
* Repository #https://github.com/ArmanSar/ProgressTextView
*
* @author Arman
*/
public class ProgressTextView extends FrameLayout {
@ColorInt
private static final int RIPPLE_COLOR = Color.parseColor("#1F000000");
private static final String IS_ENABLE_PROGRESS_STATE = "is_enable_progress_state";
public static final int NO_INDEX = -1;
private GradientDrawable gradientDrawable;
private TextView textView;
private ProgressBar progressBar;
private boolean isEnableProgress;
public ProgressTextView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public ProgressTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
private void init(AttributeSet attrs) {
inflate(getContext(), R.layout.view_progress_text, this);
textView = findViewById(R.id.text_view);
progressBar = findViewById(R.id.progress);
final TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.ProgressTextView);
int textColorInt = typedArray.getColor(R.styleable.ProgressTextView_textColor, getColorByAttr(android.R.attr.textColorPrimary));
int maxLength = typedArray.getInteger(R.styleable.ProgressTextView_maxLength, NO_INDEX);
CharSequence text = typedArray.getText(R.styleable.ProgressTextView_text);
int textSize = typedArray.getDimensionPixelSize(R.styleable.ProgressTextView_textSize, (int) textView.getTextSize());
int progressColor = typedArray.getColor(R.styleable.ProgressTextView_progressColor, getColorByAttr(R.attr.colorAccent));
int fontRes = typedArray.getResourceId(R.styleable.ProgressTextView_font, NO_INDEX);
int cornerRadius = typedArray.getDimensionPixelSize(R.styleable.ProgressTextView_cornerRadius, 0);
int cornerRadiusTopLeft = typedArray.getDimensionPixelSize(R.styleable.ProgressTextView_cornerRadiusTopLeft, cornerRadius);
int cornerRadiusTopRight = typedArray.getDimensionPixelSize(R.styleable.ProgressTextView_cornerRadiusTopRight, cornerRadius);
int cornerRadiusBottomRight = typedArray.getDimensionPixelSize(R.styleable.ProgressTextView_cornerRadiusBottomRight, cornerRadius);
int cornerRadiusBottomLeft = typedArray.getDimensionPixelSize(R.styleable.ProgressTextView_cornerRadiusBottomLeft, cornerRadius);
int solidColor = typedArray.getColor(R.styleable.ProgressTextView_solidColor, NO_INDEX);
int borderColor = typedArray.getColor(R.styleable.ProgressTextView_borderColor, NO_INDEX);
int borderWidth = typedArray.getDimensionPixelSize(R.styleable.ProgressTextView_borderWidth, NO_INDEX);
int dashWidth = typedArray.getDimensionPixelSize(R.styleable.ProgressTextView_dashWidth, 0);
int dashGap = typedArray.getDimensionPixelSize(R.styleable.ProgressTextView_dashGap, 0);
boolean isEnableRipple = typedArray.getBoolean(R.styleable.ProgressTextView_enabledRipple, false);
boolean isProgress = typedArray.getBoolean(R.styleable.ProgressTextView_isProgress, false);
int rippleColor = typedArray.getColor(R.styleable.ProgressTextView_rippleColor, RIPPLE_COLOR);
int progressSize = typedArray.getDimensionPixelSize(R.styleable.ProgressTextView_progressSize, NO_INDEX);
int progressGravity = typedArray.getInteger(R.styleable.ProgressTextView_progressGravity, NO_INDEX);
int textGravity = typedArray.getInteger(R.styleable.ProgressTextView_textGravity, NO_INDEX);
int ellipsize = typedArray.getInteger(R.styleable.ProgressTextView_ellipsize, NO_INDEX);
int lineSpacingExtra = typedArray.getDimensionPixelSize(R.styleable.ProgressTextView_lineSpacingExtra, NO_INDEX);
float lineSpacingMultiplier = typedArray.getFloat(R.styleable.ProgressTextView_lineSpacingMultiplier, NO_INDEX);
int drawablePadding = typedArray.getDimensionPixelSize(R.styleable.ProgressTextView_drawablePadding, NO_INDEX);
float letterSpacing = typedArray.getFloat(R.styleable.ProgressTextView_letterSpacing, NO_INDEX);
int maxHeight = typedArray.getDimensionPixelSize(R.styleable.ProgressTextView_maxHeight, NO_INDEX);
int minHeight = typedArray.getDimensionPixelSize(R.styleable.ProgressTextView_minHeight, NO_INDEX);
int height = typedArray.getDimensionPixelSize(R.styleable.ProgressTextView_height, NO_INDEX);
int width = typedArray.getDimensionPixelSize(R.styleable.ProgressTextView_width, NO_INDEX);
int maxWidth = typedArray.getDimensionPixelSize(R.styleable.ProgressTextView_maxWidth, NO_INDEX);
int minWidth = typedArray.getDimensionPixelSize(R.styleable.ProgressTextView_minWidth, NO_INDEX);
int lines = typedArray.getInteger(R.styleable.ProgressTextView_lines, NO_INDEX);
int maxLines = typedArray.getInteger(R.styleable.ProgressTextView_maxLines, NO_INDEX);
int minLines = typedArray.getInteger(R.styleable.ProgressTextView_minLines, NO_INDEX);
boolean textAllCaps = typedArray.getBoolean(R.styleable.ProgressTextView_textAllCaps, false);
Drawable drawableStart = typedArray.getDrawable(R.styleable.ProgressTextView_drawableStart);
Drawable drawableEnd = typedArray.getDrawable(R.styleable.ProgressTextView_drawableEnd);
Drawable drawableTop = typedArray.getDrawable(R.styleable.ProgressTextView_drawableTop);
Drawable drawableBottom = typedArray.getDrawable(R.styleable.ProgressTextView_drawableBottom);
int drawableTint = typedArray.getColor(R.styleable.ProgressTextView_drawableTint, NO_INDEX);
typedArray.recycle();
setTextColorInt(textColorInt);
setTextSize(textSize);
setMaxLength(maxLength);
setText(text);
setAllCaps(textAllCaps);
setProgressBarLayoutParams(progressSize, progressGravity);
setDrawables(drawableStart, drawableTop, drawableEnd, drawableBottom);
setCompoundDrawablePadding(drawablePadding);
setFont(fontRes);
setTextGravity(textGravity);
setEllipsizeInternal(ellipsize);
setLineSpacing(lineSpacingExtra, lineSpacingMultiplier);
setLetterSpacing(letterSpacing);
setMaxHeight(maxHeight);
setMinHeight(minHeight);
setHeight(height);
setWidth(width);
setMaxWidth(maxWidth);
setMinWidth(minWidth);
setLines(lines);
setMaxLines(maxLines);
setMinLines(minLines);
setDrawableTintInt(drawableTint);
setProgressColorInt(progressColor);
setCornerRadius(cornerRadiusTopLeft, cornerRadiusTopRight, cornerRadiusBottomRight, cornerRadiusBottomLeft);
setBorderInternal(borderWidth, borderColor, dashWidth, dashGap);
setSolidColorInt(solidColor);
showProgress(isProgress);
if (isEnableRipple) {
setRipple(rippleColor, cornerRadiusTopLeft, cornerRadiusTopRight,
cornerRadiusBottomRight, cornerRadiusBottomLeft);
}
if (gradientDrawable != null) {
setBackground(gradientDrawable);
}
}
@Nullable
@Override
protected Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
bundle.putBoolean(IS_ENABLE_PROGRESS_STATE, isEnableProgress);
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.bundle = bundle;
return savedState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
isEnableProgress = savedState.bundle.getBoolean(IS_ENABLE_PROGRESS_STATE);
showProgress(isEnableProgress);
}
/**
* Sets the color value from a resource ID of the ProgressBar
*
* @param color A color value from a resource ID
*/
public void setProgressColor(@ColorRes int color) {
setProgressColorInt(getColor(color));
}
/**
* Sets the color of the ProgressBar from a attribute
*
* @param attrRes A attribute value
*/
public void setProgressColorAttr(@AttrRes int attrRes) {
setProgressColorInt(getColorByAttr(attrRes));
}
/**
* Sets the color of the ProgressBar
*
* @param colorInt A color value in the form 0xAARRGGBB.
* Do not pass a resource ID.
* To set a color value from a resource ID,
* call {@link #setProgressColor(int)}.
*/
public void setProgressColorInt(@ColorInt int colorInt) {
setDrawableTint(progressBar.getIndeterminateDrawable(), colorInt);
}
/**
* Sets the text color for all the states (normal, selected, focused)
* from a resource ID
*
* @param colorRes A color value from a resource ID
*/
public void setTextColor(@ColorRes int colorRes) {
setTextColorInt(getColor(colorRes));
}
/**
* Sets the text color for all the states (normal, selected, focused)
* from a attribute
*
* @param attrRes A attribute value
*/
public void setTextColorAttr(@AttrRes int attrRes) {
setTextColorInt(getColorByAttr(attrRes));
}
/**
* Sets the text color for all the states (normal, selected, focused)
*
* @param color A color value in the form 0xAARRGGBB.
* Do not pass a resource ID. To get a color value from a resource ID, call
* {@link #setTextColor(int)}.
*/
public void setTextColorInt(@ColorInt int color) {
textView.setTextColor(color);
}
/**
* Set the default text size in pixels.
*
* @param textSize The desired size in pixels.
*/
public void setTextSize(@Px int textSize) {
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
}
/**
* Set the default text size in scaled pixel.
*
* @param textSize The desired size in scaled pixel.
*/
public void setTextSize(float textSize) {
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize);
}
/**
* Sets the font in which the text should be displayed.
*
* @param fontId A font value from a resource ID
*/
public void setFont(@FontRes int fontId) {
if (isNotEmpty(fontId)) {
textView.setTypeface(ResourcesCompat.getFont(getContext(), fontId));
}
}
/**
* This method hides the TextView and shows the ProgressBar.
*
* @param show True if to show the ProgressBar, false if to show the TextView.
*/
public void showProgress(boolean show) {
isEnableProgress = show;
setEnabled(!show);
textView.setVisibility(show ? INVISIBLE : VISIBLE);
progressBar.setVisibility(show ? VISIBLE : GONE);
}
/**
* Get the TextVIew
*
* @return Current TextView
*/
public TextView getTextView() {
return textView;
}
/**
* Get the ProgressBar
*
* @return Current ProgressBar
*/
public ProgressBar getProgressBar() {
return progressBar;
}
/**
* Set the ripple effect for the view
*
* @param radius Radius of the ripple effect border
*/
public void setRipple(@Px int radius) {
setRipple(radius, radius, radius, radius);
}
/**
* Set the ripple effect for the view
*
* @param rippleColor Color of the ripple effect
* @param radius Radius of the ripple effect border
*/
public void setRipple(@ColorInt int rippleColor, @Px int radius) {
setRipple(rippleColor, radius, radius, radius, radius);
}
/**
* Set the ripple effect for the view
*
* @param radiusTopLeft Top left radius of the ripple effect border
* @param radiusTopRight Top right radius of the ripple effect border
* @param radiusBottomRight Bottom right radius of the ripple effect border
* @param radiusBottomLeft Bottom left radius of the ripple effect border
*/
public void setRipple(@Px int radiusTopLeft, @Px int radiusTopRight,
@Px int radiusBottomRight, @Px int radiusBottomLeft) {
setRipple(RIPPLE_COLOR, radiusTopLeft, radiusTopRight, radiusBottomRight, radiusBottomLeft);
}
/**
* Set the ripple effect for the view
*
* @param rippleColor Color of the ripple effect
* @param radiusTopLeft Top left radius of the ripple effect border
* @param radiusTopRight Top right radius of the ripple effect border
* @param radiusBottomRight Bottom right radius of the ripple effect border
* @param radiusBottomLeft Bottom left radius of the ripple effect border
*/
public void setRipple(@ColorInt int rippleColor, @Px int radiusTopLeft, @Px int radiusTopRight,
@Px int radiusBottomRight, @Px int radiusBottomLeft) {
ColorStateList rippleColorStateList = ColorStateList.valueOf(rippleColor);
int maskColor = getColor(android.R.color.white);
float[] outerRadii = new float[]{
radiusTopLeft, radiusTopLeft,
radiusTopRight, radiusTopRight,
radiusBottomRight, radiusBottomRight,
radiusBottomLeft, radiusBottomLeft
};
RoundRectShape roundRectShape = new RoundRectShape(outerRadii, null, null);
ShapeDrawable shapeDrawable = new ShapeDrawable(roundRectShape);
shapeDrawable.getPaint().setColor(maskColor);
setForeground(new RippleDrawable(rippleColorStateList, null, shapeDrawable));
}
/**
* Set a single color for the view from a attribute.
*
* @param colorAttrRes A attribute value
*/
public void setSolidColorAttr(@AttrRes int colorAttrRes) {
setSolidColorInt(getColorByAttr(colorAttrRes));
}
/**
* Set a single color for the view from a resource ID.
*
* @param color A color value from a resource ID
*/
public void setSolidColor(@ColorRes int color) {
setSolidColorInt(getColor(color));
}
/**
* Set a single color for the view.
*
* @param color A color value in the form 0xAARRGGBB.
* Do not pass a resource ID. To get a color value from a resource ID, call
* {@link android.support.v4.content.ContextCompat#getColor(Context, int) getColor}.
*/
public void setSolidColorInt(@ColorInt int color) {
if (isNotEmpty(color)) {
getGradientDrawable().setColor(color);
}
}
/**
* Specifies radii for all corners.
*
* @param radius A radii for all corners, specified in pixels
*/
public void setCornerRadius(@Px int radius) {
setCornerRadius(radius, radius, radius, radius);
}
/**
* Specifies radii for each of the 4 corners.
*
* @param radiusTopLeft Top left radius, specified in pixels
* @param radiusTopRight Top right radius, specified in pixels
* @param radiusBottomRight Bottom right radius, specified in pixels
* @param radiusBottomLeft Bottom left radius, specified in pixels
*/
public void setCornerRadius(@Px int radiusTopLeft, @Px int radiusTopRight,
@Px int radiusBottomRight, @Px int radiusBottomLeft) {
getGradientDrawable().setCornerRadii(new float[]{
radiusTopLeft, radiusTopLeft,
radiusTopRight, radiusTopRight,
radiusBottomRight, radiusBottomRight,
radiusBottomLeft, radiusBottomLeft
});
}
/**
* Set the stroke width and color for the drawable. If width
* is zero, then no stroke is drawn. This method can also be used to dash the stroke.
*
* @param width The width in pixels of the stroke
* @param color The color of the stroke from a resource ID
* @param dashWidth The length in pixels of the dashes, set to 0 to disable dashes
* @param dashGap The gap in pixels between dashes
*/
public void setBorder(@Px int width, @ColorRes int color, @Px int dashWidth, @Px int dashGap) {
setBorderInternal(width, getColor(color), dashWidth, dashGap);
}
/**
* Set the stroke width and color for the drawable. If width
* is zero, then no stroke is drawn.
*
* @param width The width in pixels of the stroke
* @param color The color of the stroke from a resource ID
*/
public void setBorder(@Px int width, @ColorRes int color) {
setBorderInternal(width, getColor(color), 0, 0);
}
/**
* Set the stroke width and color for the drawable. If width
* is zero, then no stroke is drawn. This method can also be used to dash the stroke.
*
* @param width The width in pixels of the stroke
* @param colorAttrRes The color of the stroke from a attribute
* @param dashWidth The length in pixels of the dashes, set to 0 to disable dashes
* @param dashGap The gap in pixels between dashes
*/
public void setBorderAttr(@Px int width, @AttrRes int colorAttrRes, @Px int dashWidth, @Px int dashGap) {
setBorderInternal(width, getColorByAttr(colorAttrRes), dashWidth, dashGap);
}
/**
* Set the stroke width and color for the drawable. If width
* is zero, then no stroke is drawn.
*
* @param width The width in pixels of the stroke
* @param colorAttrRes The color of the stroke from a attribute
*/
public void setBorderAttr(@Px int width, @AttrRes int colorAttrRes) {
setBorderInternal(width, getColorByAttr(colorAttrRes), 0, 0);
}
/**
* Set the stroke width and color for the drawable. If width
* is zero, then no stroke is drawn. This method can also be used to dash the stroke.
*
* @param width The width in pixels of the stroke
* @param color The color of the stroke
* @param dashWidth The length in pixels of the dashes, set to 0 to disable dashes
* @param dashGap The gap in pixels between dashes
*/
public void setBorderInternal(@Px int width, @ColorInt int color, @Px int dashWidth, @Px int dashGap) {
if (isNotEmpty(width) && isNotEmpty(color)) {
getGradientDrawable().setStroke(width, color, dashWidth, dashGap);
}
}
/**
* Sets the Drawables (if any) to appear to the start of, above, to the end
* of, and below the text. Use 0 if you do not want a Drawable there. The
* Drawables' bounds will be set to their intrinsic bounds.
*
* @param start Resource identifier of the start Drawable.
* @param top Resource identifier of the top Drawable.
* @param end Resource identifier of the end Drawable.
* @param bottom Resource identifier of the bottom Drawable.
*/
public void setDrawables(@DrawableRes int start, @DrawableRes int top,
@DrawableRes int end, @DrawableRes int bottom) {
textView.setCompoundDrawablesRelativeWithIntrinsicBounds(start, top, end, bottom);
}
/**
* Sets the Drawables (if any) to appear to the start of, above, to the end
* of, and below the text. Use {@code null} if you do not want a Drawable
* there. The Drawables' bounds will be set to their intrinsic bounds.
* <p>
* Calling this method will overwrite any Drawables previously set using
*
* @param start Start Drawable.
* @param top Top Drawable.
* @param end End Drawable.
* @param bottom Bottom Drawable.
*/
public void setDrawables(@Nullable Drawable start, @Nullable Drawable top,
@Nullable Drawable end, @Nullable Drawable bottom) {
textView.setCompoundDrawablesRelativeWithIntrinsicBounds(start, top, end, bottom);
}
/**
* Set a color tint for Drawable
*
* @param color A color tint for Drawable from a resource ID
*/
public void setDrawableTint(@ColorRes int color) {
setDrawableTintInt(getColor(color));
}
/**
* Set a color tint for Drawable
*
* @param color A color tint for Drawable
*/
public void setDrawableTintInt(@ColorInt int color) {
if (isNotEmpty(color)) {
Drawable[] drawables = textView.getCompoundDrawablesRelative();
for (Drawable drawable : drawables) {
if (drawable != null) {
setDrawableTint(drawable, color);
}
}
}
}
/**
* Sets the size of the padding between the compound drawables
* and the text.
*
* @param pad Size of the padding in pixels.
*/
public void setCompoundDrawablePadding(@Px int pad) {
if (isNotEmpty(pad)) {
textView.setCompoundDrawablePadding(pad);
}
}
/**
* Sets the horizontal alignment of the text and the
* vertical gravity that will be used when there is extra space
* in the TextView beyond what is required for the text itself.
*
* @param gravity Gravity value
* @see android.view.Gravity
*/
public void setTextGravity(int gravity) {
if (isNotEmpty(gravity)) {
textView.setGravity(gravity);
}
}
/**
* Sets size and gravity for the progressBar
*
* @param size Size for the progressBar
* @param gravity Gravity for the progressBar
*/
public void setProgressBarLayoutParams(@Px int size, int gravity) {
FrameLayout.LayoutParams params;
if (size != -1) {
params = new FrameLayout.LayoutParams(size, size);
} else {
params = (LayoutParams) progressBar.getLayoutParams();
}
if (gravity != -1) {
params.gravity = gravity;
}
progressBar.setLayoutParams(params);
}
/**
* Set the text alignment.
*
* @param textAlignment The text alignment to set. Should be one of
* <p>
* {@link #TEXT_ALIGNMENT_INHERIT},
* {@link #TEXT_ALIGNMENT_GRAVITY},
* {@link #TEXT_ALIGNMENT_CENTER},
* {@link #TEXT_ALIGNMENT_TEXT_START},
* {@link #TEXT_ALIGNMENT_TEXT_END},
* {@link #TEXT_ALIGNMENT_VIEW_START},
* {@link #TEXT_ALIGNMENT_VIEW_END}
*/
@Override
public void setTextAlignment(int textAlignment) {
textView.setTextAlignment(textAlignment);
}
/**
* Sets text letter-spacing in em units. Typical values
* for slight expansion will be around 0.05. Negative values tighten text.
*
* @param letterSpacing A text letter-space value in ems.
*/
public void setLetterSpacing(float letterSpacing) {
if (isNotEmpty(letterSpacing)) {
textView.setLetterSpacing(letterSpacing);
}
}
/**
* Causes words in the text that are longer than the view's width
* to be ellipsized instead of broken in the middle.
* Use <code>null</code> to turn off ellipsizing.
* <p>
* If {@link #setMaxLines} has been used to set two or more lines,
* only {@link android.text.TextUtils.TruncateAt#END} and
* {@link android.text.TextUtils.TruncateAt#MARQUEE} are supported
* (other ellipsizing types will not do anything).
*
* @param where Value of a ellipsize
*/
public void setEllipsize(TextUtils.TruncateAt where) {
textView.setEllipsize(where);
}
/**
* Sets line spacing for this TextView. Each line other than the last line will have its height
* multiplied by {@code multi} and have {@code add} added to it.
*
* @param add The value in pixels that should be added to each line other than the last line.
* This will be applied after the multiplier
* @param multi The value by which each line height other than the last line will be multiplied
*/
public void setLineSpacing(float add, float multi) {
if (isNotEmpty(add) || isNotEmpty(multi)) {
if (add == -1) {
add = 0;
}
if (multi == -1) {
multi = 1;
}
textView.setLineSpacing(add, multi);
}
}
/**
* Sets the height of the TextView to be at most {@code maxHeight} tall.
* <p>
* This value is used for height calculation if LayoutParams does not force TextView to have an
* exact height. Setting this value overrides previous maximum height configurations such as
* {@link #setMaxLines(int)} or {@link #setLines(int)}.
*
* @param maxHeight The maximum height of TextView in terms of pixels
*/
public void setMaxHeight(@Px int maxHeight) {
if (isNotEmpty(maxHeight)) {
textView.setMaxHeight(maxHeight);
}
}
/**
* Sets the height of the TextView to be at least {@code minHeight} tall.
* <p>
* This value is used for height calculation if LayoutParams does not force TextView to have an
* exact height. Setting this value overrides previous minimum height configurations such as
* {@link #setMinLines(int)} or {@link #setLines(int)}.
* <p>
* The value given here is different than {@link #setMinimumHeight(int)}. Between
* {@code minHeight} and the value set in {@link #setMinimumHeight(int)}, the greater one is
* used to decide the final height.
*
* @param minHeight The minimum height of TextView in terms of pixels
*/
public void setMinHeight(@Px int minHeight) {
if (isNotEmpty(minHeight)) {
textView.setMinHeight(minHeight);
}
}
/**
* Sets the height of the TextView to be exactly <code>height</code> tall.
* <p>
* This value is used for height calculation if LayoutParams does not force TextView to have an
* exact height. Setting this value overrides previous minimum/maximum height configurations
* such as {@link #setMinHeight(int)} or {@link #setMaxHeight(int)}.
*
* @param height the exact height of the TextView in terms of pixels
* @see #setLines(int)
*/
public void setHeight(@Px int height) {
if (isNotEmpty(height)) {
textView.setHeight(height);
}
}
/**
* Sets the width of the TextView to be at least {@code minPixels} wide.
* <p>
* This value is used for width calculation if LayoutParams does not force TextView to have an
* exact width.
* <p>
* The value given here is different than {@link #setMinimumWidth(int)}. Between
* {@code minWidth} and the value set in {@link #setMinimumWidth(int)}, the greater one is used
* to decide the final width.
*
* @param minWidth the minimum width of TextView in terms of pixels
*/
public void setMinWidth(@Px int minWidth) {
if (isNotEmpty(minWidth)) {
textView.setMinWidth(minWidth);
}
}
/**
* Sets the width of the TextView to be at most {@code maxPixels} wide.
* <p>
* This value is used for width calculation if LayoutParams does not force TextView to have an
* exact width.
*
* @param maxWidth the maximum width of TextView in terms of pixels
*/
public void setMaxWidth(@Px int maxWidth) {
if (isNotEmpty(maxWidth)) {
textView.setMaxWidth(maxWidth);
}
}
/**
* Sets the width of the TextView to be exactly {@code pixels} wide.
* <p>
* This value is used for width calculation if LayoutParams does not force TextView to have an
* exact width. Setting this value overrides previous minimum/maximum width configurations
* such as {@link #setMinWidth(int)} or {@link #setMaxWidth(int)}.
*
* @param width the exact width of the TextView in terms of pixels
*/
public void setWidth(@Px int width) {
if (isNotEmpty(width)) {
textView.setWidth(width);
}
}
/**
* Sets the height of the TextView to be exactly {@code lines} tall.
* <p>
* This value is used for height calculation if LayoutParams does not force TextView to have an
* exact height. Setting this value overrides previous minimum/maximum height configurations
* such as {@link #setMinLines(int)} or {@link #setMaxLines(int)}. {@link #setSingleLine()} will
* set this value to 1.
*
* @param lines the exact height of the TextView in terms of lines
*/
public void setLines(int lines) {
if (isNotEmpty(lines)) {
textView.setLines(lines);
}
}
/**
* Sets the properties of this field (lines, horizontally scrolling,
* transformation method) to be for a single-line input.
*/
public void setSingleLine() {
textView.setSingleLine();
}
/**
* Sets the height of the TextView to be at most {@code maxLines} tall.
* <p>
* This value is used for height calculation if LayoutParams does not force TextView to have an
* exact height. Setting this value overrides previous maximum height configurations such as
* {@link #setMaxHeight(int)} or {@link #setLines(int)}.
*
* @param maxLines the maximum height of TextView in terms of number of lines
*/
public void setMaxLines(int maxLines) {
if (isNotEmpty(maxLines)) {
textView.setMaxLines(maxLines);
}
}
/**
* Sets the height of the TextView to be at least {@code minLines} tall.
* <p>
* This value is used for height calculation if LayoutParams does not force TextView to have an
* exact height. Setting this value overrides other previous minimum height configurations such
* as {@link #setMinHeight(int)} or {@link #setHeight(int)}.
*
* @param minLines the minimum height of TextView in terms of number of lines
*/
public void setMinLines(int minLines) {
if (isNotEmpty(minLines)) {
textView.setMinLines(minLines);
}
}
/**
* Sets the properties of this field to transform input to ALL CAPS
* display. This may use a "small caps" formatting if available.
* This setting will be ignored if this field is editable or selectable.
* <p>
* This call replaces the current transformation method. Disabling this
* will not necessarily restore the previous behavior from before this
* was enabled.
*/
public void setAllCaps(boolean allCaps) {
textView.setAllCaps(allCaps);
}
/**
* Sets the text to be displayed. TextView <em>does not</em> accept
* HTML-like formatting, which you can do with text strings in XML resource files.
* To style your strings, attach android.text.style.* objects to a
* {@link android.text.SpannableString}, or see the
* <a href="{@docRoot}guide/topics/resources/available-resources.html#stringresources">
* Available Resource Types</a> documentation for an example of setting
* formatted text in the XML resource file.
*
* @param text Text to be displayed
*/
public void setText(CharSequence text) {
textView.setText(text);
}
/**
* Sets the text to be displayed. TextView <em>does not</em> accept
* HTML-like formatting, which you can do with text strings in XML resource files.
* To style your strings, attach android.text.style.* objects to a
* {@link android.text.SpannableString}, or see the
* <a href="{@docRoot}guide/topics/resources/available-resources.html#stringresources">
* Available Resource Types</a> documentation for an example of setting
* formatted text in the XML resource file.
*
* @param textRes Text to be displayed from a resource ID
*/
public void setText(@StringRes int textRes) {
textView.setText(textRes);
}
/**
* Return the text that TextView is displaying. If {@link #setText(CharSequence)} was called
* with an argument of {@link android.widget.TextView.BufferType#SPANNABLE BufferType.SPANNABLE}
* or {@link android.widget.TextView.BufferType#EDITABLE BufferType.EDITABLE}, you can cast
* the return value from this method to Spannable or Editable, respectively.
*
* <p>The content of the return value should not be modified. If you want a modifiable one, you
* should make your own copy first.</p>
*
* @return The text displayed by the text view.
*/
public CharSequence getText() {
return textView.getText();
}
/**
* Sets the list of input filters that will be used if the buffer is
* Editable. Has no effect otherwise.
*
* @param filters The list of input filters
*/
public void setFilters(InputFilter[] filters) {
textView.setFilters(filters);
}
/**
* Sets the max length of the TextView.
*
* @param maxLength The max length of the TextView.
*/
public void setMaxLength(int maxLength) {
if (isNotEmpty(maxLength) && maxLength >= 0) {
setFilters(new InputFilter[]{new InputFilter.LengthFilter(maxLength)});
}
}
/**
* Returns the length, in characters, of the text managed by this TextView
*
* @return The length of the text managed by the TextView in characters.
*/
public int length() {
return textView.length();
}
@ColorInt
private int getColor(@ColorRes int colorRes) {
return ContextCompat.getColor(getContext(), colorRes);
}
@ColorInt
private int getColorByAttr(@AttrRes int colorAttrRes) {
TypedArray typedArray = getContext().obtainStyledAttributes(new TypedValue().data, new int[]{colorAttrRes});
int color = typedArray.getColor(0, 0);
typedArray.recycle();
return color;
}
private void setEllipsizeInternal(int truncateType) {
if (isNotEmpty(truncateType)) {
switch (truncateType) {
case 0:
setEllipsize(TextUtils.TruncateAt.START);
break;
case 1:
setEllipsize(TextUtils.TruncateAt.MIDDLE);
break;
case 2:
setEllipsize(TextUtils.TruncateAt.END);
break;
case 3:
setEllipsize(TextUtils.TruncateAt.MARQUEE);
break;
}
}
}
private void setDrawableTint(Drawable drawable, @ColorInt int color) {
DrawableCompat.setTint(DrawableCompat.wrap(drawable).mutate(), color);
}
private GradientDrawable getGradientDrawable() {
if (gradientDrawable == null) {
gradientDrawable = new GradientDrawable();
}
return gradientDrawable;
}
private boolean isNotEmpty(float index) {
return index != NO_INDEX;
}
private static class SavedState extends BaseSavedState {
private Bundle bundle;
private SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
bundle = in.readBundle(getClass().getClassLoader());
}
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeBundle(bundle);
}
static final Parcelable.Creator<SavedState> CREATOR
= new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<TextView
android:id="@+id/text_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:text="Hello World!"/>
<ProgressBar
android:id="@+id/progress"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:visibility="gone"
tools:visibility="visible"/>
</merge>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment