LinkSpan.java revision d832154e333a3a45b5faecd518b664ddd297183c
1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.setupwizardlib.span;
18
19import android.content.Context;
20import android.graphics.Typeface;
21import android.os.Build;
22import android.text.TextPaint;
23import android.text.style.ClickableSpan;
24import android.util.Log;
25import android.view.View;
26
27/**
28 * A clickable span that will listen for click events and send it back to the context. To use this
29 * class, implement {@link com.android.setupwizardlib.span.LinkSpan.OnClickListener} in your
30 * context (typically your Activity).
31 *
32 * <p />Note on accessibility: For TalkBack to be able to traverse and interact with the links, you
33 * should use {@code LinkAccessibilityHelper} in your {@code TextView} subclass. Optionally you can
34 * also use {@code RichTextView}, which includes link support.
35 */
36public class LinkSpan extends ClickableSpan {
37
38    /*
39     * Implementation note: When the orientation changes, TextView retains a reference to this span
40     * instead of writing it to a parcel (ClickableSpan is not Parcelable). If this class has any
41     * reference to the containing Activity (i.e. the activity context, or any views in the
42     * activity), it will cause memory leak.
43     */
44
45    /* static section */
46
47    private static final String TAG = "LinkSpan";
48
49    private static final Typeface TYPEFACE_MEDIUM =
50            Typeface.create("sans-serif-medium", Typeface.NORMAL);
51
52    public interface OnClickListener {
53        void onClick(LinkSpan span);
54    }
55
56    /* non-static section */
57
58    private final String mId;
59
60    public LinkSpan(String id) {
61        mId = id;
62    }
63
64    @Override
65    public void onClick(View view) {
66        final Context context = view.getContext();
67        if (context instanceof OnClickListener) {
68            ((OnClickListener) context).onClick(this);
69            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
70                view.cancelPendingInputEvents();
71            }
72        } else {
73            Log.w(TAG, "Dropping click event. No listener attached.");
74        }
75    }
76
77    @Override
78    public void updateDrawState(TextPaint drawState) {
79        super.updateDrawState(drawState);
80        drawState.setUnderlineText(false);
81        drawState.setTypeface(TYPEFACE_MEDIUM);
82    }
83
84    public String getId() {
85        return mId;
86    }
87}
88