I have an editText in which i want to bold the text that i select.
I'm using the Contextual Action Bar with a button to bold a selected word.
The problem is that if I bold a word I can't bold the other onesm and if i remove the span from that word, I can't add it again.
et is the editText in which i write, and i use also 2 SpannableString to catch the remaining text keeping eventual spans added before on it.
CUSTOM CALLBACK
cs1 = new StyleSpan(Typeface.BOLD);
class CustomCallback implements ActionMode.Callback {
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
//exploiting the CAB
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
menu.removeItem(android.R.id.selectAll);
return true;
}
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
ACTION ADD BOLD
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
int start = et.getSelectionStart();
int end = et.getSelectionEnd();
SpannableStringBuilder s_before,s_next;
SpannableStringBuilder ssb = new SpannableStringBuilder(et.getText().subSequence(start, end));
s_before= new SpannableStringBuilder (et.getText().subSequence(0, start));
s_next= new SpannableStringBuilder (et.getText().subSequence(end, et.length()));
switch(item.getItemId()) {
case R.id.bold:
int a=ssb.getSpanStart(cs1);
int b=ssb.getSpanEnd(cs1);
if(a==-1 && b==-1){
ssb.setSpan(cs1, 0, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
else{
ssb.removeSpan(cs1);
}
et.setText("");
et.append(s_before);
et.append(ssb);
et.append(s_next);
return true;
How can i solve it?
Thanks in advance.
I've just put a RichEditText library https://github.com/kemallette/RichEditText which adds bold/italic/strike/underline.. and a few other font styles functionalities. It also adds a bunch of great validations.
If that doesn't fit your needs, you'll need to focus on keeping track of where your spans are, what type they are and that they're being adjusted/re-added. Take a look at the RichEditText and RichTextWatcher classes in the above library. It'll give you a better idea of what's actually happening when text changes in your EditText.
Related
I am trying to present a custom action bar while long pressing a textview. My menu has more than 5 items which causes some of the items to be present under the overflow menu.
When I press the overflow icon, the action bar gets destroyed and I am not able to choose any item inside the overflow.
ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.add_rule_menu, menu);
return true;
}
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
for (int i = 0; i < menu.size(); i++) {
MenuItem item = menu.getItem(i);
if (!mOptionsList.contains(item.getItemId()))
item.setVisible(false);
}
return false;
}
// Clicking on overflow button does not trigger this method at all.
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
// Rest of the code
}
}
public void onDestroyActionMode(ActionMode mode) {}
};
textView.setCustomSelectionActionModeCallback(mActionModeCallback);
I filed an issue about this years ago, which has never been resolved.
A cheesy workaround is to use nested action modes. By this, I mean you have an item in an action mode that finishes the current mode and starts a new one, to provide a "drill-down menu" effect. I use this in my recently-resuscitated RichEditText widget, which offers an action mode for formatting text. I add a "format" item to the default action mode via setCustomSelectionActionModeCallback(). Tapping on "format" opens another action mode that offers options like bold and italic, along with further drill-downs to get to thinks like font changes.
I have a SearchView in ActionBar.
I'd like to validate the text input by the user before submitting it to SearchManager.
What I mean is, if a user entered text less than 3 characters, then a Toast will pop up instead going to another activity that shows the search results.
Here is how I implement the SearchView:
In MainActivity:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.search, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
SearchView.OnQueryTextListener queryTextListener = new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String s) {
Log.d(TAG, "submit= "+s);
if (s.length() < 4) Toast.makeText(getApplicationContext(), "More than 3 letter pl0x", Toast.LENGTH_LONG).show();
return true;
}
#Override
public boolean onQueryTextChange(String s) {
return true;
}
};
searchView.setOnQueryTextListener(queryTextListener);
return super.onCreateOptionsMenu(menu);
}
I just wanna make sure the user input is more than 3 characters. Is there a possible way to do this?
From the docs: "The listener can override the standard behavior by returning true to indicate that it has handled the submit request. Otherwise return false to let the SearchView handle the submission by launching any associated intent."
if (s.length() < 4) {
Toast.makeText(getApplicationContext(), "More than 3 letter pl0x", Toast.LENGTH_LONG).show();
return true;
} else {
return false;
}
there is a library from zasadnyy for this.
Click here https://github.com/zasadnyy/z-validations
I downloaded that library and added the class "HasMinimumLength". With that, you can check whether the length of the text is longer than the provided minimum character length.
Please take care, that you need to copy the strings from strings.xml into your own strings and that you have to switch the imports. Meaning, in the validation classes instead of
import ua.org.zasadnyy.zvalidations.R you should use import your.package.name.R
I have been developing app these days, the code for changing text items:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater=getMenuInflater();
inflater.inflate(R.menu.main, menu);
int positionOfMenuItem = 0; // or whatever...
MenuItem item = menu.getItem(positionOfMenuItem);
SpannableString s = new SpannableString("My red MenuItem");
s.setSpan(new ForegroundColorSpan(Color.RED), 0, s.length(), 0);
item.setTitleCondensed(s);
return true;
}
it works pretty, but when I clicking the menu item it stops with error
Use one of the Spannable flag constants as the last argument to the call to setSpan(), e.g. Spannable.SPAN_EXCLUSIVE_EXCLUSIVE. See http://developer.android.com/reference/android/text/Spannable.html.
Also, consider moving the code after inflate to onPrepareOptionsMenu().
The following post might be useful: http://www.techrepublic.com/article/style-androids-overflow-menu-using-this-sanity-saving-workaround/
I would like to disable the ActionBar Menu Item but make it clickable. Is there any way I can do this?
Right now, it's just greyed out if I set setEnabled as false which is normal behavior but it's not clickable.
This doesn't really answer the question as the ActionBar Menu Item cannot be disabled and clickable at the same time. What I ended up doing was enabling the Menu Item and setting the text color to grey to make it look pseudo-disabled. And if the condition was fulfilled it would change to default color.
Credit: Nicolai Buch Andersen
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.menu, menu);
SpannableStringBuilder text = new SpannableStringBuilder();
text.append(getString(R.string.menu_title));
if (someCondition){
text.setSpan(new ForegroundColorSpan(Color.BLACK),
0, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
else {
text.setSpan(new ForegroundColorSpan(Color.LTGRAY),
0, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
MenuItem item = menu.findItem(R.id.some_menu_id);
item.setTitle(text);
return true;
}
I have an actionBar with multiple items, I would like to change the colour of the text when the item is clicked. Is there anyway to do this programmatically? Please provide and example or any resources.
Thanks
public void catalogClick(MenuItem item){
//highlight menuitem etc.
}
To change without defining a style resource, we can use SpannableString.
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
//To style first menu item
MenuItem menuItem = menu.getItem(0);
CharSequence menuTitle = menuItem.getTitle();
SpannableString styledMenuTitle = new SpannableString(menuTitle);
styledMenuTitle.setSpan(new ForegroundColorSpan(Color.parseColor("#00FFBB")), 0, menuTitle.length(), 0);
menuItem.setTitle(styledMenuTitle);
return super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
Toast.makeText(this, item.getTitle() + " clicked!", Toast.LENGTH_LONG).show();
return true;
}
As you format the text style, you will get "Invalid payload item type" exception. To avoid that, override onMenuItemSelected, and use return true or false.
Reference:
Android: java.lang.IllegalArgumentException: Invalid payload item type
http://vardhan-justlikethat.blogspot.in/2013/02/solution-invalid-payload-item-type.html
Follow this link which explains how to change menuitem text programmatically.
http://developer.android.com/guide/topics/ui/actionbar.html#Style
Check for android:actionMenuTextColor for defining a style resource for text.
Try Firewall_Sudhan answer but iterating the submenu of the menu
#Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
SubMenu subMenu = menu.getItem(0).getSubMenu();
for (int i = 0; i < subMenu.size(); i++) {
MenuItem menuItem = subMenu.getItem(i);
CharSequence menuTitle = menuItem.getTitle();
SpannableString styledMenuTitle = new SpannableString(menuTitle);
styledMenuTitle.setSpan(new ForegroundColorSpan(Color.BLACK), 0, menuTitle.length(), 0);
menuItem.setTitle(styledMenuTitle);
}
}