Подтвердить что ты не робот

Почему мой Android UI действует неуловимо, когда я пытаюсь выбрать текст?

Я работаю над Android-приложением (API 15 и ниже). В моем пользовательском интерфейсе у меня есть элемент TextView, который я бы хотел, чтобы люди могли выбирать и копировать. Вот как выглядит мой элемент:

<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>

Этот TextView находится внутри ListView, заполненного SimpleCursorAdapter. Этот ListView выглядит следующим образом:

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

ListView находится в 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>

Всякий раз, когда я пытаюсь щелкнуть текст в чате chat_info или chat_message, ничего не происходит. Однако, когда я пытаюсь дважды щелкнуть текст:

  • весь мой пользовательский интерфейс сдвигается вниз
  • В верхней части экрана появляется "панель инструментов".
  • "Панель инструментов" сразу исчезает, и мой дисплей сдвигается назад.

В "панели инструментов" это то, что я вижу:

Похоже, это диалоговое окно копирования, но оно немедленно исчезает.

Я могу вставить "отдельный" TextView в LinearLayout с android:textIsSelectable="true", и диалог копирования работает так, как должен; что он останется видимым до тех пор, пока я не выберу "копию".

Последняя часть информации, которую я могу предложить, заключается в том, что моя LinearLayout находится в активности с вкладками, используя фрагменты с ViewPager. Я просто не понимаю, как это может быть проблемой, потому что, как я уже сказал, я могу добавить еще один элемент (например, TextView) в LinearLayout, и диалог Copy отлично работает. Я думал, что добавлю этот кусок для полной ясности.

Все, что я хочу сделать, это выбрать текст в chat_info или chat_message, чтобы я мог скопировать и вставить текст в другое место.

Любые идеи?

НОВАЯ ИНФОРМАЦИЯ!!!

Когда я выбираю текст в редакторе "chat_text_compose" EditText, панель инструментов "Копировать" появляется нормально. На этом этапе я может успешно выбрать текст в моих областях TextView. Weird.

UPDATE: код, управляющий этим макетом

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();
    }
}
4b9b3361

Ответ 1

Как FYI, на всякий случай кто-нибудь другой ищет ответ.

Я отказался от этого, используя "android: textIsSelectable = 'true", и пошел другим путем. Вместо этого я установил "onItemLongClickListener()" и использовал ClipboardManager для захвата текста в чате:

public void displayChats(){
        final Context context = getContext();
        final ClipboardManager clipboardManager = (ClipboardManager)context.getSystemService(context.CLIPBOARD_SERVICE);
        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);

        myListView.setOnLongClickListener(new AdapterView.OnItemLongClickListener(){
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id){
                TextView chatText = (TextView)view.findViewById(R.id.chat_message);
                ClipData clipData = ClipData.newPlainText("copied chat", chatText.getText.toString());
                if(clipboardManager.hasPrimaryClip()){
                    Toast.makeText(this, "copied text", Toast.LENGTH_LONG).show();
                }
                return false;
            }
        });
        myDBHelper.close();
    }

Ответ 2

Используйте CustomAdapter, так как вам нужно установить registerForContextMenu() на оба из TextViews следующим образом.

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

Используйте onCreateContextMenu для создания context menu и для отображения выделенного текста

@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();
}

И используйте onContextItemSelected для копирования текста в 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;
}

Я пробовал с этим. Вам нужно долго нажимать на textView, из которого вы хотите скопировать текст. Он показывает dialog, и после того, как вы нажмете копию текста, текст будет скопирован на clipboard. Вы можете вставлять его в любом месте. Пример, который я пробовал, здесь.

Ответ 3

Ожидается один клик. Android не работает на одном клике.

Вы вводите режим действия для копирования. Режим действия - это состояние действия, при котором панель инструментов отключается для набора команд, поддерживающих контекст (в этом случае команды копирования/вставки). Похоже, вы входите в него, а затем сразу же покидаете его, возможно, потому, что теряете фокус на другом элементе.

Ответ 4

Возможно, вы должны использовать registerForContextMenu(yourTextView);, ваш TextView будет зарегистрирован для получения событий контекстного меню. И вы сможете получить текст из вашего текстового поля в буфер обмена, используя OnCreateContextMenu.

    @Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
    //user has long pressed your TextView
    menu.add(0, v.getId(), 0, "your text...copy blbblaba");

    //cast the received View to TextView so that you can get its text
    TextView yourTextView = (TextView) v;

    //place your TextView text in clipboard
    ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); 
    clipboard.setText(yourTextView.getText());
}