19 May 2013

fabian's picture
Posted by fabian on July 27, 2012

This tutorial is for devices 3.0 and above unless you are using ActionBarCompat (http://developer.android.com/resources/samples/ActionBarCompat/index.html)

In this tutorial we will cover how to select text and set custom menu items using the contextual action bar like this:

I came across the problem of selecting text so I can change the style of them, I won't go into that now but I wil have the code in here if you want it.

The first thing we want is to specify the layout, we will name this main.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
 
    <TextView
   android:id="@+id/textView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />
 
</LinearLayout>
 
and then set the string resource "hello" as:
 
"Software Engineer from New Zealand, I mainly specialise in Android Development and I am slowly getting into things like python and C Hello there my name is Fabian Cook and C Hello there my name is Fabian Cook and Java however I am a Software Engineer from New Zealand, I mainly specialise in Android Development and I am slowly getting into things like python and I am a Software Engineer from New Zealand, I mainly specialise in Android Development and C Hello there my name is Fabian Cook and C Hello the"

That just some random text that we will use to test the selection process.

We need to make it so that the text view can actually be selected so we need to add this to it in the XML layout:

android:textIsSelectable="true"
 
Now head over to your activity and create a member for the TextView, I am going to name mine "tv"
 
TextView tv;
 
Then in your on create method assign it:
 
tv = (TextView) findViewById(R.id.textView1);
 
Then we need to get the call back for the selection:
 
tv.setCustomSelectionActionModeCallback(this);
 
Make your activity implement CallBack
 
public class TextSelectionActivity extends Activity implements Callback{
 
and then add the missing methods in:
 
@Override
public boolean onActionItemClicked(ActionMode arg0, MenuItem arg1) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
// TODO Auto-generated method stub
 
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
return false;
}
 
Now what we want to do is add in the selection functionality.
 
First we need to return true in onCreateActionMode, this will start the CAB. Then in onActionItemClicked we can start doing things.
 
To get where the text is selected we should find where selection starts and ends
 
(This is inside onActionItemClicked)
 
int start = tv.getSelectionStart();
int end = tv.getSelectionEnd();
 
Now we can use this to get the text selected and do what ever with it.
 
We should do something with the text like making the text bold. We can use this using a span.
 
First we want to add a menu item to the menu in onCreateActionMode
 
menu.add(0,0,0,"BOLD");
 
Then in onActionItemClicked we want to receive the item click, so in onActionItemClicked we should add this:
 
CharacterStyle cs = null;
 
switch (arg1.getItemId()){
case 0:
 
break;
}
 
Now we can do something with the selected text when the user presses bold after selecting the text.
 
We now need to set the text to bold.
 
in the switch statement we need to set cs as bold.
 
CharacterStyle cs;
 
switch (arg1.getItemId()){
case 0:
cs = new StyleSpan(Typeface.BOLD);
break;
}
 
Then we need to build the span
 
SpannableStringBuilder ssb = new SpannableStringBuilder(tv.getText());
ssb.setSpan(cs, start, end, 1);
 
and then set the text view
 
tv.setText(ssb);
 
And there you go, run your activity and you will have text selection with formatting, just add in some other formatting tools like italic, underline and color and you should be sweet
 
switch(type){
case 0:
cs = new StyleSpan(Typeface.BOLD);
break;
case 1:
cs = new UnderlineSpan();
break;
case 2:
cs = new StyleSpan(Typeface.ITALIC);
break;
case 3:
cs = new ForegroundColorSpan(Color.rgb(r, g, b));
}
 
There we go :)

Tags: