Im currently making a search engine like application for android and i want to highlight the searched word from edittext to textview... this is that i got so far and it only highlights the first word in the textview
TV.setText("Hello World", TextView.BufferType.SPANNABLE);
Spannable WordtoSpan = (Spannable) TV.getText();
WordtoSpan.setSpan(new BackgroundColorSpan(0xFFFFFF00), 0, notes.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
TV.setText(WordtoSpan);
I think you want to highlight a specific word of TextView which user types in a EditText.
Say et is your EditText and tv is TextView object. Use the following code:
String ett =et.getText().toString();
String tvt =tv.getText().toString();
int index = tvt.indexOf(ett);
Spannable WordtoSpan = new SpannableString( tv.getText() );
if(index != -1)
{
WordtoSpan.setSpan(new BackgroundColorSpan(0xFFFFFF00), index, index+ett.length(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
tv.setText(WordtoSpan, TextView.BufferType.SPANNABLE);
}
else
tv.setText("The name of our country is Bangladesh");
Here is the outcome:
Here is the complete code:
public class MotivationalQuotesActivity extends Activity {
/** Called when the activity is first created. */
Button next;
EditText et;
TextView tv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et = (EditText) findViewById(R.id.et);
tv = (TextView) findViewById(R.id.tv);
tv.setText("The name of our country is Bangladesh");
next = (Button) findViewById(R.id.button1);
next.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
String ett =et.getText().toString();
String tvt =tv.getText().toString();
int index = tvt.indexOf(ett);
Spannable WordtoSpan = new SpannableString( tv.getText() );
if(index != -1)
{
WordtoSpan.setSpan(new BackgroundColorSpan(0xFFFFFF00), index, index+ett.length(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
tv.setText(WordtoSpan, TextView.BufferType.SPANNABLE);
}
else
tv.setText("The name of our country is Bangladesh");
}
});
}
}
it could help
TextView tv = (TextView) findViewById(R.id.hello);
SpannableString s = new SpannableString(getResources().getString(R.string.linkify));
Pattern p = Pattern.compile("abc");
Matcher m = p.matcher(s);
while (m.find()) {
int start = m.start();
int end = m.end();
s.setSpan(new ForegroundColorSpan(Color.RED), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
tv.setText(s);
Related
I need to make all the occurrences of a bunch of words, that I have in my textview text clickable
Eg. - I have 2 names in my arraylist - Ajay and Dhananjay
and lets say text in my textview is ........
#Ajay, #Dhananjay, I just had a great fight with #Vijay yesterday
now, I need to highlight only #Ajay and #Dhananjay all occurences in my textview, and make them clickable as well
but not #Vijay (as its not in my arraylist)
How to do so?
I run this code and worked fine for me, check it:
public class MainActivity extends AppCompatActivity {
TextView text;
String string = "#Ajay, #Dhananjay, I just had a great fight with #Vijay yesterday";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.textView1);
SpannableString ss = new SpannableString(string);
String[] words = string.split(" ");
for (final String word : words) {
if (word.startsWith("#") && word.endsWith(",")) {
ClickableSpan clickableSpan = new ClickableSpan() {
#Override
public void onClick(View textView) {
//use word here to make a decision
}
};
ss.setSpan(clickableSpan, string.indexOf(word), string.indexOf(word) + word.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
text.setText(ss);
text.setMovementMethod(LinkMovementMethod.getInstance());
}
}
A few modifications in Survivor's Answer worked for me, as per my requirement.
text = (TextView) findViewById(R.id.textView1);
string += " ";
SpannableString ss = new SpannableString(string);
String[] words = string.split(" ");
for (final String word : words) {
if (word.startsWith("#") && mentionsNamesList.contains(word.substring(1))) {
int lastIndex = 0;
while(lastIndex != -1){
lastIndex = string.indexOf(word+" ",lastIndex);
if(lastIndex != -1){
ClickableSpan clickableSpan = new ClickableSpan() {
#Override
public void onClick(View textView) {
//use word here to make a decision
}
};
ss.setSpan(clickableSpan, lastIndex, lastIndex + word.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
lastIndex += word.length();
}
}
}
text.setText(ss);
text.setMovementMethod(LinkMovementMethod.getInstance());
The modifications done included the use of while loop in order to highlight and make clickable every occurrence of the word in the whole textview,instead of only the first one. The other one was adding space along with the word to highlight, in order to avoid highlighting the substring occurrence within a bigger word. For eg. test in test123
I'm working on ClickableSpan in a TextView, and I'm trying to get the clicked span's text. This is my code.
// this is the text we'll be operating on
SpannableString text = new SpannableString("Lorem ipsum dolor sit amet");
// make "dolor" (characters 12 to 17) display a toast message when touched
ClickableSpan clickableSpan = new ClickableSpan() {
#Override
public void onClick(View view) {
// This will get "Lorem ipsum dolor sit amet", but I just want "dolor"
String text = ((TextView) view).getText().toString();
Toast.makeText(context, text, Toast.LENGTH_LONG).show();
}
};
text.setSpan(clickableSpan, 12, 17, 0);
As you can see, I set the clickablespan to the TextView from characters 12 to 17, and I want to get these characters in the onClick event.
Is there anyway I can do that? Or at least can I pass the 12, 17 parameter to onClick event?
Thank you!
try this:
public class LoremIpsumSpan extends ClickableSpan {
#Override
public void onClick(View widget) {
// TODO add check if widget instanceof TextView
TextView tv = (TextView) widget;
// TODO add check if tv.getText() instanceof Spanned
Spanned s = (Spanned) tv.getText();
int start = s.getSpanStart(this);
int end = s.getSpanEnd(this);
Log.d(TAG, "onClick [" + s.subSequence(start, end) + "]");
}
}
A little simpler, could also pass a model reference if necessary.
public class SpecialClickableSpan extends ClickableSpan {
String text;
public SpecialClickableSpan(String text){
super();
this.text = text;
}
#Override
public void onClick(View widget) {
Log.d(TAG, "onClick [" + text + "]");
}
}
Then call new SpecialClickableSpan("My Text")
Edited: previous code was wrong, this works
// make "dolor" (characters 12 to 17) display a toast message when touched
ClickableSpan clickableSpan = new ClickableSpan() {
#Override
public void onClick(View view) {
TextView textView = (TextView) view;
CharSequence charSequence = textView.getText();
if (charSequence instanceof Spannable) {
Spannable spannableText = (Spannable)charSequence;
ClickableSpan[] spans = spannableText.getSpans(0, textView.length(), ClickableSpan.class);
for (ClickableSpan span : spans) {
int start = spannableText.getSpanStart(span);
int end = spannableText.getSpanEnd(span);
Toast.makeText(MainActivity.this, charSequence.subSequence(start, end), Toast.LENGTH_LONG).show();
}
}
}
};
You can also use to make string spannable like this
String htmlLinkText = "Lorem ipsum <a href='http://www.google.com'>dolor</a> sit amet";
testView.setText(Html.fromHtml(htmlLinkText));
testView.setMovementMethod(LinkMovementMethod.getInstance());
CharSequence text = testView.getText();
if (text instanceof Spannable) {
int end = text.length();
Spannable sp = (Spannable) testView.getText();
URLSpan[] urls = sp.getSpans(0, end, URLSpan.class);
SpannableStringBuilder style = new SpannableStringBuilder(text);
style.clearSpans();//should clear old spans
for (URLSpan url : urls) {
CustomerTextClick click = new CustomerTextClick(url.getURL());
style.setSpan(click, sp.getSpanStart(url), sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
testView.setText(style);
}
and CustomerTextClick will be
private static class CustomerTextClick extends ClickableSpan {
private String mUrl;
CustomerTextClick(String url) {
mUrl = url;
}
#Override
public void onClick(View widget) {
// TODO Auto-generated method stub
//Toast.makeText(ctx, "hello google!",Toast.LENGTH_LONG).show();
// Do your action here
}
}
Tested and working code.
Hello I want to know how to highlight all Words that is inputted in the EditText and will appear in the TextView this post is related to this one Highlight Textview Using EditText
Say et is your EditText and tv is TextView object. Use the following code:
public class MotivationalQuotesActivity extends Activity {
/** Called when the activity is first created. */
Button next;
EditText et;
TextView tv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et = (EditText) findViewById(R.id.et);
tv = (TextView) findViewById(R.id.tv);
tv.setText("The name of our country is Bangladesh. Bangladesh is a land of rivers.");
next = (Button) findViewById(R.id.button1);
next.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
tv.setText("The name of our country is Bangladesh. Bangladesh is a land of rivers.");
String ett =et.getText().toString();
String tvt =tv.getText().toString();
int ofe = tvt.indexOf(ett,0);
Spannable WordtoSpan = new SpannableString( tv.getText() );
for(int ofs=0;ofs<tvt.length() && ofe!=-1;ofs=ofe+1)
{
ofe = tvt.indexOf(ett,ofs);
if(ofe == -1)
break;
else
{
WordtoSpan.setSpan(new BackgroundColorSpan(0xFFFFFF00), ofe, ofe+ett.length(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
tv.setText(WordtoSpan, TextView.BufferType.SPANNABLE);
}
}
}
});
}
}
The result is:
One easy and quick way of highlighting a text, is to use string replace method. Replace the desire string with font tag
Spanned strHTML= Html.fromHtml("<center>"+full_string.replaceAll(strSrch,"<font color='yellow'>"+strSrch+"</font>")+"</center><br/>");
TextView tv=(TextView) v.findViewById(R.id.txtPager);
tv.setText(strHTML,TextView.BufferType.SPANNABLE);
I have one TextView. In this view I want to make it as some portion of text is clickable. if you click on that text then I want to open WebView.
I did the following way:
textView.setText(Html.fromHtml("I have read and agree to the " +
"<a href='id.web.freelancer.example.TCActivity://Kode'>TERMS AND CONDITIONS</a>"));
textView.setClickable(true);
textView.setMovementMethod(LinkMovementMethod.getInstance());
Here if you click on the TERMS AND CONDITIONS then it opens in the browser but I want to open it in the WebView.
Another way, borrows a bit from Linkify but allows you to customize your handling.
Custom Span Class:
public class ClickSpan extends ClickableSpan {
private OnClickListener mListener;
public ClickSpan(OnClickListener listener) {
mListener = listener;
}
#Override
public void onClick(View widget) {
if (mListener != null) mListener.onClick();
}
public interface OnClickListener {
void onClick();
}
}
Helper function:
public static void clickify(TextView view, final String clickableText,
final ClickSpan.OnClickListener listener) {
CharSequence text = view.getText();
String string = text.toString();
ClickSpan span = new ClickSpan(listener);
int start = string.indexOf(clickableText);
int end = start + clickableText.length();
if (start == -1) return;
if (text instanceof Spannable) {
((Spannable)text).setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
SpannableString s = SpannableString.valueOf(text);
s.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
view.setText(s);
}
MovementMethod m = view.getMovementMethod();
if ((m == null) || !(m instanceof LinkMovementMethod)) {
view.setMovementMethod(LinkMovementMethod.getInstance());
}
}
Usage:
clickify(textView, clickText,new ClickSpan.OnClickListener()
{
#Override
public void onClick() {
// do something
}
});
try this may it works
SpannableString span = new SpannableString(
"Click here to for gmail page.");
span.setSpan(new URLSpan("http://www.gmail.com"), 6, 10,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
TextView tv = (TextView) findViewById(R.id.text);
tv.setText(span);
tv.setMovementMethod(LinkMovementMethod.getInstance());
change start and end position according to your text size
How do I make links in a TextView clickable?
or u can create a linear layout with horizontal orientation having 2 textviews making second textview clickable..
Why don't you make the textView call on onClick method:
<TextView
...
android:onClick"openWebView"
...
/>
And then just have a method in your activity called:
public void openWebView (View v) {
....
// Do something
}
I have TextView with text that changed dynamically. This text contain strings like <a href='myWord'>myWord</a>. I want that after click to this "link" myWord appear in the EditText in the same activity.
This is my code:
txt.setText(Html.fromHtml("...<a href='link'>link</a>..."));
txt.setMovementMethod(LinkMovementMethod.getInstance());
It's work well for URLs inside href attribute, but there is an error for another format.
I found a lot of similar questions on the StackOverflow but all of them were about url links. In my app I want create "link" inside activity.
In general, I can change tag to some another if it's depend...
Please help me!
Thank you!
-----SOLVED-----
Thank you Jacob Phillips for idea!
May it will be interesting someone in future.
This is a code:
//This is my string;
String str = "<b>Text</b> which contains one <a href='#'>link</a> and another <a href='#'>link</a>";
//TextView;
TextView txt = new TextView(this);
//Split string to parts:
String[] devFull = data[v.getId()][1].split("<a href='#'>");
//Adding first part:
txt.append(Html.fromHtml(devFull[0]));
//Creating array for parts with links (they amount always will devFull.length-1):
SpannableString[] link = new SpannableString[devFull.length-1];
//local vars:
ClickableSpan[] cs = new ClickableSpan[devFull.length-1];
String linkWord;
String[] devDevFull = new String[2];
for(int i=1; i<devFull.length; i++){
//obtaining 'clear' link
devDevFull = devFull[i].split("</a>");
link[i-1] = new SpannableString(devDevFull[0]);
linkWord = devDevFull[0];
cs[i-1] = new ClickableSpan(){
private String w = linkWord;
#Override
public void onClick(View widget) {
// here you can use w (linkWord)
}
};
link[i-1].setSpan(cs[i-1], 0, linkWord.length(), 0);
txt.append(link[i-1]);
try{
txt.append(Html.fromHtml(devDevFull[1]));
}
catch(Exception e){}
}
This should do the trick. Just change your edittext's text in the OnClickListener. It may be able to be reduced but this should work.
private void foo() {
SpannableString link = makeLinkSpan("click here", new View.OnClickListener() {
#Override
public void onClick(View v) {
// respond to click
}
});
// We need a TextView instance.
TextView tv = new TextView(context);
// Set the TextView's text
tv.setText("To perform action, ");
// Append the link we created above using a function defined below.
tv.append(link);
// Append a period (this will not be a link).
tv.append(".");
// This line makes the link clickable!
makeLinksFocusable(tv);
}
/*
* Methods used above.
*/
private SpannableString makeLinkSpan(CharSequence text, View.OnClickListener listener) {
SpannableString link = new SpannableString(text);
link.setSpan(new ClickableString(listener), 0, text.length(),
SpannableString.SPAN_INCLUSIVE_EXCLUSIVE);
return link;
}
private void makeLinksFocusable(TextView tv) {
MovementMethod m = tv.getMovementMethod();
if ((m == null) || !(m instanceof LinkMovementMethod)) {
if (tv.getLinksClickable()) {
tv.setMovementMethod(LinkMovementMethod.getInstance());
}
}
}
/*
* ClickableString class
*/
private static class ClickableString extends ClickableSpan {
private View.OnClickListener mListener;
public ClickableString(View.OnClickListener listener) {
mListener = listener;
}
#Override
public void onClick(View v) {
mListener.onClick(v);
}
}
Better approach is
SpannableString ss = new SpannableString("Android is a Software stack");
ClickableSpan clickableSpan = new ClickableSpan() {
#Override
public void onClick(View textView) {
startActivity(new Intent(MyActivity.this, NextActivity.class));
}
};
ss.setSpan(clickableSpan, 22, 27, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//where 22 and 27 are the starting and ending index of the String. Now word stack is clickable
// onClicking stack it will open NextActiivty
TextView textView = (TextView) findViewById(R.id.hello);
textView.setText(ss);
textView.setMovementMethod(LinkMovementMethod.getInstance());
You can use below code;
SpannableString myString = new SpannableString(Html.fromHtml("Please "+"<font color=\"#F15d36\"><u>"+"login"+"</u></font>" +" or "+ "<font color=\"#F15d36\"><u>"+"sign up"+ "</u></font>"+" to begin your YupIT experience"));
ClickableSpan clickableSpan = new ClickableSpan() {
#Override
public void onClick(View textView) {
Toast.makeText(getContext(),"dfsgvdfs",Toast.LENGTH_SHORT).show();
}
};
ClickableSpan clickableSpan1 = new ClickableSpan() {
#Override
public void onClick(View textView) {
Toast.makeText(getContext(),"dfsgvdfs",Toast.LENGTH_SHORT).show();
}
};
myString.setSpan(clickableSpan,6,12,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
myString.setSpan(clickableSpan1,15,23,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
myString.setSpan(new ForegroundColorSpan(Color.parseColor("#F15d36")),6, 12, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
myString.setSpan(new ForegroundColorSpan(Color.parseColor("#F15d36")),15,23, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
tvFound.setMovementMethod(LinkMovementMethod.getInstance());
tvFound.setText(myString);
The best workaround I know is to create your own Button class. You could make the Button have a transparent background so that only the text is seen by the user. Then when the Button is pressed down change the TextColor and TextStyle of the button to be a darker color and underlined. This will work exactly as a link does. You can then use startActivity to go to the appropriated activity. You should not use hyperlinks to connect to other activities within your application.
My personal opinion would be to make a second textview containing the text that you want to be your link. Then you could do your action in the onClick of this second textView . Also as zzzzzzzzzzz stated above, you could choose to change the font properties of that text to whatever you want once it has been clicked.
To make it full answer with mixing answers;
private void textAreaInit()
{
String str = "<a href='#'>Link 1</a> and <a href='#'>Link2</a> is here.";
TextView tv = mConfirmText;
String[] devFull = str.split("<a href='#'>");
tv.append(Html.fromHtml(devFull[0]));
SpannableString[] link = new SpannableString[devFull.length-1];
ClickableSpan[] cs = new ClickableSpan[devFull.length-1];
String linkWord;
String[] devDevFull = new String[2];
for(int i=1; i<devFull.length; i++)
{
//obtaining 'clear' link
devDevFull = devFull[i].split("</a>");
link[i-1] = new SpannableString(devDevFull[0]);
linkWord = devDevFull[0];
final String a = linkWord;
cs[i-1] = new ClickableSpan()
{
private String w = a;
#Override
public void onClick(View widget) {
if(w.equals("Link 1"))
{
Intent intent = new Intent(PrintPropertiesActivity.this, ViewerAcivity.class);
intent.putExtra("title", "Link1");
intent.putExtra("uri", "link1");
intent.putExtra("type", "1");
startActivity(intent);
}
else
{
Intent intent = new Intent(PrintPropertiesActivity.this, ViewerAcivity.class);
intent.putExtra("title", "Link2");
intent.putExtra("uri", "link2");
intent.putExtra("type", "2");
startActivity(intent);
}
}
};
link[i-1].setSpan(cs[i-1], 0, linkWord.length(), 0);
tv.append(link[i-1]);
try{
tv.append(Html.fromHtml(devDevFull[1]));
}
catch(Exception e){}
}
makeLinksFocusable(tv);
}
private void makeLinksFocusable(TextView tv) {
MovementMethod m = tv.getMovementMethod();
if ((m == null) || !(m instanceof LinkMovementMethod)) {
if (tv.getLinksClickable()) {
tv.setMovementMethod(LinkMovementMethod.getInstance());
}
}
}