1be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang/*
2be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang * Copyright (C) 2015 The Android Open Source Project
3be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang *
4be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang * Licensed under the Apache License, Version 2.0 (the "License");
5be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang * you may not use this file except in compliance with the License.
6be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang * You may obtain a copy of the License at
7be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang *
8be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang *      http://www.apache.org/licenses/LICENSE-2.0
9be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang *
10be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang * Unless required by applicable law or agreed to in writing, software
11be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang * distributed under the License is distributed on an "AS IS" BASIS,
12be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang * See the License for the specific language governing permissions and
14be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang * limitations under the License.
15be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang */
16be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang
17be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tangpackage com.android.settings;
18be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang
19be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tangimport android.text.Spannable;
20be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tangimport android.text.TextPaint;
21be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tangimport android.text.method.LinkMovementMethod;
22be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tangimport android.text.style.ClickableSpan;
23be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tangimport android.view.View;
24be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tangimport android.widget.TextView;
25be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tangimport android.widget.TextView.BufferType;
26be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang
27be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang/**
28be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang * Utility class to create clickable links inside {@link TextView TextViews}.
29be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang */
30be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tangpublic class LinkifyUtils {
31be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang    private static final String PLACE_HOLDER_LINK_BEGIN = "LINK_BEGIN";
32be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang    private static final String PLACE_HOLDER_LINK_END = "LINK_END";
33be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang
34be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang    private LinkifyUtils() {
35be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang    }
36be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang
37be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang    /** Interface that handles the click event of the link */
38be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang    public interface OnClickListener {
39be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang        void onClick();
40be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang    }
41be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang
42be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang    /**
43be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang     * Applies the text into the {@link TextView} and part of it a clickable link.
44be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang     * The text surrounded with "LINK_BEGIN" and "LINK_END" will become a clickable link. Only
45be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang     * supports at most one link.
46be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang     * @return true if the link has been successfully applied, or false if the original text
47be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang     *         contains no link place holders.
48be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang     */
49be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang    public static boolean linkify(TextView textView, StringBuilder text,
50be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang            final OnClickListener listener) {
51be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang        // Remove place-holders from the string and record their positions
52be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang        final int beginIndex = text.indexOf(PLACE_HOLDER_LINK_BEGIN);
53be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang        if (beginIndex == -1) {
54be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang            textView.setText(text);
55be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang            return false;
56be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang        }
57be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang        text.delete(beginIndex, beginIndex + PLACE_HOLDER_LINK_BEGIN.length());
58be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang        final int endIndex = text.indexOf(PLACE_HOLDER_LINK_END);
59be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang        if (endIndex == -1) {
60be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang            textView.setText(text);
61be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang            return false;
62be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang        }
63be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang        text.delete(endIndex, endIndex + PLACE_HOLDER_LINK_END.length());
64be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang
65be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang        textView.setText(text.toString(), BufferType.SPANNABLE);
66be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang        textView.setMovementMethod(LinkMovementMethod.getInstance());
67be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang        Spannable spannableContent = (Spannable) textView.getText();
68be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang        ClickableSpan spannableLink = new ClickableSpan() {
69be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang            @Override
70be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang            public void onClick(View widget) {
71be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang                listener.onClick();
72be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang            }
73be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang
74be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang            @Override
75be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang            public void updateDrawState(TextPaint ds) {
76be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang                super.updateDrawState(ds);
77be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang                ds.setUnderlineText(false);
78be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang            }
79be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang        };
80be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang        spannableContent.setSpan(spannableLink, beginIndex, endIndex,
81be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
82be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang        return true;
83be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang    }
84be794c30ca49c17521e66482ce30c94ffb2ec8eeLifu Tang}
85