I have a Scrollview and I have the attribute android:clickable="true" and android:autoLink="all".
I have a string for the ScrollView, and the emails, tel numbers etc, appear and are correctly clickable.
However, The string contains other numbers, such as Years, which also appear clickable and I don't want this; how can I stop this from happening?
Don't use autoLink="all", use the ones you need.
android:autoLink="web|email|phone" will probably cover your use cases.
The clickable="true" on the ScrollView isn't needed for this; rather you should set the autoLink attribute on the TextViews themselves; perhaps extracting a style if you have other common properties.
Add the new Linkify class to your project. From a place that you have access to the TextView (e.g. the Activity):
TextView myTextView = // get a reference to your textview
int mask = Linkify.ALL;
Linkify.addLinks(myTextView, mask);
The addLinks(TextView, int) method is static, so you can use it without creating an instance of Linkify. The return value (boolean) indicates whether something was linkified, but you probably don't need this information, so we don't bother with it.
You'll need to ensure that you don't put the autoLink attribute on the TextViews, otherwise the setText(...) implementations will still linkify years (unless you completely override the setText(...) implementations without calling super.setText(...))
For extra brownie points, you can create a subclass of TextView which will do the linkify for you when you set text on it:
public class AutoLinkifyTextView extends TextView {
public AutoLinkifyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AutoLinkifyTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void setText(String text) {
super.setText(text);
parseLinks();
}
#Override
public void setText(int stringRes) {
super.setText(stringRes);
parseLinks();
}
private void parseLinks() {
Linkify.addLinks(this, Linkify.ALL);
}
}
For top marks of course, you'd read the attributes from the attrs and use the correct mask from the XML attributes, but I'd prefer to get rid of that option and do it here.
Related
I have a lot of views using one and the same color as a background. I want to change the color of all views when I receive a call from the server programmatically. I don't want to call for every view
view.setBackgroundColor(new color);
Is there a way to change a color code that is in colors.xml.
Short answer: No, you can't. The resources are defined at compile time.
See this question for a similar case: How can I programmatically change the value of a color in colors.xml?
You can't replace the value of the color in the xml file. But you
can create different themes which are used in your application and
change the theme dynamically
See this tutorial:
http://www.developer.com/ws/android/changing-your-android-apps-theme-dynamically.html
What I end up doing is create a custom class that sets the color form preference. And use this class everywhere I want to change the color. And next time the view is drawn it gets the new color. Something like this:
public class ColoredToolbar extends android.support.v7.widget.Toolbar {
public ColoredToolbar(Context context) {
super(context);
setBackgroundColor(context);
}
public ColoredToolbar(Context context, AttributeSet attrs) {
super(context, attrs);
setBackgroundColor(context);
}
public ColoredToolbar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setBackgroundColor(context);
}
private void setBackgroundColor(Context context) {
int color = PreferenceHelper.getToolBarColor(context, Preferences.PREF_TITLE_BAR_COLOR_KEY);
this.setBackgroundColor(color);
}
}
i have Helvetica Neue.ttf in asset Folder , How to set the Helvetica Neue textStyle on My Entire Applcation.
There is currently no way to do this with the Views that come with the Android SDK. You can set your View to use any of the Roboto fonts as per this answer, but you cannot set a custom font.
The way I typically tackle this problem is to create my own TextView that uses my font, like so:
public class MyFontTextView extends TextView {
public static final String FONT_PATH = "fonts/MyFont.ttf";
public MyFontTextView(Context context) {
super(context);
initFont();
}
public MyFontTextView(Context context, AttributeSet attrs) {
super(context, attrs);
initFont();
}
public MyFontTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initFont();
}
/**
* Set up the font.
*/
private void initFont() {
if (!isInEditMode()) {
Typeface font = Typeface.createFromAsset(getContext().getAssets(), FONT_PATH);
setTypeface(font);
}
}
}
You replace all of your TextViews with this TextView, and then you will have your font. Note that other UI elements (e.g. Buttons) will still use Roboto unless you also customize those.
If you have a View that you only use once in your application, you could call setTypeFace() on that View instead of creating a custom View. The custom View method works well for Views that you use a lot in an application such as TextViews.
I extended the class ImageView and added some custom parameters. I succeed to get these custom parameters from my code, using the method Context.getTheme().obtainStyledAttributes().
What I need is to access the standard parameters of the ImageView object, such as android:src and android:background. I know it exist the class android.R.styleable.* which I could use to get those parameters, but that class has been deprecated (and is not visible anymore). What can I do to access those android parameters?
While I’m not sure how to extract parent values from a TypedArray, you’re able to access them with appropriate getters, e.g.:
public class MyImageView extends ImageView {
public MyImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
final TypedArray array = getContext().obtainStyledAttributes(attrs, R.styleable.whatever);
try {
// get custom attributes here
} finally {
array.recycle();
}
// parent attributes
final Drawable background = getBackground();
final Drawable src = getDrawable();
// etc.
}
}
It's not exactly what you're looking for, but it might help.
How do I set up a constructor in a custom TextView to be able to pass text from a fragment?
In other words, I'm confused how to send text from my fragment (Fragment1) to the custom view (View1):
public class View1 extends TextView {
//constructors:
public View1(Context context, AttributeSet ats, int ds) {
super(context, ats, ds);
init();
}
public View1(Context context) {
super(context);
init();
}
public View1(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
...
canvas.drawText(myString, margin1, margin2, paint); //myString is from Fragment1
....
}
I asked a similar question here, but didn't really get much help. Example code would go a long way towards clearing up my confusion. Thanks in advance!
You are extending a TextView anyway. As A--C mentioned, you can use getText(), as well as setText() to get and set the text.
In your context, I am not sure if it is a good idea to use TextView to implement your custom view/widget. View might be a better starting point, as TextView carries all kind of stuff around for formatting, icon/drawable display, click/button logic etc.
You need to define the standard constructors if you want to be able to have the system instantiate/inflate your components from an XML layout. Then you can use standard getters/setters for your data, same way as all other controls do it.
If you instantiate your widget/view yourself (in your code), you are free to define whatever constructors you want to (I believe).
For instance:
This is foo text for wrapping text in TextView
The way that TextView wraps is:
This is foo text for
wrapping text in ...
I want this:
This is foo text for wr
apping text in TextView
It's a bit hacky, but you could replace spaces with the unicode no-break space character (U+00A0). This will cause your text to be treated as a single string and wrap on characters instead of words.
myString.replace(" ", "\u00A0");
As I know, there is no such property for TextView. If you want to implement text wrapping by yourself, you can override TextView and use Paint's breakText(String text, boolean measureForwards, float maxWidth, float[] measuredWidth) function. Note that you have to specify text size, typeface etc to Paint instance.
Add an invisible zero-width space ('\u200b') after each character:
textView.setText(longlongText.replaceAll(".(?!$)", "$0\u200b"));
This works also for long strings containing no spaces (for example, link addresses). Standard TextView tries to break a link by question mark '?' and slash '/'.
public class CharacterWrapTextView extends TextView {
public CharacterWrapTextView(Context context) {
super(context);
}
public CharacterWrapTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CharacterWrapTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override public void setText(CharSequence text, BufferType type) {
super.setText(text.toString().replace(" ", "\u00A0"), type);
}
}
<com.my.CharacterWrapTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text"/>
(yellow background: normal textview)
The following extension method implements #atarasenko's solution in C# which may be useful for people working with Xamarin.Android. The resultant string will wrap within a TextView character-by-character.
/// <summary>
/// Add zero-width spaces after each character. This is useful when breaking text by
/// character rather than word within a TextView.
/// </summary>
/// <param name="value">String to add zero-width spaces to.</param>
/// <returns>A new string instance containing zero-width spaces.</returns>
public static string AddZeroWidthSpaces(this string value) => Regex.Replace(
value
, "."
, "$0\u200b"
);