Tuesday, September 20, 2016

Why is my Android UI acting wonky whenever I try to select text?

Leave a Comment

I am working on an Android app (API 15 and below). In my UI I have a TextView element that I would like people to be able to select and copy from. Here is what my element looks like:

<LinearLayout     android:orientation="horizontal"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:padding="20dp" />     <TextView         android:id="@+id/chat_info"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_weight="0"         android:padding="8dp" />      <TextView         android:id="@+id/chat_message"         android:layout_width="0dp"         android:layout_height="wrap_content"         android:layout_weight="1"         android:layout_margin="2dp"         android:padding="8dp"         android:textSize="18sp"         android:gravity="right"         android:textColor="@color/BLACK"         android:textIsSelectable="true"/> </LinearLayout> 

This TextView sits within a ListView that is populated with a SimpleCursorAdapter. This ListView looks like this:

<ListView     android:id="@+id/chat_text_display"     android:layout_width="match_parente"     android:layout_height="0dp"     android:layout_weight="1"     android:layout_marginTop="2dp"     android:layout_marginRight="2dp"      android:layout_marginBottom="2dp"     android:layout_marginLeft="2dp"     android:padding="5dp"     android:background="@color/WHITE"     android:divider="@null"     android:divider_height="0dp"     android:stackFromBottom="true"     android:transcriptMode="alwaysScroll"/> 

Whenever I try to single-click the text in chat_info or chat_message, nothing happens. However, whenever I try to double-click the text:

  1. my entire UI shifts down
  2. a "toolbar" shows up at the top of the screen
  3. the "toolbar" immediately goes away and my display shifts back up

In the "toolbar" this is what I see:

http://i.imgur.com/krZK5Ji.png

It looks like it is the copy dialog, but it goes away immediately.

All I am wanting to do is select the text in chat_info or chat_message so I can copy and paste the text elsewhere.

Any ideas?

2 Answers

Answers 1

Single click is expected. Android doesn't hilight on single click.

You're entering the action mode for copy paste. An action mode is a state of an activity where the toolbar switches out for a context aware set of commands (in this case copy/paste commands). It seems like you're entering it and then immediately exiting it, possibly because you're losing focus to another element.

Answers 2

There are a lot of typing errors in your xml ;O)

I would not use android:textIsSelectable="true"

This code copies automatically the data to clipboard on every user click.
I would do it like this (tested code on API19, easy enough to lower API):

 //some test data     static final String[] FRUITS = new String[] { "Apple", "Avocado", "Banana",         "Blueberry", "Coconut", "Durian", "Guava", "Kiwifruit",         "Jackfruit", "Mango", "Olive", "Pear", "Sugar-apple" };  @Override protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     m_context = getApplicationContext();      setContentView(R.layout.shadow);      ListView listView = (ListView) findViewById(R.id.chat_text_display);          ArrayList<ChatRow> chat_list = new ArrayList<ChatRow>();         for(int i = 0 ;i<FRUITS.length;i++)         {             chat_list.add( new ChatRow(FRUITS[i]+"(chat_info)",FRUITS[i]+"(chat_message)"));         }         final ChatArrayAdapter chatArryAdapter = new ChatArrayAdapter(m_context, chat_list);         listView.setAdapter(chatArryAdapter); } //==================================================      public class ChatRow      {           private String  name1   = "" ;           private String  name2   = "" ;           //constructor           public ChatRow( String name1, String name2 )           {               this.name1  = name1;               this.name2  = name2;           }           //setters and getters         //--------------------------------------------------------------------------------               public String getName1()               {                 return name1 ;               }         //--------------------------------------------------------------------------------               public void setName1(String name)               {                 this.name1 = name ;               }         //--------------------------------------------------------------------------------               public String getName2()               {                 return name2 ;               }         //--------------------------------------------------------------------------------               public void setName2(String name)               {                 this.name2 = name ;               }         //--------------------------------------------------------------------------------     }//class ChatRow //==================================================      public class ChatArrayAdapter extends ArrayAdapter<ChatRow>      {             private final Context   context;              //--------------------------------------------------------------------------------             //constructor             public ChatArrayAdapter(Context context,  ArrayList<ChatRow> rowList)             {                 super(context, R.layout.achievements_item, R.id.chat_info, rowList);                 this.context = context;             }//ChatArrayAdapter constructor             //--------------------------------------------------------------------------------             @Override             public View getView(int position, View convertView, ViewGroup parent)             {                 // CBRow to display                 final ChatRow row = (ChatRow) this.getItem( position );                  LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);                  View rowView = inflater.inflate(R.layout.achievements_item, parent, false);                 TextView textView1 = (TextView) rowView.findViewById(R.id.chat_info);                 TextView textView2 = (TextView) rowView.findViewById(R.id.chat_message);                  textView1.setText(row.getName1());                 textView2.setText(row.getName2());                  textView1.setOnClickListener(new View.OnClickListener()                   {                       @Override public void onClick(View view)                       {                           Toast.makeText(m_context, "clicked first field:" + row.name1, Toast.LENGTH_SHORT).show();                       }                     });                  textView2.setOnClickListener(new View.OnClickListener()                   {                       @Override public void onClick(View view)                       {                            Toast.makeText(m_context, "clicked second field" + row.name2 + ", **copied to clipboard**", Toast.LENGTH_SHORT).show();                            ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);                            ClipData clip              = ClipData.newPlainText(row.name1, row.name2);                            clipboard.setPrimaryClip(clip);                       }                     });                 return rowView;             }//getView         }//class ChatArrayAdapter //================================================== 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment