I have a function to build clickable tags for a textview. It goes as follows:
private CharSequence tagsBuilder(String text, String token) {
SpannableStringBuilder builtTags = new SpannableStringBuilder();
int start = 0, end = 0;
for(int i = 0; i < 5; i++) {
start = 0;
end = text.indexOf(token, 0);
try {
if(start < end) {
SpannableStringBuilder ssb = new SpannableStringBuilder(text.substring(start, end));
ssb.setSpan(new ClickableSpan() {
#Override
public void onClick(View v)
{
Log.i("DEBUGTAG", "Span clicked - " + ((TextView) v).getText());
}
}, start, end, 0);
builtTags.append(ssb);
builtTags.append(" ");
text = text.substring(end + 1);
}
} catch (IndexOutOfBoundsException e) {
break;
}
}
return builtTags;
}
I can see the textview with 5 individually clickable tags. But the problem is, the Log that prints for any tag that is clicked is whole text of the textview.
Am I doing something wrong here? How do I get the text of individual tags that were clicked.
Your log line is the following:
Log.i("DEBUGTAG", "Span clicked - " + ((TextView) v).getText());
That logs the contents of the TextView. So... you get the text of the TextView. If you want to get token in there, you'll have to copy that in.
Here's something you can try:
private CharSequence tagsBuilder(String text, final String token) {
SpannableStringBuilder builtTags = new SpannableStringBuilder();
int start = 0, end = 0;
for(int i = 0; i < 5; i++) {
start = 0;
end = text.indexOf(token, 0);
try {
if(start < end) {
SpannableStringBuilder ssb = new SpannableStringBuilder(text.substring(start, end));
ssb.setSpan(new ClickableSpan() {
private String mText = token;
#Override
public void onClick(View v)
{
Log.i("DEBUGTAG", "Span clicked - " + mText);
}
}, start, end, 0);
builtTags.append(ssb);
builtTags.append(" ");
text = text.substring(end + 1);
}
} catch (IndexOutOfBoundsException e) {
break;
}
}
return builtTags;
}
Related
I have an activity where credit/debit card details is added. Currently my code allows to add date and month in MM/YY format. But i need year in 4 digits format MM/YYYY. Adding the '/' divider is set after 2nd digit. So if i increase my total digits count, i get the divider after every 2nd digit. How to fix this?
Carddetails.java:
public class CardDetailsActivity extends AppCompatActivity implements TextWatcher {
private static final int CARD_NUMBER_TOTAL_SYMBOLS = 19; // size of pattern 0000-0000-0000-0000
private static final int CARD_NUMBER_TOTAL_DIGITS = 16; // max numbers of digits in pattern: 0000 x walknew2
private static final int CARD_NUMBER_DIVIDER_MODULO = 5; // means divider position is every 5th symbol beginning with walknew4
private static final int CARD_NUMBER_DIVIDER_POSITION = CARD_NUMBER_DIVIDER_MODULO - 1; // means divider position is every 4th symbol beginning with 0
private static final char CARD_NUMBER_DIVIDER = '-';
#BindView(R.id.cardno)
EditText cardno;
#BindView(R.id.cardDateEditText)
EditText cardDateEditText;
#BindView(R.id.cardCVCEditText)
EditText cardCVCEditText;
SharedPreferences pref;
SharedPreferences.Editor editor;
private static final int CARD_DATE_TOTAL_SYMBOLS = 7; // size of pattern MM/YY
private static final int CARD_DATE_TOTAL_DIGITS = 6; // max numbers of digits in pattern: MM + YY
private static final int CARD_DATE_DIVIDER_MODULO = 3; // means divider position is every 3rd symbol beginning with walknew4
private static final int CARD_DATE_DIVIDER_POSITION = CARD_DATE_DIVIDER_MODULO - 1; // means divider position is every 2nd symbol beginning with 0
private static final char CARD_DATE_DIVIDER = '/';
private static final int CARD_CVC_TOTAL_SYMBOLS = 3;
String card_date, card_year, card_month, card_cvv, card_num, user_id, card_type = "debitcard";
#BindView(R.id.btn_add_card)
Button btn_add_card;
#BindView(R.id.btn_back)
Button btn_back;
Context context;
ProgressDialog progressDialog;
ApiService apiService;
String driverid, id, usertype, c_id, booking_id;
EditText card_numm, card_yearm, card_cvvm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_card_details);
ButterKnife.bind(this);
context = CardDetailsActivity.this;
Log.e("TAG", "Inside Card Details Activity:");
apiService = RetrofitSingleton.getApiService();
usertype = PrefConnect.readString(CardDetailsActivity.this, PrefConnect.USERTYPE, "");
pref = getApplicationContext().getSharedPreferences("MyPref", 0);
editor = pref.edit();
id = pref.getString("driver_id", "");
Log.e("driver_id", id);
try {
if (getIntent() != null) {
driverid = getIntent().getStringExtra("Driverid");
booking_id = getIntent().getStringExtra("bookingid");
}
} catch (Exception e) {
e.printStackTrace();
Log.e("paymentact", e.getMessage());
}
cardno.getText().toString().trim();
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
cardno.addTextChangedListener(this);
cardDateEditText.addTextChangedListener(this);
card_numm = (EditText) findViewById(R.id.cardno);
card_yearm = (EditText) findViewById(R.id.cardDateEditText);
card_cvvm = (EditText) findViewById(R.id.cardCVCEditText);
}
#OnClick({R.id.btn_add_card, R.id.btn_back})
public void OnClick(View view) {
switch (view.getId()) {
case R.id.btn_back:
finish();
break;
case R.id.btn_add_card:
View view1 = getCurrentFocus();
Log.e("TAG", "Inside Card Details Activity Button Add Card ");
Validation();
break;
}
}
private boolean isInputCorrect(Editable s, int size, int dividerPosition, char divider) {
boolean isCorrect = s.length() <= size;
for (int i = 0; i < s.length(); i++) {
if (i > 0 && (i + 1) % dividerPosition == 0) {
isCorrect &= divider == s.charAt(i);
} else {
isCorrect &= Character.isDigit(s.charAt(i));
}
}
return isCorrect;
}
private String concatString(char[] digits, int dividerPosition, char divider) {
final StringBuilder formatted = new StringBuilder();
for (int i = 0; i < digits.length; i++) {
if (digits[i] != 0) {
formatted.append(digits[i]);
if ((i > 0) && (i < (digits.length - 1)) && (((i + 1) % dividerPosition) == 0)) {
formatted.append(divider);
}
}
}
return formatted.toString();
}
private char[] getDigitArray(final Editable s, final int size) {
char[] digits = new char[size];
int index = 0;
for (int i = 0; i < s.length() && index < size; i++) {
char current = s.charAt(i);
if (Character.isDigit(current)) {
digits[index] = current;
index++;
}
}
return digits;
}
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable s) {
card_num = String.valueOf(s);
Log.i("TAG", "Card Date:" + s);
Log.i("TAG", "Card Date :" + cardDateEditText.getEditableText());
if (s == cardno.getEditableText()) {
if (!isInputCorrect(s, CARD_NUMBER_TOTAL_SYMBOLS, CARD_NUMBER_DIVIDER_MODULO, CARD_NUMBER_DIVIDER)) {
s.replace(0, s.length(), concatString(getDigitArray(s, CARD_NUMBER_TOTAL_DIGITS), CARD_NUMBER_DIVIDER_POSITION, CARD_NUMBER_DIVIDER));
}
// DO STH
} else if (s == cardDateEditText.getEditableText()) {
if (!isInputCorrect(s, CARD_DATE_TOTAL_SYMBOLS, CARD_DATE_DIVIDER_MODULO, CARD_DATE_DIVIDER)) {
s.replace(0, s.length(), concatString(getDigitArray(s, CARD_DATE_TOTAL_DIGITS), CARD_DATE_DIVIDER_POSITION, CARD_DATE_DIVIDER));
} else if (s == cardCVCEditText.getEditableText()) {
if (s.length() > CARD_CVC_TOTAL_SYMBOLS) {
s.delete(CARD_CVC_TOTAL_SYMBOLS, s.length());
}
}
}
}
}
As by my understanding, your date divider must always be at position 2
private static final int CARD_DATE_DIVIDER_POSITION = CARD_DATE_DIVIDER_MODULO - 1; // means divider position is every 2nd symbol beginning with 0
with the above declaration, before appending the date divider, I should test this way ( you can change your isInputCorrect method this way):
private boolean isInputCorrect(Editable s, int size, int dividerPosition, char divider) {
boolean isCorrect = s.length() <= size;
for (int i = 0; i < s.length(); i++) {
if (i > 0 && (i + 1) % dividerPosition == 0) {
if (divider=='/') {
if (i==2) {
isCorrect &= divider == s.charAt(i);
}
}
} else {
isCorrect &= Character.isDigit(s.charAt(i));
}
}
return isCorrect;
}
And then after the text has changed can be modified a bit to become:
#Override
public void afterTextChanged(Editable s) {
card_num = String.valueOf(s);
String ss=cardDateEditText.getText().toString();
Log.i("TAG", "Card Date:" + s);
Log.i("TAG", "Card Date :" + ss);
if (s == cardno.getEditableText()) {
if (!isInputCorrect(s, CARD_NUMBER_TOTAL_SYMBOLS, CARD_NUMBER_DIVIDER_MODULO, CARD_NUMBER_DIVIDER)) {
s.replace(0, s.length(), concatString(getDigitArray(s, CARD_NUMBER_TOTAL_DIGITS), CARD_NUMBER_DIVIDER_POSITION, CARD_NUMBER_DIVIDER));
}
} else if (s == cardDateEditText.getEditableText()) {
if (s.length()<=CARD_DATE_TOTAL_SYMBOLS)
{
if (!isInputCorrect(s, CARD_DATE_TOTAL_SYMBOLS, CARD_DATE_DIVIDER_MODULO, CARD_DATE_DIVIDER)) {
Log.e("TAG",s+"");
s.replace(0, s.length(), concatString(getDigitArray(s, CARD_DATE_TOTAL_DIGITS), CARD_DATE_DIVIDER_POSITION, CARD_DATE_DIVIDER));
}
}else
{
s.delete(CARD_DATE_TOTAL_SYMBOLS,s.length());
}
} else if (s == cardCVCEditText.getEditableText()) {
if (s.length() > CARD_CVC_TOTAL_SYMBOLS) {
s.delete(CARD_CVC_TOTAL_SYMBOLS, s.length());
}
}
}
So you test also the length of the editable text.
The date divider must be included only once and just after the month represented by two first characters. That means the last digit must be at 2nd position index 1, at that instant i==1. So no other divider will be appended. I should have to test if the divider set is for date, to know I'm dealing with the date and then test if the index is not greater or equals to 2.
That's how I could handle that. I hope this will help.
I have an edit text while typing inside edit text if the word starts with # that particular words color should change ,
i have implemented textwatcher and found that if text starts with # but do not know how to update the color dynamically ,
Have tried SpannableStringBuilder ssb = new SpannableStringBuilder(yourText) But its static , could anyone help me for dynamic implementation
Here is my code
myEditTxt.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence text, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence text, int start, int before, int count) {
if (text.charAt(start) == '#') {
//here i needs to update the typing text color
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
As implemented in this link How to change color of words with hashtags #Muhammed GÜNEŞ suggested
you can modify it according to follow
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
textView.removeTextChangedListener(this);
setTags(textView,s.toString());
textView.setSelection(textView.getText().toString().length());
textView.addTextChangedListener(this);
}
private void setTags(TextView pTextView, String pTagString) {
SpannableString string = new SpannableString(pTagString);
int start = -1;
for (int i = 0; i < pTagString.length(); i++) {
if (pTagString.charAt(i) == '#') {
start = i;
} else if (pTagString.charAt(i) == ' ' || (i == pTagString.length() - 1 && start != -1)) {
if (start != -1) {
if (i == pTagString.length() - 1) {
i++; // case for if hash is last word and there is no
// space after word
}
final String tag = pTagString.substring(start, i);
string.setSpan(new ClickableSpan() {
#Override
public void onClick(View widget) {
Toast.makeText(MainActivity.this,"Click",Toast.LENGTH_LONG).show();
}
#Override
public void updateDrawState(TextPaint ds) {
// link color
ds.setColor(Color.parseColor("#33b5e5"));
ds.setUnderlineText(false);
}
}, start, i, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
start = -1;
}
}
}
pTextView.setMovementMethod(LinkMovementMethod.getInstance());
pTextView.setText(string);
}
it will add color and click event too also u can modify it according o your further requirement
Maybe something like this
#Override
public void onTextChanged(CharSequence text, int start, int before, int count) {
if (text.charAt(start) == '#') {
SpannableString spannableString = new SpannableString(editText.getText().toString());
ForegroundColorSpan foregroundSpan = new ForegroundColorSpan(ContextCompat.getColor(getContext(), R.color.yourColor));
spannableString.setSpan(foregroundSpan, start,
spannableString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
editText.setText(spannableString);
}
}
If you only want to change "#" char. You can try it:
int index = myEditTxt.getText().toString().indexOf("#");
if (index != -1) {
SpannableString spannable = new
SpannableString(myEditTxt.getText().toString());
ForegroundColorSpan fcs = new ForegroundColorSpan(color);
// Set the text color
spannable.setSpan(fcs, index, index + 1,
Spannable.SPAN_INCLUSIVE_INCLUSIVE);
mEditText.setText(spannable);
}
If you only want to change after and before "#". You can try it in your listener:
if (text.charAt(start) == '#') {
SpannableString spannable = new
SpannableString(myEditTxt.getText().toString());
ForegroundColorSpan fcs = new ForegroundColorSpan(color);
// Set the text color
if (start > 0)
spannable.setSpan(fcs, 0, start -1,
Spannable.SPAN_INCLUSIVE_INCLUSIVE);
if (start < myEditTxt.getText().toString().length())
spannable.setSpan(fcs, start + 1, myEditTxt.getText().toString().length(),
Spannable.SPAN_INCLUSIVE_INCLUSIVE);
mEditText.setText(spannable);
}
Finally found an answer and works as expected .
private int intCount = 0, initialStringLength = 0;
private String strText = "";
on text changed
#Override
public void onTextChanged(CharSequence text, int start, int before, int count) {
String strET = editText.getText().toString();
String[] str = strET.split(" ");
int cnt = 0;
if (text.length() != initialStringLength && text.length() != 0) {
if (!strET.substring(strET.length() - 1).equals(" ")) {
initialStringLength = text.length();
cnt = intCount;
for (int i = 0; i < str.length; i++)
if (str[i].charAt(0) == '#')
strText = strText + " " + "<font color='#EE0000'>" + str[i] + "</font>";
else
strText = strText + " " + str[i];
}
if (intCount == cnt) {
intCount = str.length;
editText.setText(Html.fromHtml(strText));
editText.setSelection(textShareMemories.getText().toString().length());
}
} else {
strText = "";
}
}
i have button,on button click it create editText with value, value of edit text is depending on count of total edit texts.for example edittext1 = 100, when user create two edit text then the value will be like this edittext1 = 50,edittext2 = 50 and so on.( value = 100/ total no of edittext) which i set equally to each edit text.now the problem is when user want to change/update any value from edittext, i want to update value of each edittext according to user's newly entered value.
i want to call textwatcher when value changed by only user,in my case when user click on button it will call.
thank you.
here is my code
public class StageForm extends BaseActivity implements View.OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.stage_form);
spinnerProjectStage = (Spinner) findViewById(R.id.spinnerAddProjectStage);
spinnerProjectList = (Spinner) findViewById(R.id.spinnerProjectList);
stageLinearLayout = (LinearLayout) findViewById(R.id.stageProjectList);
btnAddMoreStage = (Button) findViewById(R.id.btnAddMoreStage);
btnAddMoreStage.setOnClickListener(this);
getProjectStage();
}
public void onClick(View v) {
if (v.getId() == R.id.btnAddMoreStage) {
public void addMoreFields () {
try {
k++;
flag = k;
final LinearLayout.LayoutParams lparams;
lparams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layout[flag] = new LinearLayout(StageForm.this);
layout[flag].setLayoutParams(lparams);
layout[flag].setId(flag);
txtStageName[flag] = new EditText(StageForm.this);
txtStageName[flag].setLayoutParams(lparams);
txtStageName[flag].setHint("stage " + k + "");
txtStageName[flag].setId(flag);
txtStagePercent[flag] = new EditText(StageForm.this);
txtStagePercent[flag].setLayoutParams(lparams);
txtStagePercent[flag].setHint("percent");
txtStagePercent[flag].setId(flag);
txtStagePercent[flag].addTextChangedListener(stagePercentChangeListener);
if (flag == 0) {
txtStagePercent[flag].setText(String.valueOf(totalPercent));
} else {
countEditText = flag + 1;
calculatePercentage(countEditText, flag);
}
} catch (Exception e) {
e.printStackTrace();
}
layout[flag].addView(txtStageName[flag]);
layout[flag].addView(txtStagePercent[flag]);
stageLinearLayout.addView(layout[flag]);
}
}
}
private void calculatePercentage(int countEditText, int flag) {
k = flag;
if (flag == 0) {
// countEditText = flag;
lastTextBox = countEditText;
} else {
// countEditText = flag;
lastTextBox = countEditText - 1;
}
result = totalPercent / countEditText;
convertFloatResult = Math.round(result);
remainingPercent = totalPercent - (convertFloatResult * countEditText);
lastTextValue = convertFloatResult + remainingPercent;
try {
if (remainingPercent == 0) {
for (int j = 0; j <= lastTextBox; j++) {
txtStagePercent[j].setText(String.valueOf(convertFloatResult));
}
txtStagePercent[lastTextBox].setText(String.valueOf(lastTextValue));
} else {
for (int j = 0; j < lastTextBox; j++) {
txtStagePercent[j].setText(String.valueOf(convertFloatResult));
}
txtStagePercent[lastTextBox].setText(String.valueOf(lastTextValue));
}
} catch (Exception e) {
e.printStackTrace();
}
}
private TextWatcher stagePercentChangeListener = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if (flag == 0) {
} else {
String getbeforValue = String.valueOf(s);
beforeTextChanged = Integer.parseInt(getbeforValue);
}
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String getchangedValue = String.valueOf(s);
afterTextChanged = Integer.parseInt(getchangedValue);
}
#Override
public void afterTextChanged(Editable s) {
totalPercent = totalPercent - afterTextChanged;
countEditText = countEditText - 1;
calculatePercentage(countEditText, flag);
}
};
}
I have here code where it highlights all the words inside the TextView which is equal to the typed string. By pressing the buttons next/previous, It highlights the current word found.
What I'm trying to do is to go to the position of that word currently being highlighted.
I've added this code inside my onClick
myScroll.scrollBy(0, +20);
But it doesn't seem to be what im looking for
Also I've tried something like this
myScroll.scrollTo(0, selected); // getting the index of the highlighted word
// but it's not working
onClickListener to highlight next word
findViewById(R.id.next).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selected++;
String text = ((EditText) findViewById(R.id.editText)).getText().toString();
if(text.equals("") {}
else
selected = changeTextView(details, text, selected);
}
});
method to highlight the text
private int changeTextView(TextView tv, String target, int selected) {
if(selected < 0 ) {
selected = 0;
}
String bString = (String) tv.getText().toString();
int startSpan = 0, endSPan = 0;
Spannable spanRange = new SpannableString(bString);
int currentIndex = 0;
while(true) {
startSpan = bString.indexOf(target, endSpan);
endSpan = startSpan + target.lenght();
boolean isLast = bString.indexOf(target, endSpan) < 0;
if(startSpan < 0)
break;
ParcelableSpan span;
if(currentIndex == selected || isLast && selected > currentIndex) {
span = new BackgroundColorSpan(Color.LTGRAY);
if(isLast && selected > currentIndex) {
selected = currentIndex;
}
} else {
span = new BackgroundColorSpan(Color.YELLOW);
}
currentIndex++;
spanRange.setSpan(
span,
startSpan,
endSpan,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
tv.setText(spanRange);
if(currentIndex == 0) {
return -1;
} else {
return selected;
}
}
Based on the answer given on this post,
Android - Expandable TextView with Animation
I want to be able to use my function
`
holder.expandableTextView.setText(wallContent);
SpannableStringBuilder ssb = SharefolioSpannableHandler.getSpannableStringBuilder(context, wallContent, currentWall.personTagged, currentWall.companyTagged);
holder.expandableTextView.setMovementMethod(LinkMovementMethod.getInstance());
holder.expandableTextView.setText(ssb);
`
This is SharefolioSpannableHandler class
`
public class SharefolioSpannableHandler {
public static SpannableStringBuilder getSpannableStringBuilder(final Context context, String text, List<Account> persons, List<Company> companies) {
SpannableStringBuilder ssb = new SpannableStringBuilder(text);
if (persons.size() != 0) {
for (int i = 0; i < persons.size(); i++) {
final Account person = persons.get(i);
final String personName = persons.get(i).firstname;
if (text.contains(personName)) {
int start = text.indexOf(personName) - 1;
int end = start + personName.length() + 1;
ssb.setSpan(new StyleSpan(Typeface.BOLD), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.setSpan(new ForegroundColorSpan(Color.BLUE), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.setSpan(new ClickableSpan() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(context, LoadUserWallActivity.class);
intent.putExtra(LoadUserWallActivity.TAG, person);
context.startActivity(intent);
}
}, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
if (companies.size() != 0) {
for (int i = 0 ; i < companies.size() ; i++) {
final Company company = companies.get(i);
final String companyCode = companies.get(i).companyCode;
if (text.contains(companyCode)) {
int start = text.indexOf(companyCode) - 1;
int end = start + companyCode.length() + 1;
ssb.setSpan(new StyleSpan(Typeface.BOLD), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.setSpan(new ForegroundColorSpan(Color.BLUE), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.setSpan(new ClickableSpan() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, CompanyActivity.class);
Bundle b = new Bundle();
b.putSerializable("company", company);
intent.putExtras(b);
context.startActivity(intent);
}
}, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
return ssb;
}
}
`
I am currently having some issues as the ExpendableTextView which is a holder already has a setText but how to include the StringBuilder function is giving me problems. If i run as shown above, while it does create the Expandable TextView, it doesnt peform what should be done by the StringBuilder in terms of links or tags.
Does anyone have any clue on how to join both functions together?
Thanks
Kingsley
I found out my issue. I just needed to return the output of my StringBuilder in my ExpendableTextView so instead of this
holder.expandableTextView.setText(wallContent);
SpannableStringBuilder ssb = SharefolioSpannableHandler.getSpannableStringBuilder(context, wallContent, currentWall.personTagged, currentWall.companyTagged);
holder.expandableTextView.setMovementMethod(LinkMovementMethod.getInstance());
holder.expandableTextView.setText(ssb);
I did this
holder.expandableTextView.setText(wallContent);
holder.expandableTextView.setMovementMethod(LinkMovementMethod.getInstance());
holder.expandableTextView.setText(SharefolioSpannableHandler.getSpannableStringBuilder(context, wallContent, currentWall.personTagged, currentWall.companyTagged));
Worked perfectly for me.