im.zico.fancy.common.widget.HackyMovementMethod.java Source code

Java tutorial

Introduction

Here is the source code for im.zico.fancy.common.widget.HackyMovementMethod.java

Source

/*
 * Copyright (C) 2014 Peter Cai
 *
 * This file is part of BlackLight
 *
 * BlackLight is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * BlackLight is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with BlackLight.  If not, see <http://www.gnu.org/licenses/>.
 */

package im.zico.fancy.common.widget;

import android.support.v4.content.ContextCompat;
import android.text.Spannable;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.method.Touch;
import android.text.style.BackgroundColorSpan;
import android.text.style.ClickableSpan;
import android.view.MotionEvent;
import android.widget.TextView;

import im.zico.fancy.R;

/*
  Hack to fix conflict between URLSpan and parent's OnClickListener
*/
public class HackyMovementMethod extends LinkMovementMethod {

    private static HackyMovementMethod sInstance;

    private BackgroundColorSpan mGray;

    private boolean mIsLinkHit = false;

    public static HackyMovementMethod getInstance() {
        if (sInstance == null) {
            sInstance = new HackyMovementMethod();
        }

        return sInstance;
    }

    @Override
    public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
        if (mGray == null) {
            mGray = new BackgroundColorSpan(
                    ContextCompat.getColor(widget.getContext(), R.color.alpha_spannable_pressed));
        }

        mIsLinkHit = false;

        int action = event.getAction();

        if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_UP) {
            int x = (int) event.getX();
            int y = (int) event.getY();
            x -= widget.getTotalPaddingLeft();
            y -= widget.getTotalPaddingTop();
            x += widget.getScrollX();
            y += widget.getScrollY();

            int line = widget.getLayout().getLineForVertical(y);
            int offset = widget.getLayout().getOffsetForHorizontal(line, x);

            ClickableSpan[] spans = buffer.getSpans(offset, offset, ClickableSpan.class);

            if (spans.length != 0) {
                int start = buffer.getSpanStart(spans[0]);
                int end = buffer.getSpanEnd(spans[0]);
                mIsLinkHit = true;
                if (action == MotionEvent.ACTION_DOWN) {
                    buffer.setSpan(mGray, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                } else if (action == MotionEvent.ACTION_UP) {
                    spans[0].onClick(widget);
                    buffer.removeSpan(mGray);
                }
                return true;
            }
        } else {
            buffer.removeSpan(mGray);
        }

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

    public boolean isLinkHit() {
        boolean ret = mIsLinkHit;
        mIsLinkHit = false;
        return ret;
    }
}