TextView 에 ClickableSpan 과 LinkMovement Method 의 관 계 를 추가 합 니 다.
4857 단어 Android
TextView tv = (TextView) findViewById(R.id.textview);
SpannableString ss = new SpannableString("Java Android");
ss.setSpan(new MyClickSpan("java"),0,4,0);tv.setText(ss);
4.567913.다시 실행 하면 클릭 할 수 있 습 니 다.여기 서 기본적으로 만족 하 는 대부분의 개발 업 무 를 발견 할 수 있 습 니 다.그러나 어 려 운 개발 자로 서 제품 매니저 를 만족 시 켜 야 합 니 다.
먼저 클릭 한 문 제 를 말 하고,뒤에 다시 그림 과 글 을 혼합 하여 배열 하 다.위의 코드 는 현재 로 서 는 문제 가 없 는 것 같 지만 필 자 는 현재 두 가지 문 제 를 발견 했다.
1.textview 가 일부 파일 의 클릭 이벤트 에 응답 하 는 것 을 제외 하고 나머지 부분 이 다른 작업 에 응답 하면 문제 가 발생 합 니 다.(동료 가 span 의 onclick 과 textview 의 click 을 되 돌려 줍 니 다)
2.textview 가 설정 한 max Line 과 텍스트 높이 가 max line 의 값 을 초과 하면 텍스트 가 굴 러 갈 수 있 습 니 다.ellipsize 의 값 을 설정 하 더 라 도 LinkMovement Method 가 설정 되 어 있 기 때 문 입 니 다.
이 두 버그 의 존 재 는 반드시 테스트 를 통과 할 수 없 기 때문에 각종 도 모 와 구 글 은 만 족 스 러 운 답 을 찾 지 못 해 스스로 TextView 소스 코드 를 뜯 어 먹 을 수 밖 에 없 었 다.
클릭 이 onClick 이나 onTouch 이벤트 와 관련 되 기 때문에 먼저 onClick 을 찾 았 으 나 TextView 에서 onClick 관련 코드 를 찾 지 못 했 습 니 다.그리고 온 터치 이벤트 방법 을 보면,
그래서 아래 코드 를 찾 았 습 니 다.
,
tv.setMovementMethod(LinkMovementMethod.getInstance());
코드 중if ((mMovement != null || onCheckIsTextEditor()) && isEnabled()
&& mText instanceof Spannable && mLayout != null) {
boolean handled = false;
if (mMovement != null) {
handled |= mMovement.onTouchEvent(this, (Spannable) mText, event);
}
final boolean textIsSelectable = isTextSelectable();
if (touchIsFinished && mLinksClickable && mAutoLinkMask != 0 && textIsSelectable) {
// The LinkMovementMethod which should handle taps on links has not been installed
// on non editable text that support text selection.
// We reproduce its behavior here to open links for these.
ClickableSpan[] links = ((Spannable) mText).getSpans(getSelectionStart(),
getSelectionEnd(), ClickableSpan.class);
if (links.length > 0) {
links[0].onClick(this);
handled = true;
}
}
부분 은 set Movement Method 방법 으로 설 정 된 대상 입 니 다.LinkMovement Method 의 인 스 턴 스 를 설정 하기 때문에 LinkMovement Method 소스 코드 를 계속 열 어 onTouchEvent 의 코드 를 봅 니 다.
Clickable Span 의 실현 원 리 를 한눈 에 알 수 있다.
tv.setMovement Method(LinkMovement Method.getInstance())때문에;코드 상기 빨간색 두 가지 문 제 를 보고 소스 코드 를 보면 우리 의 해결 방법 은 TextView 에 onTouch Event 를 직접 설정 하 는 것 입 니 다.
다음은 스스로 Clickable Span 클릭 을 실현 하 는 코드 입 니 다. if (mMovement != null) {
handled |= mMovement.onTouchEvent(this, (Spannable) mText, event);
}
디 버 깅 을 실행 하 였 는데,더 이상 상술 한 두 가지 문제 가 없 음 을 발견 하여 큰 성 과 를 거 두 었 다.
최종 코드 는 아주 적은 것 이지 만 처음에 문 제 를 만 나 어떻게 해결 해 야 할 지 모 를 때 소스 코드 를 읽 는 것 이 힘 들 기 때문에 평소에 문 제 를 해결 할 때 소스 코드 를 많이 보 는 것 이 큰 도움 이 된다.구 글 이 안 드 로 이 드 를 오픈 해 주 셔 서 감사합니다.
사용자 정의 클릭 가능 한 텍스트 색상 을 포함 하여 MyClickSpan 코드 를 추가 합 니 다. @Override
public boolean onTouchEvent(TextView widget, Spannable buffer,
MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_UP ||
action == MotionEvent.ACTION_DOWN) {
int x = (int) event.getX();
int y = (int) event.getY();
x -= widget.getTotalPaddingLeft();
y -= widget.getTotalPaddingTop();
x += widget.getScrollX();
y += widget.getScrollY();
Layout layout = widget.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
if (link.length != 0) {
if (action == MotionEvent.ACTION_UP) {
link[0].onClick(widget);
} else if (action == MotionEvent.ACTION_DOWN) {
Selection.setSelection(buffer,
buffer.getSpanStart(link[0]),
buffer.getSpanEnd(link[0]));
}
return true;
} else {
Selection.removeSelection(buffer);
}
}
return super.onTouchEvent(widget, buffer, event);
}
작가 가 문 제 를 해결 한 후에 stackoverflow 에서 발견 한 똑 같은 문제 에 링크 를 첨부 하여 참고 하 시기 바 랍 니 다.
https://stackoverflow.com/questions/5183645/android-clickablespan-in-clickable-textview/40214599#40214599
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.