Intereting Posts

Выбор TextView с помощью Spannable и LinkMovementMethod

То, что я сделал до сих пор, представляет собой просмотр списка текстовых просмотров, имеющих обычный текст и интерактивные пробелы: Нетронутый предмет

Нажав на span, я открываю URL-адрес, щелкнув элемент «Вид вокруг» textView, чтобы listView OnItemClickListener к деталям, это нормально: Элемент коснулся вне textView

Теперь проблема заключается в следующем:

Элемент textView нормальный текст коснулсяЭлемент textView span коснулся Прикосновение к textView делает обычный текст выделенным цветом (с тем же цветом, который имеет при выборе элемента полностью), событие OnTouchListener срабатывает, но не событие OnFocusChangeListener и элемент View не получает стиль выделения. Пробовал все варианты FOCUS_BLOCK_DESCENDANTS для listView, item View, textView focusable был включен или отключен с тем же результатом.

К счастью, событие textView OnClickListener срабатывает таким образом, но это настолько уродливо: текст невидим, пока сенсорный звук не OnClickListener , так как выделенный цвет текста совпадает с цветом элемента, нет другого указания, что пользователь переходит к деталям Кроме этого уродливого текста, исчезающего.

Я подозреваю, что это происходит из-за того, что содержимое textView является Spannable , а части, которые не являются CliclableSpan-s, ведут себя странным образом.

Любой шанс, что я могу выбрать элемент, как только нормальный текст будет затронут?


Элемент списка listView:

 <?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:descendantFocusability="blocksDescendants" android:orientation="horizontal" > <ImageView android:id="@+id/icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginBottom="5dp" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_marginTop="5dp" android:focusable="false" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:id="@+id/title" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:layout_marginTop="5dp" android:focusable="false" android:text="" android:textAppearance="?android:attr/textAppearanceLarge" android:textStyle="bold" /> <TextView android:id="@+id/info" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="4dp" android:layout_marginLeft="4dp" android:layout_marginRight="4dp" android:focusable="false" android:text="" android:textAppearance="?android:attr/textAppearanceSmall" /> <TextView android:id="@+id/details" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="4dp" android:layout_marginLeft="4dp" android:layout_marginRight="4dp" android:focusable="false" android:gravity="fill_horizontal|right" android:text="" android:textAppearance="?android:attr/textAppearanceMedium"/> </LinearLayout> </LinearLayout> 

С текстовым представлением setClickable (false) я могу отключить этот странный стиль выбора таким образом, что ничего не происходит при касании области просмотра текста, но не полезно, но может быть полезно для решения.

Также попытался добавить не фокусируемую и не кликаемую кнопку для каждого элемента, когда он коснулся всего элемента, и когда прикосновение выпущено, событие клика элемента передается, это именно то, что я ожидал от textView с содержимым Spannable.

Solutions Collecting From Web of "Выбор TextView с помощью Spannable и LinkMovementMethod"

Вы пытались настроить фон вашего TextView на Android по умолчанию list_selector_background ?

  textView.setMovementMethod(LinkMovementMethod.getInstance()); textView.setBackgroundResource(android.R.drawable.list_selector_background); 

Для меня это, кажется, дает результат, который вы хотите.

ОБНОВЛЕНИЕ. Увидев, что элемент является не только одним TextView

Ну, это не идеальное решение (так как, вероятно, лучше как-то исправлять взаимодействие с TextView – ListView), но он работает достаточно хорошо.

Я выяснил, что вместо того, чтобы устанавливать метод перемещения в TextView (который вызывает проблему), проще всего проверять onItemClick() в ListView (после однозначного подтверждения щелчка), чтобы увидеть, нужно ли запускать onClick() На нашем ClickableSpans:

 public class MyActivity extends Activity { private final Rect mLastTouch = new Rect(); private boolean spanClicked(ListView list, View view, int textViewId) { final TextView widget = (TextView) view.findViewById(textViewId); list.offsetRectIntoDescendantCoords(widget, mLastTouch); int x = mLastTouch.right; int y = mLastTouch.bottom; x -= widget.getTotalPaddingLeft(); y -= widget.getTotalPaddingTop(); x += widget.getScrollX(); y += widget.getScrollY(); final Layout layout = widget.getLayout(); final int line = layout.getLineForVertical(y); final int off = layout.getOffsetForHorizontal(line, x); final Editable buffer = widget.getEditableText(); final ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class); if (link.length == 0) return false; link[0].onClick(widget); return true; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if (spanClicked(listView, view, R.id.details)) return; // no span is clicked, normal onItemClick handling code here .. } }); listView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { mLastTouch.right = (int) event.getX(); mLastTouch.bottom = (int) event.getY(); } return false; } }); // ... } } 

Метод spanClicked() в основном представляет собой сокращенную версию метода onTouchEvent() в рамках. Чтобы зафиксировать последние координаты MotionEvent (чтобы проверить событие щелчка), мы просто добавляем OnTouchListener в наш ListView.

Я думаю, что лучший способ решить эту проблему – использовать селектор. Вы можете выбрать цвет backgroun, чтобы они увидели то же самое

Пример кода выбора:

 <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:color="#000000" /> <!-- pressed --> <item android:state_focused="true" android:color="#000000" /> <!-- focused --> <item android:color="#FFFFFF" /> <!-- default --> </selector> 

Реализуйте sth, как это, к вашей ссылке.

Дайте мне знать о результате

Цитата из документации setMovementMethod() TextView

Устанавливает метод перемещения (обработчик клавиш стрелки), который будет использоваться для этого TextView. Это может быть null, чтобы запретить использование клавиш со стрелками для перемещения курсора или прокрутки представления.

Будьте внимательны, если вы хотите, чтобы TextView с функцией прослушивания клавиш или движения не был настраиваемым, или если вы хотите, чтобы TextView без прослушивателя клавиш или метода перемещения был сфокусирован, вы должны вызвать android.view.View.setFocusable (boolean) Снова после вызова этого, чтобы получить фокусируемость назад, как вы этого хотите.

Во втором абзаце объясняется, что мы должны явно вызвать метод setFocusable после установки LinkMovementMethod для обеспечения фокусируемости, как мы этого хотим.

Вам нужно сделать это в коде после раздувания элемента списка. Когда вы сможете получить фокус, вы можете установить селектор на другой цветной текст.

Вот исходный код setMovementMethod .

Используйте setHighlightColor(Color.TRANSPARENT); TextView setHighlightColor(Color.TRANSPARENT);