Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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_parent"
    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"/>

The ListView is within a LinearLayout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/custom_border">
    <ListView
        android:id="@+id/chat_text_display"
        android:layout_width="match_parent"
        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:dividerHeight="0dp"
        android:stackFromBottom="true"
        android:transcriptMode="alwaysScroll"/>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0"
        android:orientation="horizontal"
        android:layout_marginTop="2dp"
        android:layout_marginRight="1dp"
        android:layout_marginBottom="2dp"
        android:layout_marginLeft="2dp">
        <Button
            android:id="@+id/text_send"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="0"
            android:layout_gravity="center_vertical"
            android:enabled="false"
            android:text="@string/chat_button"/>
        <EditText
            android:id="@+id/chat_text_compose"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:minLines="3"
            android:maxLines="3"
            android:paddingLeft="8dp"
            android:background="@color/WHITE"
            android:hint="@string/chat_hint"/>
    </LinearLayout>
</LinearLayout>

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:

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

I can insert a "stand alone" TextView within the LinearLayout with a android:textIsSelectable="true" and the copy dialog works as it should; meaning that it will stay visible until I have selected "copy".

The last piece of information I can offer is that my LinearLayout is within a tabbed activity using fragments with a ViewPager. I just don't see how this can be the issue because, like I said, I can add another element (e.g., TextView) within the LinearLayout and the Copy dialog acts perfectly. I thought I would add this piece for full clarity.

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?

NEW INFORMATION!!!

When I select the text in the "chat_text_compose" EditText, the Copy toolbar appears normally. At this point, I can successfully select the text in my TextView areas. Weird.

UPDATE: The code that controls this layout

public class Chat extends Fragment {

    private View rootView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.chat, container, false);
        return rootView;
    }

    @Override
    public void onViewCreated(View rootView, Bundle savedInstanceState) {
        super.onViewCreated(rootView, savedInstanceState);
        displayChats();
    }

    @Override
    public void onResume() {
        super.onResume();
        displayChats();
    }

    @Override
    public View getView() {
        final Button sendChatButton = (Button) rootView.findViewById(R.id.text_send);
        final EditText chatEntryWindow = (EditText) rootView.findViewById(R.id.chat_text_compose);

        // Check to see if the text entry field is empty. If it is empty, disable the "Send" button.
        chatEntryWindow.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if(s.length() != 0){
                    sendChatButton.setEnabled(true);
                } else {
                    sendChatButton.setEnabled(false);
                }
            }

            @Override
            public void afterTextChanged(Editable s) {}
        });

        // Send the chat
        if(sendChatButton != null) {
            sendChatButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Date rightNow = new Date();
                    SimpleDateFormat timeSDF = new SimpleDateFormat(Constants.SIMPLE_TIME, Locale.US);
                    SimpleDateFormat dateSDF = new SimpleDateFormat(Constants.SIMPLE_DATE, Locale.US);
                    SharedPreferences myAppPreferences = getContext().getSharedPreferences(Constants.PREFS_NAME, Context.MODE_PRIVATE);
                    String message = chatEntryWindow.getText().toString();
                    String username = myAppPreferences.getString("username", Constants.TABLET_ID);
                    Message myMessage = new Message(true, username, message, 0, dateSDF.format(rightNow), timeSDF.format(rightNow));
                    if(!message.equals("")){
                        LogChat logChat = new LogChat(getActivity());
                        logChat.addNewMessage(myMessage);
                        new SendChat(getActivity(), message, username).execute();
                        chatEntryWindow.setText("");
                        sendChatButton.setEnabled(false);
                        if(v != null){
                            InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
                            inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
                        }
                        displayChats();
                    }
                }
            });
        }
        return super.getView();
    }

    public void displayChats(){
        DatabaseHelper myDBHelper = new DatabaseHelper(getActivity());
        final Cursor chatsCursor = myDBHelper.getChatsCursor();
        String[] fromColumns = {"messageInfo","messageText"};
        int[] toViews = {R.id.chat_information, R.id.chat_message};
        SimpleCursorAdapter simpleCursorAdapter = new SimpleCursorAdapter(getContext(), R.layout.line_of_chat, chatsCursor, fromColumns, toViews, 0);
        ListView myListView = (ListView) rootView.findViewById(R.id.chat_text_display);

        // Draw the list
        myListView.setAdapter(simpleCursorAdapter);

        myDBHelper.close();
    }
}
like image 571
Brian Avatar asked Sep 08 '16 19:09

Brian


1 Answers

Use CustomAdapter as you need to set registerForContextMenu() to your both of TextViews as follows.

registerForContextMenu(holder.chatMessage);
registerForContextMenu(holder.chatInfo);

Use onCreateContextMenu to create context menu and to show the selected text

@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
    TextView textView = (TextView) view;
    menu.setHeaderTitle(textView.getText()).add(0, 0, 0, R.string.menu_copy_to_clipboard);
    clipBoardText = textView.getText().toString();
}

And use onContextItemSelected for copying the text to clip board

@Override
public boolean onContextItemSelected(MenuItem item) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        final android.content.ClipboardManager clipboardManager = (android.content.ClipboardManager)
                getSystemService(Context.CLIPBOARD_SERVICE);
        final android.content.ClipData clipData = android.content.ClipData
                .newPlainText("label", clipBoardText);
        clipboardManager.setPrimaryClip(clipData);
    } else {
        ((ClipboardManager) getSystemService(CLIPBOARD_SERVICE)).setText(clipBoardText);
    }
    return true;
}

I have tried with this. You have to long click on the textView from which you want the text to be copied. It shows a dialog and after you click copy text, the text will be copied to clipboard. You can paste it anywhere you want. The example I have tried is here.

like image 159
Nikhil Avatar answered Sep 29 '22 00:09

Nikhil