I entered text in an EditText while designing a form filling app. Now, if i select part of that text, and wish to delete/modify it, I am not getting how to do it. All other options show how to clear entire textbox. How to clear just selected text.
EditText inputText=(EditText)findViewById(R.id.edit);
String inputString=inputText.getText().toString();
//To get the selected String
int selectionStart=inputText.getSelectionStart();
int selectionEnd=inputText.getSelectionEnd();
String selectedText = inputString.substring(selectionStart, selectionEnd);
if(!selectedText.isEmpty())
{
//Modify the selected StringHere
String modifiedString="...your modification logic here...";
//If you wish to delete the selected text
String selectionDeletedString=inputString.replace(selectedText,"");
inputText.setText(selectionDeletedString);
//If you wish to modify the selected text
String selectionModifiedString=inputString.replace(selectedText,modifiedString);
inputText.setText(selectionModifiedString);
}
You need to extract the string with
String fromEditText = editText.getText();
Now, you can do with string whatever you want and then put it back like
editText.setText(myString);
For operations with strings google working with strings and chars java on google.
Try this..
public void modifyText(View view ) {
if (view instanceof EditText) {
if(view.getText().toString().equals("Selected text")){
view.setText("Your Text");
}
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
View innerView = ((ViewGroup) view).getChildAt(i);
modifyText(innerView);
}
}
}
call this in your activity modifyText(findViewById(R.id.rootView));
This will modify all EditText in the current activity
I found this to be the best solution.
String contents = editText.getText().toString(), newText;
newText = contents.substring(0, noteEdit.getSelectionStart()) +
contents.substring(editText.getSelectionEnd(), contents.length());
editText.setText(newText);
Edit Selection
An easy and best(maybe) way of modifying the selected text.
int start = descriptionBox.getSelectionStart();
int end = descriptionBox.getSelectionEnd();
String modifiedText = "*" + descriptionBox.getText().subSequence(start, end) + "*";
descriptionBox.getText().replace(start, end, modifiedText);
Input Text ( '|' indicate selection )
hello |world|
Output Text
hello *world*
Delete Selection
All you have to do is replace the start and end of selection with empty String.
int start = descriptionBox.getSelectionStart();
int end = descriptionBox.getSelectionEnd();
descriptionBox.getText().replace(start, end, "");
Related
Is it possible to make part of the text inside EditText one color and the other part another color?
I have an example working with Html, but you can easily change it
String text = "<p>Hello world</p>";
// create Spanned
Spanned spanned = Html.fromHtml(text);
// create SpannableString
SpannableString spanString = new SpannableString(spanned);
// set colored part
ClickableSpan coloredPart = new ClickableSpan() {
#Override
public void onClick(View textView) {
}
#Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
ds.setColor(Color.WHITE);
}
};
spanString.setSpan(coloredPart, 0, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
editText.setText(spanString, TextView.BufferType.SPANNABLE);
Sure no problem.
TextAppearanceSpan mHighlightTextSpan = new TextAppearanceSpan(mContext, R.style.searchTextHighlight);
int startOfTextSearchTeam = orderModel.getTitle() != null ? indexOfSearchTermFromName(orderModel.getTitle()) : -1; //simple search for string in string for index
final SpannableString highlightTitle = new SpannableString(orderModel.getTitle() + " " + mContext.getString(R.string.count_open_bracket) + orderModel.getImageCount() + mContext.getString(R.string.count_closed_bracket));
// Sets the span to start at the starting point of the match and end at "length"
// characters beyond the starting point
if(startOfTextSearchTeam != -1){
highlightTitle.setSpan(mHighlightTextSpan, startOfTextSearchTeam, startOfTextSearchTeam + mSearchTerm.length(), 0);
itemViewHolder.txtOrderTitle.setText(highlightTitle);
}
I do this inside a recycler view adapter as I'm highlighting spans on each row as they search, but it's identical concept. Also I knew up the highlightTextSpan only one time in the constructor.
Hope that helps. Goodluck.
You can use SpannableString, try this.
SpannableString spannableText = new SpannableString("Text default to color");
final EditText diffColor = new EditText(getActivity());
// make "Text" (characters 0 to 4) red
spannableText.setSpan(new ForegroundColorSpan(Color.RED), 0, 4, 0);
diffColor.setText(spannableText, TextView.BufferType.SPANNABLE);
try this. It will work...
EditText edtText=(EditText)findViewById(R.id.edtText);
SpannableStringBuilder sb = new SpannableStringBuilder("Hello world in android");
final ForegroundColorSpan fcs = new ForegroundColorSpan(Color.RED);
// code to specify the character which do you want to change color. In this I have set value from 0,4 to change the color of firts 4 character from string.
sb.setSpan(fcs,0,4, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
edtText.setText(sb);
I am in the process of adding some html based formatting features to a JTextPane. The idea is that the user would select text in the JTextPane, then click a button (bold, italic etc) to insert the html tags at the appropriate locations. I can do this without difficulty using the JTextPane.getSelectionStart() and .getSelectionEnd() methods.
My problem is that I also want to scan each character in the JTextPane to index all the html tag locations - this is so the software can detect where the JTextPane caret is in relation to the html tags. This information is then used if the user wants to remove the formatting tags.
I am having difficulty synchronising this character index with the caret position in the JTextPane. Here is the code I have been using:
public void scanHTML(){
try {
boolean blnDocStartFlag = false;
alTagRecords = new ArrayList(25);
alTextOnlyIndex = new ArrayList();
String strTagBuild = "";
int intTagIndex = 0; // The index for a tag pair record in alTagRecords.
int intTextOnlyCount = 0; // Counts each text character, ignoring all html tags.
// Loop through HTMLDoc character array:
for (int i = 0; i <= strHTMLDoc.length() -1; i ++){
// Look for the "<" angle bracket enclosing the tag keyword ...
if (strHTMLDoc.charAt(i) == '<'){// It is a html tag ...
int intTagStartLocation = i; // this value will go into alTagFields(?,0) later ...
while (strHTMLDoc.charAt(i) != '>'){
strTagBuild += strHTMLDoc.charAt(i);
i ++; // continue incrementing the iterator whilst in this sub loop ...
}
strTagBuild += '>'; // makes sure the closing tag is not missed from the string
if (!strTagBuild.startsWith("</")){
// Create new tag record:
ArrayList<Integer> alTagFields = new ArrayList(3);
alTagFields.add(0, intTagStartLocation); // Tag start location index ...
alTagFields.add(1, -1); // Tag end not known at this stage ...
alTagFields.add(2, getTagType(strTagBuild));
alTagRecords.add(intTagIndex, alTagFields); // Tag Type
System.out.println("Tag: " + strTagBuild);
intTagIndex ++; // Increment the tag records index ...
} else { // find corresponding start tag and store its location in the appropriate field of alTagFields:
int intManipulatedTagIndex = getMyOpeningTag(getTagType(strTagBuild));
ArrayList<Integer> alManipulateTagFields = alTagRecords.get(intManipulatedTagIndex);
alManipulateTagFields.set(1, (intTagStartLocation + strTagBuild.length() -1) ); // store the position of the end angled bracket of the closing tag ...
alTagRecords.set(intManipulatedTagIndex, alManipulateTagFields);
System.out.println("Tag: " + strTagBuild);
}
strTagBuild = "";
} else {
// Create the text index:
if (blnDocStartFlag == false){
int intAscii = (int) strHTMLDoc.charAt(i);
if (intAscii >= 33){ // Ascii character 33 is an exclamation mark(!). It is the first character after a space.
blnDocStartFlag = true;
}
}
// Has the first non space text character has been reached? ...
if (blnDocStartFlag == true){ // Index the character if it has ...
alTextOnlyIndex.add(i);
intTextOnlyCount ++;
}
}
}
} catch (Exception ex){
System.err.println("Error at HTMLTagIndexer.scanHTML: " + ex);
}
}
The problem with the code above is that the string variable strHTMLDoc is obtained using JTextPane.getText, and this appears to have inserted some extra space characters within the string. Consequently this has put it out of sync with the corresponding caret position in the text pane.
Can anybody suggest an alternative way to do what I am trying to achieve?
Many thanks
Depending on the value:
Example
Pay:+200
Pay:-100
If the value of pay is higher the color of 200 is green.
If the value of pay is lower the color of 100 is red.
It changes color every seconds because I have xml file link from the browser
and update the xml file every seconds.
I like the color together as the link in my xml file refresh it in seconds and change the color depends if higher or lower.
Here if you mean the xml file to be of xml parsing, try the following one
while your placing the text in listview from xml file, get the color from the xml file and parse it as follows
String txt = "<font color=#408cc4>"+"here text you need to print"+"";
viewHolder.activity_hold_heading.setText(Html.fromHtml(txt));
here color = the color you need
Try to getGroupView method of base adapter class.According to value you get try set differnt colors as follows.
Before the method :
1) you have to get value(text need to be highlighted) from String and parse it to int and compare.
2) you have to get start and end index of your value(text need to be highlighted) from the String.
#Override
public View getGroupView(final int groupPosition, boolean isExpanded,View convertView, ViewGroup parent) {
Spannable WordtoSpan = new SpannableString(valuestring);
if(yourvalue>200){
WordtoSpan.setSpan(new ForegroundColorSpan(Color.parseColor("##00FF40")),start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}else if (yourvalue<100){
WordtoSpan.setSpan(new ForegroundColorSpan(Color.parseColor("#DF0101")),start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
yourtextview.setText(WordtoSpan);
}
to achieve this you need to bind data with Simpleadpter and using ViewBinder you can get the String values and Update the Color As per your Requirement and to update the data make adpter Notifydatasetchange
adapater1 = new SimpleAdapter(Byshedulelist.this, shedulelist, R.layout.rowshedule,
new String[] { "im","Countryname", "Titel"},
new int[] { R.id.rowshedulecountryimg,R.id.shedulerowCountrynametxt, R.id.shedulerowtitle,});
adapater1.setViewBinder(new MyViewBinder1());
itemlist.setAdapter(adapater1);
class MyViewBinder1 implements ViewBinder
{ #Override
public boolean setViewValue(View view, Object Status,String textRepresentation)
{
String complet="Pay:+200 ";
String notcomlet="Pay:-100";
String getdata= textRepresentation;
if((view instanceof TextView) & (Status instanceof String) )
{
TextView iv= (TextView) view;
if(complet.equals(Status))
{
r1=true;
r2=false;
iv.setText(textRepresentation);
iv.setTextColor(Color.parseColor("#008000"));
return true;
}
else if(notcomlet.equals(Status))
{
r2=true;
r1=false;
iv.setText(textRepresentation);
iv.setTextColor(Color.RED);
return true;
}
if(r1 && (getdata.startsWith("Pay: ")))
{
iv.setText(textRepresentation);
iv.setTextColor(Color.parseColor("#008000"));
return true;
}
else if (r2 && (getdata.startsWith("Pay: ")))
{
//TextView iv= (TextView) view;
iv.setText(textRepresentation);
iv.setTextColor(Color.RED);
return true;
}
}
return false;
}
}
String txt = "<font color=Red>"+"-100"+"";
String txt = "<font color=Green>"+"200"+"";
viewHolder.activity_hold_heading.setText(Html.fromHtml(txt));
I have an application that has 2 screens. The first screen has a ListView of movies with a row consisting of 3 Elements: Title, Date and Gross declared in strings.xml. The user has the option of adding a movie by clicking the menu button, which sends him to another screen. The second screen has 3 Edit texts that correspond to Title Date and Gross, which is alphabetically sorted straight away when it returns to screen 1.
Similarly, the user can also Edit/Delete entries by long clicking a row thatbrings up a context menu. The Edit function works like this:
a.) User long clicks Titanic and chooses Edit
b.) Row gets deleted, and user is brought to screen 2
c.) Edit texts are populated with the initial data from the deleted Row
d.) When user edits data, new movie is added at the bottom of the ListView.
The problem arises when the user deletes this new movie at the bottom of the ListView. Logcat gives a
java.lang.IndexOutOfBoundsException: Invalid index 50, size is 50
Here is my code (Take note I am using Perst to persist data, but I don;t think that won't really matter with my problem):
case R.id.contextedit:
Lab9_082588FetchDetails row = (Lab9_082588FetchDetails) getListView()
.getItemAtPosition(info.position);
Intent editData = new Intent(MovieList.this, Lab9_082588Edit.class);
String startTitle = row.getTitle();
String startGross = row.getGross();
String startDate = row.getDate();
editData.putExtra(Lab9_082588Edit.TITLE_STRING, startTitle);
editData.putExtra(Lab9_082588Edit.GROSS_STRING, startGross);
editData.putExtra(Lab9_082588Edit.DATE_STRING, startDate);
startActivityForResult(editData, MovieList.EDIT_MOVIE);
int posEdit = info.position;
String editTitle = results.get(info.position).getTitle();
results.remove(posEdit);
adapter.notifyDataSetChanged();
//Perst
Index<Lab9_082588FetchDetails> rootEdit = (Index<Lab9_082588FetchDetails>) db
.getRoot();
rootEdit.remove(editTitle, results.get((int) info.id));
db.setRoot(rootEdit);
return true;
Edit Class:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection using item.getItemId()
switch (item.getItemId()) {
case R.id.edit:
next();
break;
}
return true;
}
private void next() {
// TODO Auto-generated method stub
EditText movieTitle = (EditText) findViewById(R.id.etTitle);
EditText movieGross = (EditText) findViewById(R.id.etGross);
EditText movieDate = (EditText) findViewById(R.id.etDate);
String title = movieTitle.getText().toString();
String gross = movieGross.getText().toString();
String date = movieDate.getText().toString();
if ((title.length() > 0) && (gross.length() > 0)
&& (date.length() == 4)) {
Intent hobby = getIntent();
hobby.putExtra(Lab9_082588Edit.TITLE_STRING, title);
hobby.putExtra(Lab9_082588Edit.GROSS_STRING, gross);
hobby.putExtra(Lab9_082588Edit.DATE_STRING, date);
setResult(RESULT_OK, hobby);
finish();
}
}
Delete function:
int posDelete = info.position;
String deleteTitle = results.get(
info.position).getTitle();
results.remove(posDelete);
adapter.notifyDataSetChanged();
Index<Lab9_082588FetchDetails> rootDelete = (Index<Lab9_082588FetchDetails>) db
.getRoot();
rootDelete.remove(deleteTitle,
results.get(info.position));
db.setRoot(rootDelete); //Perst
return;
OnActivityResult (Edit):
case EDIT_MOVIE:
Lab9_082588FetchDetails edittedMovie = new Lab9_082588FetchDetails();
NumberFormat formatterEdit = new DecimalFormat("###,###,###");
edittedMovie.setTitle(data
.getStringExtra(Lab9_082588Add.TITLE_STRING));
edittedMovie.setGross("$"
+ formatterEdit.format(Double.parseDouble(data
.getStringExtra(Lab9_082588Add.GROSS_STRING))));
edittedMovie.setDate(data
.getStringExtra(Lab9_082588Add.DATE_STRING));
results.add(edittedMovie);
adapter.notifyDataSetChanged();
Populating the Listview:
for (int i = 0; i < items.size(); i++) {
Lab9_082588FetchDetails sr = new Lab9_082588FetchDetails();
sr.setTitle(items.get(i).getTitle());
sr.setGross(items.get(i).getGross());
sr.setDate(items.get(i).getDate());
results.add(sr);
Collections.sort(results, ignoreCaseStart);
}
How do I remedy this?
This problem occurs because in your delete function, you first remove the element from the results collection("results.remove(posDelete);"), and then, a few lines later, you call "results.get(info.position)" to fetch a parameter for the rootDelete.remove call, but which is already removed.
If the element is the last element of your collection, let's say the 50th element, the value for "info.position" is 50. You remove one element, so the number of elements is now 49. In the rootDelete.remove line you call results.get(50), which produces the error.
I've created a timetable app, which allows the user to enter data and then view it.However if the user enters an entry, on a day and time where there already is one, my emulator crashes(forces a close).
Basically I'm pulling back data to a linear layout- which contains 10 TextViews, each representing the times 9-15.
Here's the code:
public void addMondayGrid() {
// TODO Auto-generated method stub
for (int index = 0; index < info.mon.size(); index++) {
// int entryId = info.monIds.get(index);
int time = info.monTimes.get(index);
int id = info.monIds.get(index);
int duration = info.monDuration.get(index);
String dayOfWeek = "mon";
timeId = getResources().getIdentifier("mon" + time, "id",
getPackageName());
if (duration == 1) {
SpannableString text = new SpannableString(info.mon.get(index));
setEntryColour(text);
final TextView textV = (TextView) findViewById(timeId);
textV.setTextSize(10);
textV.setText(text, BufferType.SPANNABLE);
textV.setId(id);
deleteGridEntry(textV);
} else {
longerDuration(time, index, id, info.mon, dayOfWeek);
}
}
}
The thing is is works fine as long as there isn't two entries for the same day and time, eg. monday at 9 oclock.
Anyone have any ideas?I'm quite new to this and any help would be much appreciated!
I have to reference the id this way as there are too many ids to reference any other way,is there not a simple way to overwrite the old textView with new data pulled back from the database? I want the id to be the same one as that is the textView I want to deal with, but it just keeps crashing, is it something to do with instances?
change:
final TextView textV = (TextView) findViewById(timeId);
to:
final TextView textV = (TextView) findViewById(R.id.timeId);