안드로이드 스크롤 가능 textView

8422 단어
프로젝트에서 이러한 수요에 부닥치다
1. 한 단락의 문자로 최대 두 줄을 표시하고 어떤 단어를 클릭하여 A페이지에 들어가고 다른 단어를 클릭하면 B페이지에 들어간다.
2. 문장이 너무 길면 이textView를 위아래로 스크롤할 수 있지만 textView의 높이는 원래 두 줄의 높이여서 높일 수 없고 단어의 클릭 이벤트가 사라질 수 없습니다.
3. 이textView는recycler VIew에 끼워져 있기 때문에textView를 굴릴 때recyclerView를 굴릴 수 없습니다.그리고 성능 문제를 위해scrollView에textView를 내장하는 방식을 사용할 수 없기 때문에 아래의 방법을 사용했습니다.
사고방식이 비교적 간단하여textView에서 구체적인 어떤 단어의 클릭 이벤트를 실현하려면 textView를 사용해야 한다.append (클릭 가능한 계승spannable 클래스만 있으면 됩니다)
우선 이textView의 레이아웃은

여기 maxLines=2 즉 최대 두 줄을 표시하는 것을 주의하세요. 여기 이렇게 설정하는 것은 주로 뒤에 이textView 높이를 설정하기 위해서입니다.
다음은 이 TextView를 초기화하고 코드에 클릭할 수 있는 단어를 설정하고textView를 실행합니다.setMovementMethod() - TextView를 세로로 스크롤할 수 있습니다.
public static void initCardHeader(final Activity activity, final TextView textView, String userName, String middleText, String restaurantName, final long userId , final long restaurantId , TextView ctv_reviewPhoto_count, long reviewCount , int photoCount){
        if(textView==null||activity==null)return;
        textView.setText("");//  textView
        SpannableString userNameSpan = new SpannableString(userName);
        userNameSpan.setSpan(new ClickableSpan() {
            @Override
            public void updateDrawState(TextPaint ds) {
                super.updateDrawState(ds);
                ds.setColor(0xFF505256);
                ds.setAntiAlias(true);//   
                ds.setUnderlineText(false);
                ds.setFakeBoldText(true);//    
            }
            @Override
            public void onClick(View widget) {//         
                JLogUtils.i("Alex","      ,  id "+userId);
                if(QravedApplication.getAppConfiguration().getUserId()!=userId)return;
                JLogUtils.i("Alex","     myQraved");
                if(activity instanceof HomeActivity)((HomeActivity)activity).switchFragment(HomeActivity.FRAGMENT_TYPE_HOME_HOME, HomeActivity.FRAGMENT_TYPE_HOME_MYPROFILE_MYLIST);
            }
        }, 0, userNameSpan.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        textView.append(userNameSpan);
        if(activity instanceof HomeActivity || activity instanceof JournalCommentsActivity) {
            textView.append(middleText);//      

            SpannableString restaurantSpan = new SpannableString(restaurantName);
            restaurantSpan.setSpan(new ClickableSpan() {
                @Override
                public void updateDrawState(TextPaint ds) {
                    super.updateDrawState(ds);
                    ds.setColor(0xFF505256);
                    ds.setAntiAlias(true);//   
                    ds.setUnderlineText(false);
                    ds.setFakeBoldText(true);//    
                }

                @Override
                public void onClick(View widget) {//         
                    JLogUtils.i("Alex", "       ,  id " + restaurantId);
                    Intent intent = new Intent();
                    intent.putExtra("restaurantId", String.valueOf(restaurantId));
                    intent.setClass(activity, RestaurantDetailActivity.class);
                    activity.startActivity(intent);
                    activity.overridePendingTransition(R.anim.enter_righttoleft, R.anim.exit_righttoleft);
                }
            }, 0, restaurantSpan.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            textView.append(restaurantSpan);
        }
        textView.setMovementMethod(AlxLinkMovementMethod.getInstance());// textView      ,           
        ctv_reviewPhoto_count.setText(reviewCount + (reviewCount > 1 ? " reviews" : " review") + " - " + photoCount + (photoCount > 1 ? " photos" :" photo"));
        //            
        ViewTreeObserver observer = textView.getViewTreeObserver();
        observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            
            @Override
            public void onGlobalLayout() {
                // TODO Auto-generated method stub
               
                Layout layout2 = textView.getLayout();
                if(textView!=null&&layout2!=null){
                    int lines = layout2.getLineCount();
                    
                    if(lines!=2)return;//      ,    
                    int textViewHeight = textView.getHeight();//       textView   
                    textView.setMaxHeight(textViewHeight);//  textView          
                    textView.setMaxLines(Integer.MAX_VALUE);//   textView   ,         
                }

            }
        });

    }

다음은 가장 중요한 링크 Movement Method의 쓰기 방법입니다. 이 종류를 사용하면 textView의 세로 스크롤을 실현할 수 있습니다
또한 RecyclerView에서 스크롤 이벤트가 충돌하지 않고 스크롤 후에도 클릭 이벤트를 유지하며 클릭 이벤트의 오류 발생을 방지합니다
package com.imaginato.qravedconsumer.widget;

import android.text.Layout;
import android.text.Selection;
import android.text.Spannable;
import android.text.method.LinkMovementMethod;
import android.text.method.MovementMethod;
import android.text.style.ClickableSpan;
import android.view.MotionEvent;
import android.widget.TextView;

import com.imaginato.qravedconsumer.utils.JLogUtils;

/**
 * Created by Administrator on 2016/3/21.
 */
public class AlxLinkMovementMethod extends LinkMovementMethod{
    @Override
    public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
        if (widget.getLayout().getLineCount() > 1) {
            JLogUtils.i("Alex", "    ");
            boolean ret = mOnTouchEvent(widget, buffer, event);
            widget.getParent().requestDisallowInterceptTouchEvent(true);//     View  touch  
            if(event.getAction()==MotionEvent.ACTION_UP) widget.getParent().requestDisallowInterceptTouchEvent(false);
            JLogUtils.i("Alex","ret "+ret);
            return true;
        } else {//    
            boolean ret =  super.onTouchEvent(widget, buffer, event);
            JLogUtils.i("Alex", "    "+ret);
            return ret;
        }
    }
    private boolean couldClick = true;//          
    private float lastY;

    private boolean mOnTouchEvent(TextView widget, Spannable buffer, MotionEvent event){
        int action = event.getAction();
        switch (event.getAction()){
            case MotionEvent.ACTION_MOVE:
                if(Math.abs(event.getY()-lastY)>10)couldClick = false;//                  
                break;
        }
        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) {
                    JLogUtils.i("Alex","  up "+couldClick);
                    if(couldClick)link[0].onClick(widget);
                } else if (action == MotionEvent.ACTION_DOWN) {
                    lastY = event.getY();
                    Selection.setSelection(buffer,
                            buffer.getSpanStart(link[0]),
                            buffer.getSpanEnd(link[0]));
                    couldClick = true;
                }

                return true;
            } else {
                Selection.removeSelection(buffer);
            }
        }

        return super.onTouchEvent(widget, buffer, event);
    }

    private static AlxLinkMovementMethod hahaInstance;
    public static MovementMethod getInstance() {
        if (hahaInstance == null)
            hahaInstance = new AlxLinkMovementMethod();

        return hahaInstance;
    }

}

좋은 웹페이지 즐겨찾기