how can i underline word by word in a sentence in android studio? so my program would be like this if i click a button the underline will start at first and when i click again the button it will move again to the next word.
for Example:
_The_ *** *** ***** **** *** **** ***.
so if i want to click the button the underline will move next to it word or 3 asterisk.
The _***_ *** ***** **** *** **** ***.
and click again to the next asterisk.
this is my code using for this:
public class MainActivity extends AppCompatActivity {
Button btn;
TextView txt;
int counter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = findViewById(R.id.button);
txt = findViewById(R.id.display);
txt.setText("the red fox jumps over the lazy dog.");
final String [] compare1 = txt.getText().toString().split("\\s");
final String arr[] = txt.getText().toString().split(" ",2);
final String fword = arr[0];
String rword = arr[1];
final String reprword = rword.replaceAll("[a-z]", "*");
txt.setText(fword + " " + reprword);
final String [] display = txt.getText().toString().split("\\s");
/*final ArrayList<String> getters = new ArrayList<String>(Arrays.asList(display));*/
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(counter <= display.length) {
if(compare1[counter].length() == display[counter].length())
{
txt.setText(formatText(fword + " " + reprword,display[counter]));
}
counter++;
}
else
{
}
}
});
}
public CharSequence formatText(String base, String highlight) {
int start = base.indexOf(highlight);
if (start >= 0) {
SpannableString span = new SpannableString(base);
span.setSpan(new UnderlineSpan(), start, start + highlight.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return span;
}
return base;
}
}
I change the other half the sentence to test it for this.
base.indexOf(highlight) ==> indexOf() returns the first occurrence of highlight in base , thats why the underline span jumps to first "the" instead of the next occurrence. You can use indexOf(String str, int fromIndex).
The following code tracks the "fromIndex" in this variable "nextStartIndex", and also underlining resets to first word after completing the sentence.
public class UnderlineWordsActivity extends AppCompatActivity {
private Button btn;
private TextView txt;
private int counter=0;
private int nextStartIndex=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = findViewById(R.id.button);
txt = findViewById(R.id.display);
txt.setText("the red fox jumps over the lazy dog.");
final String[] arr = txt.getText().toString().split(" ", 2);
final String firstWord = arr[0];
String remainingWords = arr[1];
final String reprword = remainingWords.replaceAll("[a-z]", "*");
String text = firstWord+" "+reprword;
txt.setText(text);
final String[] display = txt.getText().toString().split("\\s");
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (counter >= display.length) {
counter = 0;
nextStartIndex = 0;
}
txt.setText(formatText(text, display[counter]));
counter++;
}
});
}
public CharSequence formatText(String base, String highlight) {
int start = base.indexOf(highlight,nextStartIndex);
nextStartIndex = start+highlight.length();
if (start >= 0) {
SpannableString span = new SpannableString(base);
span.setSpan(new UnderlineSpan(), start, nextStartIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return span;
}
return base;
}
}
Related
I'm in the beginning of my learning how to make apps. I want to make an app which should display randomized inputted tasks to do for the user. Firstly user should choose how many tasks would like to create and then write down tasks in EditText. I am able to create particular amount of EditText but I have no clue how to display all EditText input after pressing button. I have many versions of the code but non of them work. I got stuck and I need advice.
Here is one of my code version for the second activity.
public class TaskActivity extends AppCompatActivity {
LinearLayout containerLayout;
TextView receiverTV;
TextView tv;
TextView displayTaskTv;
EditText et;
Button btn;
Button randomTaskBtn;
int i = 0;
int size;
String inputEditText;
String inputTextView;
String stringsEt[];
String stringsTv [];
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_task);
containerLayout = (LinearLayout) findViewById(R.id.linear_layout);
receiverTV = (TextView) findViewById(R.id.receiver_textView);
Intent intent = getIntent();
int number = intent.getIntExtra("Number", defaultValue);
receiverTV.setText("You have chosen to add: " + number + " tasks!");
createEtTvBtn(number);
createBtn();
createTextView();
}
public void createEtTvBtn(int number) {
for (i = 1; i <= number; i++) {
tv = new TextView(this);
tv.setText("Task nr: " + i);
tv.setPadding(16, 16, 16, 16);
tv.setTextColor(Color.parseColor("#008b50"));
tv.setTextSize(20);
tv.setId(i + value);
containerLayout.addView(tv);
et = new EditText(this);
et.setHint("Enter task nr: " + i);
et.setId(i + value);
et.setLines(2);
containerLayout.addView(et);
btn = new Button(this);
btn.setText("Confirm task nr: " + i);
btn.setId(i + value);
containerLayout.addView(btn);
final List<EditText> allEditText = new ArrayList<EditText>();
final List<TextView>allTextView = new ArrayList<TextView>();
final List<Button>allButton = new ArrayList<Button>();
String[] stringsEditText = new String[(allEditText.size())];
String[] stringsTextView = new String[(allTextView.size())];
String[] stringsBtn = new String[(allButton.size())];
for(int i=0; i < allEditText.size(); i++){
stringsEditText[i] = allEditText.get(i).getText().toString();
}
for (int i=0; i < allTextView.size(); i++) {
stringsTextView[i] = allTextView.get(i).getText().toString();
size = allTextView.get(i).getText().toString().length();
}
for(int i=0; i < allButton.size(); i++){
stringsBtn[i] = allButton.get(i).getText().toString();
}
allTextView.add(tv);
allEditText.add(et);
allButton.add(btn);
allButton.get(0).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
inputEditText = allEditText.get(0).getText().toString();
stringsEt = new String[] {allEditText.get(0).getText().toString()};
if (inputEditText.length() > 0) {
allTextView.get(0).setText(inputEditText);
allEditText.add(allEditText.get(0));
allEditText.get(0).setText("");
}
else if (inputEditText.length() ==0){
Toast.makeText(TaskActivity.this, "You need to write down your task", Toast.LENGTH_LONG).show();
}
inputTextView = allTextView.get(0).getText().toString();
stringsTv = new String[] {allTextView.get(0).getText().toString()};
if (inputTextView.length() > 0) {
allTextView.get(0).getText();
allTextView.add(allTextView.get(0));
}
}
});
}
}
private Button createBtn() {
randomTaskBtn = new Button(this);
randomTaskBtn.setText("Task");
containerLayout.addView(randomTaskBtn);
randomTaskBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
double luckyTask = Math.random();
luckyTask *=size;
int luckyIndex = (int)luckyTask;
displayTaskTv.setText(stringsTv[luckyIndex]);
}
});
return randomTaskBtn;
}
private TextView createTextView() {
displayTaskTv = new TextView(this);
displayTaskTv.setTextSize(20);
displayTaskTv.setTextColor(Color.parseColor("#dd2626"));
displayTaskTv.setText("");
containerLayout.addView(displayTaskTv);
return displayTaskTv;
}
}
Thank you for any constructive advices.
I am sure my code is big mess. I wanted to created more methods but I didn't succeed.
This is what you should do
Step 1 -
Create multiple EditTexts and store each one of them in an ArrayList say myEditTextList.
Step 2- Take data from all edit texts
String str = ""
for(EditText et: myEditTextList) {
str += et.getText().toString();
}
Step 3- Display data in str wherever you want.
Im using a SpannableString to color the words which match an existing string.
This works perfectly the first time the fragment is called, the words are found, matched and colored. But the second time the fragment is called, the method which checks for matches and colors the matching words fires, and from the log cat I can see the words are found and matched but not colored.
I'm guessing it has something to do with the lifecycle of the fragment and where SpannableString is being initialized.
I have tried to initialize the SpannableString in onResume(); and in setUserVisibleHint(boolean isVisibleToUser);
This is my approach
public class LessonOne extends ActualFragmetHolder {
#Override
public void init(Bundle savedInstanceState) {
addSlide(FragmentPronounce.newInstance("The cat is jumping over the mouse"));
addSlide(FragmentPronounce.newInstance("This house is really big"));
.....
FragmentPronounce.java
public class FragmentPronounce extends Fragment implements View.OnClickListener,RecognitionListener,TextToSpeech.OnInitListener {
private static final String ARG_OPTION_ONE = "opt1";
private SpannableString hashText;
....
public static FragmentPronounce newInstance(String option1) {
FragmentPronounce sampleSlide = new FragmentPronounce();
Bundle args = new Bundle();
args.putString(ARG_OPTION_ONE, option1);
sampleSlide.setArguments(args);
return sampleSlide;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
....
if (getArguments() != null && getArguments().size() != 0) {
option1 = getArguments().getString(ARG_OPCTION_ONE);
}
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_pronounce_material, container, false);
final TextView the_question = (TextView) v.findViewById(R.id.text_user_must_say);
if (theQuestion != 0) {
the_question.setText(theQuestion);
}
//mic button
fabMic.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
///starts listening for speech and does its thing
///Im using my own custom speech recognition which works fine
speech.startListening(recognizerIntent);
////check for OnResults()
}
}
#Override
public void onResults(Bundle results) {
//if its a OnResults is fine then
methodToCheckAnswer(results);
....
}
private void methodToCheckAnswer(Bundle results) {
//checks answer and calls method which counts and colors words in string
countAndColorWords();
}
//This is the method which check and colors, it triggers fine every time fragment is called, but it only colors the word the first time is called in the fragment's life cycle
private void countAndColorWords(){
String strRight = rightanswer;
.....
the_question = (TextView) getActivity().findViewById(R.id.text_user_says);
the_question.setText(theQuestion);
System.out.println("The question's TEXT" + String.valueOf(the_question.getText().toString()) + "Tokens counted" + tokensCounted + "Option1" + option1 + "What was spoken " + userAnswered);
hashText = SpannableString.valueOf(the_question.getText().toString());
System.out.println("hashText Value "+hashText+ "Right Answer "+ rightanswer);
Matcher matcher = Pattern.compile("\\S+").matcher(strRight);
Matcher usermatcher = Pattern.compile("\\S+").matcher(userAnswered);
int groupCounted = 0;
groupCounted += matcher.groupCount()+1;
Log.d(TAG, "The position number of groups:"+groupCounted +" "+userAnswered);
int rightAnswerCount = matcher.groupCount();
int userAnswerCount = usermatcher.groupCount();
String rightAnswer;
String userAnswer;
int contadorGroup = 0;;
int matchCounter =0;
contadorGroup += matcher.groupCount() + 1;
while (matcher.find() && usermatcher.find()) {
System.out.println(matcher.start() + ":" + matcher.group());
rightAnswer = matcher.group();
userAnswer = usermatcher.group();
rightAnswerCount += matcher.groupCount();
userAnswerCount += usermatcher.groupCount();
String check = "";
for (int i = 0; i <= rightAnswerCount && i <= userAnswerCount; i++) {
if (matcher.group(i).equalsIgnoreCase(usermatcher.group(i))) {//matcher.group(i) == usermatcher.group(i)
matchCounter++;
check = matcher.group(i);
hashText.setSpan(new ForegroundColorSpan(Color.parseColor("#64DD17")), matcher.start(), matcher.end(), i);
}
}
}
//hashText.setSpan(new ForegroundColorSpan(Color.parseColor("#64DD17")), matcher.start(), matcher.end(), palabraColor);
the_question.setText(hashText);
}
Sorry for spaghetti code, tried cleaning it up best I could after trying 100 different things.
I'm trying to make a feature for my app where the user can make a selected text Bold but I also want to make it so that if the selected text is already bold, then the text shall be set to normal again, a kind of an undo-function.
I have tried over 100 of combinations without any succses!
CharacterStyle csBold = new StyleSpan(Typeface.BOLD);
CharacterStyle csNormal = new StyleSpan(Typeface.NORMAL);
int start = editText.getSelectionStart();
int end = editText.getSelectionEnd();
SpannableStringBuilder ssb = new SpannableStringBuilder(editText.getText());
ssb.setSpan(csBold, start, end, 1);
SpannableStringBuilder ssb2 = new SpannableStringBuilder(editText.getText());
ssb2.setSpan(csNormal, start, end, 1);
switch(item.getItemId()) {
case R.id.bold:
while(editText.isSelected()){
if(editText.getSelectionStart() + editText.getSelectionEnd() == ssb.getSpanStart(start) + ssb.getSpanEnd(end)){
editText.setText(ssb2);
return true;
}else{
editText.setText(ssb);
return true;
}
}
Update ANSWER
Edittext editext;
Button bold_btn , normal_btn , itlac;
CharacterStyle styleBold , styleItalc;
boolean bold = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
styleBold = new StyleSpan(Typeface.BOLD);
styleNormal = new StyleSpan(Typeface.NORMAL);
styleItalc = new StyleSpan(Typeface.ITALIC);
underLine = new UnderlineSpan();
editext = (Editext) findViewById(R.id.editext);
bold_btn = (Button) findViewById(R.id.button1);
italic_btn = (Button) findViewById(R.id.button2);
italic_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String wholeText = username.getText().toString();
int start = username.getSelectionStart();
int end = username.getSelectionEnd();
SpannableStringBuilder sb = new SpannableStringBuilder(wholeText);
sb.setSpan(styleItalic, start, end, 0);
username.setText(sb);
}
});
........
.....
bold_btn.setOnClickListener(BoldbuttonListener);
normal_btn.setOnClickListener(normalbuttonListener);
}
View.OnClickListener BoldbuttonListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
bold = !bold;
String wholeText = username.getText().toString();
int start = username.getSelectionStart();
int end = username.getSelectionEnd();
CharacterStyle passedStyle;
SpannableStringBuilder sb = new SpannableStringBuilder(wholeText);
if(bold) {
passedStyle = styleNormal;
}else {
passedStyle = styleBold;
}
sb.setSpan(passedStyle, start, end, 0);
editext.setText(sb);
}
};
the same for normal effect
I only want to find the words on the Diccionario Array and highlight but show other words to
Example: If I search "spannable", i want to return the same text but with the words who find it on highlight or other color !
public class FindString extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search_string);
final Button btnSearch = (Button) findViewById(R.id.searchBtn);
final EditText Searchtxt = (EditText)findViewById(R.id.textSearch);
final String[] Diccionario = {"hola","adios","ayer","hoy","maƱana"};
btnSearch.setOnClickListener(new View.OnClickListener() {
public void onClick(View v){
String FinalText = " " ;
String SearchText ="";
SearchText = Searchtxt.getText().toString();
String[] split = SearchText.split(" ");
for(int i=0; i<split.length; i++)
{
for(int j=0; j<Diccionario.length;j++)
{
if(split[i].equals(Diccionario[j]))
{
FinalText = FinalText +" "+split[i];
}
}
}
}
emphasized text
try this
{
final SpannableStringBuilder sb = new SpannableStringBuilder(FinalText);
final ForegroundColorSpan fcs = new ForegroundColorSpan(Color.rgb(158, 158, 158));
// Span to set text color to some RGB value
final StyleSpan bss = new StyleSpan(android.graphics.Typeface.BOLD);
// Span to make text bold
sb.setSpan(fcs, 0, 4, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
// Set the text color for first 4 characters
sb.setSpan(bss, 0, 4, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
// make them also bold
yourTextView.setText(sb);
}
When I type S in text1 a corresponding picture appears in text2 however when I type G in text1 a corresponding picture is shown in text2, but the previous picture of S is shown as a letter instead of a picture. Why is that? Why can't it display two pictures? What's wrong?
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText te1 = (EditText)findViewById(R.id.t1);
final EditText te2 = (EditText)findViewById(R.id.t2);
final Button v = (Button)findViewById(R.id.b1);
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//imva.setImageResource(R.id.b1);
te2.setText(" ");
String t= te1.getText().toString();
char [] aa = t.toString().toCharArray();
for (int i = 0 ; i < aa.length ; i++)
{
if (aa[i] == 's')
{
SpannableStringBuilder builder = new SpannableStringBuilder(te1.getText());
do {
ImageSpan imageSpan = new ImageSpan(getBaseContext(),R.drawable.a1);
int pos = builder.toString().indexOf("s");
builder.replace(pos, pos + 1, "$");
builder.setSpan(imageSpan, pos, pos + 1,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} while (builder.toString().indexOf("s") > -1);
te2.setText(builder);
}
if (aa[i] == 'g')
{
SpannableStringBuilder builder = new SpannableStringBuilder(te1.getText());
do {
ImageSpan imageSpan = new ImageSpan(getBaseContext(),R.drawable.a2);
int pos = builder.toString().indexOf("g");
builder.replace(pos, pos+ 1, "$");
builder.setSpan(imageSpan, pos, pos + 1,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} while (builder.toString().indexOf("g") > -1);
te2.setText(builder);
}
}