Как установить clickablespan для TextView в RecyclerView

У меня есть recyclerviwq с textvies, а текст в textview имеет urlss, и я хочу установить clickcablespan в textview и захватить URL.

Я использую этот принятый ответ, и он не работает.

Это мой код:

    public class LibAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private Context mContext;
    private List<LibItem> mLibItemList;

    private final int HEAD_VIEW = 0;
    private final int LIB_VIEW = 1;

    public LibAdapter(List<LibItem> libItems, Context context) {
        super();
        this.mLibItemList = libItems;
        this.mContext = context;
    }

    @Override
    public int getItemViewType(int position) {
        if (isPositionItem(position)) {
            return HEAD_VIEW;
        }
        return LIB_VIEW;
    }

    private boolean isPositionItem(int position) {
        return position == 0;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == LIB_VIEW) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.library_item, parent, false);
            return new LibHolder(view);
        } else  if (viewType == HEAD_VIEW) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.about_hedaer, parent, false);
            return  new HeadHolder(view);
        }
        return null;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof LibHolder) {
            final LibItem libItem = mLibItemList.get(position);
            ((LibHolder) holder).libName.setText(libItem.getLibName());
            ((LibHolder) holder).libCopy.setText(Html.fromHtml(libItem.getLibCopy()));
            ((LibHolder) holder).libLic.setText(mContext.getString(R.string.proj_license));

            setTextViewHTML(((LibHolder) holder).libWeb, mContext.getString(R.string.proj_code, libItem.getLibWebs()));
            ((LibHolder) holder).libLic.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.d("LibAdapter", "License of " + libItem.getLibName() + "clicked");
                }
            });
        } else if (holder instanceof HeadHolder){
            String versionCode = BuildConfig.VERSION_NAME;
            ((HeadHolder) holder).abtVersion.setText(mContext.getString(R.string.app_version, versionCode));
        }
    }

    protected void makeLinkClickable(SpannableStringBuilder strBuilder, final URLSpan span)
    {
        int start = strBuilder.getSpanStart(span);
        int end = strBuilder.getSpanEnd(span);
        int flags = strBuilder.getSpanFlags(span);
        ClickableSpan clickable = new ClickableSpan() {
            public void onClick(View view) {
                Log.d("LipAdapter", span.getURL());
            }
        };
        strBuilder.setSpan(clickable, start, end, flags);
        strBuilder.removeSpan(span);
    }

    protected void setTextViewHTML(TextView text, String html)
    {
        CharSequence sequence = Html.fromHtml(html);
        SpannableStringBuilder strBuilder = new SpannableStringBuilder(sequence);
        URLSpan[] urls = strBuilder.getSpans(0, sequence.length(), URLSpan.class);
        for(URLSpan span : urls) {
            makeLinkClickable(strBuilder, span);
        }
        text.setText(strBuilder);
        text.setMovementMethod(LinkMovementMethod.getInstance());
    }



    @Override
    public int getItemCount() {
        return mLibItemList.size();
    }

    public class LibHolder extends RecyclerView.ViewHolder {
        @BindView(R.id.lib_name) TextView libName;
        @BindView(R.id.lib_website) TextView libWeb;
        @BindView(R.id.lib_copyright) TextView libCopy;
        @BindView(R.id.lib_license) TextView libLic;

        public LibHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
    }

    public class  HeadHolder extends RecyclerView.ViewHolder {
        @BindView(R.id.abt_version) TextView abtVersion;

        public HeadHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
    }
}

С текстом все в порядке, но по ссылке отказались нажимать. пожалуйста, у вас есть решение для этого?

2 ответа

Вы пытались это::

  protected void makeLinkClickable(SpannableStringBuilder strBuilder, final URLSpan span)
{
    int start = strBuilder.getSpanStart(span);
    int end = strBuilder.getSpanEnd(span);
    int flags = strBuilder.getSpanFlags(span);
    ClickableSpan clickable = new ClickableSpan() {
        public void onClick(View view) {
            Log.d("LipAdapter", span.getURL());
        }
    };
    strBuilder.setSpan(clickable, start, end, flags);
    strBuilder.removeSpan(span);
}

Но вам нужно сделать что-то вроде этого:

protected void makeLinkClickable(SpannableStringBuilder strBuilder, final URLSpan span)
{
    int start = strBuilder.getSpanStart(span);
    int end = strBuilder.getSpanEnd(span);
    int flags = strBuilder.getSpanFlags(span);


    ClickableSpan clickable = new ClickableSpan() {
        @Override
        public void onClick(View widget) {
            Log.d("LipAdapter", span.getURL());
        }

        @Override
        public void updateDrawState(TextPaint ds) {
            super.updateDrawState(ds);
        }
    };

    strBuilder.setSpan(clickable, start, end, flags);
    strBuilder.removeSpan(span);
}

Надеюсь, что это будет работать для других

У меня была такая же проблема, и мне пришлось набрать sequence в Spannable чтобы это работало.

Просто замени

SpannableStringBuilder strBuilder = new SpannableStringBuilder(sequence);

с

Spannable strBuilder = (Spannable) sequence;
Другие вопросы по тегам