วิธีการตั้งค่าส่วนของมุมมองข้อความสามารถคลิกได้


213

ฉันมีข้อความ " Android เป็น Software stack " ในข้อความนี้ฉันต้องการตั้งค่าข้อความ " stack " สามารถคลิกได้ ในแง่ถ้าคุณคลิกที่มันจะถูกเปลี่ยนเส้นทางไปยังกิจกรรมใหม่ (ไม่ใช่ในเบราว์เซอร์)

ฉันพยายาม แต่ฉันไม่ได้รับ


12
"ฉันพยายามแล้ว แต่ฉันไม่ได้รับ" ฉันต้องการทราบว่าคุณได้ลองทำอะไรและคุณจะทำอะไรที่ผิดพลาด
Rashmi.B

คำตอบ:


536

android.text.style.ClickableSpan สามารถแก้ปัญหาของคุณ

SpannableString ss = new SpannableString("Android is a Software stack");
ClickableSpan clickableSpan = new ClickableSpan() {
    @Override
    public void onClick(View textView) {
        startActivity(new Intent(MyActivity.this, NextActivity.class));
    }
    @Override
    public void updateDrawState(TextPaint ds) {
        super.updateDrawState(ds);
        ds.setUnderlineText(false);
    }
};
ss.setSpan(clickableSpan, 22, 27, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

TextView textView = (TextView) findViewById(R.id.hello);
textView.setText(ss);
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setHighlightColor(Color.TRANSPARENT);

ใน XML:

<TextView 
  ...
  android:textColorLink="@drawable/your_selector"
/>

2
คุณสามารถตั้งค่าวัตถุ ClickableSpan หลายรายการในมุมมองข้อความได้หรือไม่?
Jonathan

4
ใช่คุณสามารถตั้งค่าช่วงที่คลิกได้หลายรายการเป็นสตริงที่ขยายได้
degratnik

15
เพื่อให้สีเปลี่ยนเป็นสีน้ำเงินคุณสามารถเพิ่ม: ForegroundColorSpan fcs = new ForegroundColorSpan(Color.BLUE); ss.setSpan(fcs, 22, 27, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
xemacobra

4
สิ่งนี้เกิดขึ้นในกรณีของฉันเพื่อเปลี่ยนสีจากสีน้ำเงินเป็นสีอื่น ตั้งForegroundColorSpanอยู่ในsetSpan หลังจากที่คุณได้ตั้งค่าช่วงที่คลิกได้ วางพื้นหน้าก่อนที่จะคลิกได้ช่วงสีใหม่จะไม่ปรากฏ
Shubham A.

1
ขอบคุณสำหรับบรรทัดนี้ stextView.setMovementMethod (LinkMovementMethod.getInstance ()); textView.setHighlightColor (Color.TRANSPARENT);
ซาสึเกะอุจิวะ

99

ฟังก์ชั่นของฉันสำหรับสร้างหลายลิงก์ภายใน TextView

fun TextView.makeLinks(vararg links: Pair<String, View.OnClickListener>) {
    val spannableString = SpannableString(this.text)
    for (link in links) {
        val clickableSpan = object : ClickableSpan() {
            override fun onClick(view: View) {
                Selection.setSelection((view as TextView).text as Spannable, 0)
                view.invalidate()
                link.second.onClick(view)
            }
        }
        val startIndexOfLink = this.text.toString().indexOf(link.first)
        spannableString.setSpan(clickableSpan, startIndexOfLink, startIndexOfLink + link.first.length,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
    }
    this.movementMethod = LinkMovementMethod.getInstance() // without LinkMovementMethod, link can not click
    this.setText(spannableString, TextView.BufferType.SPANNABLE)
}

ใช้

my_text_view.makeLinks(
        Pair("Terms of Service", View.OnClickListener {
            Toast.makeText(applicationContext, "Terms of Service Clicked", Toast.LENGTH_SHORT).show()
        }),
        Pair("Privacy Policy", View.OnClickListener {
            Toast.makeText(applicationContext, "Privacy Policy Clicked", Toast.LENGTH_SHORT).show()
        }))

XML

<TextView
    android:id="@+id/my_text_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Please accept Terms of Service and Privacy Policy"
    android:textColorHighlight="#f00" // background color when pressed
    android:textColorLink="#0f0"
    android:textSize="20sp" />

การสาธิต

การอ้างอิง

โซลูชันสำหรับล้างการเลือกลิงก์ไฮไลต์ให้ทำตามhttps://stackoverflow.com/a/19445108/5381331


มันทำงานได้อย่างสมบูรณ์แบบ แต่มีสิ่งที่พฤติกรรมแปลก ๆ ปรากฏขึ้น ฉันมีข้อความลงท้ายด้วย "นโยบาย" ที่ไหน "." จะถูกข้ามโดย Spannable ที่คลิกได้ มีใครมีปัญหาเดียวกันไหม ส่วน "." ถูกข้ามเฉพาะถ้าเป็นอักขระสิ้นสุดของมุมมองข้อความ
Nikhil

ทางออกที่ดี แต่ใครบางคนต้องดูแลหากมีการแปลหลายภาษา (แอพหลายภาษา)
Himanshu Mori

ขอบคุณ มันใช้งานได้ดีมาก ฉันต้องการบอกว่าถ้าคุณกำลังตั้งค่าสตริงที่จัดรูปแบบเช่น <string name = "string"> Something% 1 $ s Edit </string> โปรดจำไว้ว่าให้ตั้งค่าสิ่งที่คุณต้องการแทนที่% 1 $ s ก่อนแล้วจึงเรียกใช้เมธอด makeLinks
Rajan Maurya

คุณช่วยบอกได้ไหมว่าฉันจะใช้ฟังก์ชั่นนี้ได้อย่างไรเพราะเมื่อฉันเพิ่งวางเมธอด onCreate ของคุณมันจะแสดงข้อผิดพลาด
BlackBlind

1
@BlackBlind คุณได้รับข้อผิดพลาดใดบ้าง หากมีข้อผิดพลาดในการนำเข้าโปรดนำเข้าอย่างถูกต้อง นอกจากนี้คุณไม่ควรใส่ฟังก์ชั่นภายในสร้างวางไว้ข้างนอก
ฟาน Van Linh

35

คุณสามารถใช้ClickableSpanตามที่อธิบายไว้ในโพสต์นี้

รหัสตัวอย่าง:

TextView myTextView = new TextView(this);
String myString = "Some text [clickable]";
int i1 = myString.indexOf("[");
int i2 = myString.indexOf("]");
myTextView.setMovementMethod(LinkMovementMethod.getInstance());
myTextView.setText(myString, BufferType.SPANNABLE);
Spannable mySpannable = (Spannable)myTextView.getText();
ClickableSpan myClickableSpan = new ClickableSpan() {
   @Override
   public void onClick(View widget) { /* do something */ }
};
mySpannable.setSpan(myClickableSpan, i1, i2 + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

การอ้างอิง


ขอบคุณ @ImranRana, สนับสนุนstartIndexและendIndexตรรกะ
Ravi Vaniya

12

คุณสามารถใช้รหัสตัวอย่าง คุณต้องการเรียนรู้รายละเอียดเกี่ยวกับ ClickableSpan โปรดตรวจสอบเอกสารนี้

  SpannableString myString = new SpannableString("This is example");

            ClickableSpan clickableSpan = new ClickableSpan() {
                    @Override
                    public void onClick(View textView) {
                        ToastUtil.show(getContext(),"Clicked Smile ");
                    }
                };

        //For Click
         myString.setSpan(clickableSpan,startIndex,lastIndex,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)

        //For UnderLine
         myString.setSpan(new UnderlineSpan(),startIndex,lastIndex,0);

        //For Bold
        myString.setSpan(new StyleSpan(Typeface.BOLD),startIndex,lastIndex,0);

        //Finally you can set to textView. 

        TextView textView = (TextView) findViewById(R.id.txtSpan);
        textView.setText(myString);
        textView.setMovementMethod(LinkMovementMethod.getInstance());

10

ฉันทำวิธีผู้ช่วยนี้ในกรณีที่มีคนต้องการตำแหน่งเริ่มต้นและสิ้นสุดจากสตริง

public static TextView createLink(TextView targetTextView, String completeString,
    String partToClick, ClickableSpan clickableAction) {

    SpannableString spannableString = new SpannableString(completeString);

    // make sure the String is exist, if it doesn't exist
    // it will throw IndexOutOfBoundException
    int startPosition = completeString.indexOf(partToClick);
    int endPosition = completeString.lastIndexOf(partToClick) + partToClick.length();

    spannableString.setSpan(clickableAction, startPosition, endPosition,
        Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

    targetTextView.setText(spannableString);
    targetTextView.setMovementMethod(LinkMovementMethod.getInstance());

    return targetTextView;
}

และนี่คือวิธีที่คุณใช้

private void initSignUp() {
    String completeString = "New to Reddit? Sign up here.";
    String partToClick = "Sign up";
    ClickableTextUtil
        .createLink(signUpEditText, completeString, partToClick,
            new ClickableSpan() {
                @Override
                public void onClick(View widget) {
                    // your action
                    Toast.makeText(activity, "Start Sign up activity",
                        Toast.LENGTH_SHORT).show();
                }

                @Override
                public void updateDrawState(TextPaint ds) {
                    super.updateDrawState(ds);
                    // this is where you set link color, underline, typeface etc.
                    int linkColor = ContextCompat.getColor(activity, R.color.blumine);
                    ds.setColor(linkColor);
                    ds.setUnderlineText(false);
                }
            });
}

สิ่งนี้ดีกว่าที่จะต้องคำนึงถึงการแปลเป็นภาษาท้องถิ่น
hiddeneyes02

7
 t= (TextView) findViewById(R.id.PP1);

 t.setText(Html.fromHtml("<bThis is normal text </b>" +
                "<a href=\"http://www.xyz-zyyx.com\">This is cliclable text</a> "));
 t.setMovementMethod(LinkMovementMethod.getInstance());

2
คุณช่วยอธิบายคำตอบของคุณหน่อยได้ไหม คำตอบที่มีคำอธิบายที่ดีกว่าเสมอ ฉันยังแก้ไขเนื่องจากข้อมูลโค้ดของคุณไม่ได้อยู่ในรูปแบบที่ถูกต้อง
Popeye

1
ดูเหมือนว่าลิงก์จะไปยังหน้าเว็บไม่ใช่กิจกรรมตามที่ OP ร้องขอ
William T. Mallard

5

นี่คือKotlinวิธีในการสร้างส่วนของTextViewคลิกได้:

private fun makeTextLink(textView: TextView, str: String, underlined: Boolean, color: Int?, action: (() -> Unit)? = null) {
    val spannableString = SpannableString(textView.text)
    val textColor = color ?: textView.currentTextColor
    val clickableSpan = object : ClickableSpan() {
        override fun onClick(textView: View) {
            action?.invoke()
        }
        override fun updateDrawState(drawState: TextPaint) {
            super.updateDrawState(drawState)
            drawState.isUnderlineText = underlined
            drawState.color = textColor
        }
    }
    val index = spannableString.indexOf(str)
    spannableString.setSpan(clickableSpan, index, index + str.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
    textView.text = spannableString
    textView.movementMethod = LinkMovementMethod.getInstance()
    textView.highlightColor = Color.TRANSPARENT
}

สามารถเรียกหลาย ๆ ครั้งเพื่อสร้างลิงค์หลายลิงค์ภายใน TextView:

makeTextLink(myTextView, str, false, Color.RED, action = { Log.d("onClick", "link") })
makeTextLink(myTextView, str1, true, null, action = { Log.d("onClick", "link1") })

3

คำตอบของฟาน Van Linh รุ่น Kotlin

โปรดทราบว่ามันมีการดัดแปลงเล็กน้อย

fun makeLinks(textView: TextView, links: Array<String>, clickableSpans: Array<ClickableSpan>) {
    val spannableString = SpannableString(textView.text)

    for (i in links.indices) {
        val clickableSpan = clickableSpans[i]
        val link = links[i]

        val startIndexOfLink = textView.text.indexOf(link)

        spannableString.setSpan(clickableSpan, startIndexOfLink, startIndexOfLink + link.length,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
    }

    textView.movementMethod = LinkMovementMethod.getInstance()
    textView.setText(spannableString, TextView.BufferType.SPANNABLE)
}

fun setupClickableTextView() {
    val termsOfServicesClick = object : ClickableSpan() {
        override fun onClick(p0: View?) {
            Toast.makeText(applicationContext, "ToS clicked", Toast.LENGTH_SHORT).show()
        }
    }

    val privacyPolicyClick = object : ClickableSpan() {
        override fun onClick(p0: View?) {
            Toast.makeText(applicationContext, "PP clicked", Toast.LENGTH_SHORT).show()
        }
    }

    makeLinks(termsTextView, arrayOf("terms", "privacy policy"), arrayOf(termsOfServicesClick, privacyPolicyClick))
}


1

ฉันขอแนะนำวิธีการอื่นที่ฉันคิดว่าต้องใช้รหัสน้อยลงและ "เป็นมิตรกับการแปล" มากกว่า

สมมติว่ากิจกรรมปลายทางของคุณเรียกว่า "ActivityStack" กำหนดไว้ในรายการตัวกรองเจตนาสำหรับกิจกรรมด้วยชุดรูปแบบที่กำหนดเอง (เช่น "myappscheme") ใน AndroidManifest.xml:

<activity
    android:name=".ActivityStack">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:host="stack"/>
        <data android:scheme="myappscheme" />
    </intent-filter>
</activity>

กำหนด TextView โดยไม่มีแท็กพิเศษ (เป็นสิ่งสำคัญที่จะไม่ใช้แท็ก "android: autoLink" โปรดดู: https://stackoverflow.com/a/20647011/1699702 ):

<TextView
    android:id="@+id/stackView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/stack_string" />

จากนั้นใช้ลิงก์ที่มีสกีมที่กำหนดเองและโฮสต์ในข้อความของ TextView เป็น (ใน String.xml):

<string name="stack_string">Android is a Software <a href="myappscheme://stack">stack</a></string>

และ "เปิดใช้งาน" ลิงก์พร้อม setMovementMethod () (ใน onCreate () สำหรับกิจกรรมหรือ onCreateView () สำหรับแฟรกเมนต์):

TextView stack = findViewById(R.id.stackView);
stack.setMovementMethod(LinkMovementMethod.getInstance());

กิจกรรมนี้จะเปิดกิจกรรมสแต็กด้วยการแตะที่คำว่า "สแต็ค"


0

คุณสามารถใช้วิธีนี้เพื่อตั้งค่าที่คลิกได้

public void setClickableString(String clickableValue, String wholeValue, TextView yourTextView){
    String value = wholeValue;
    SpannableString spannableString = new SpannableString(value);
    int startIndex = value.indexOf(clickableValue);
    int endIndex = startIndex + clickableValue.length();
    spannableString.setSpan(new ClickableSpan() {
                                @Override
                                public void updateDrawState(TextPaint ds) {
                                    super.updateDrawState(ds);
                                    ds.setUnderlineText(false); // <-- this will remove automatic underline in set span
                                }

                                @Override
                                public void onClick(View widget) {
                                    // do what you want with clickable value
                                }
                            }, startIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    yourTextView.setText(spannableString);
    yourTextView.setMovementMethod(LinkMovementMethod.getInstance()); // <-- important, onClick in ClickableSpan won't work without this
}

นี่คือวิธีการใช้งาน:

TextView myTextView = findViewById(R.id.myTextView);
setClickableString("stack", "Android is a Software stack", myTextView);

0

นี่คือของฉันMovementMethodสำหรับการตรวจจับการคลิกลิงค์ / ข้อความ / รูปภาพ LinkMovementMethodมันมีการแก้ไข

import android.text.Layout;
import android.text.NoCopySpan;
import android.text.Selection;
import android.text.Spannable;
import android.text.method.ScrollingMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.ImageSpan;
import android.text.style.URLSpan;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;

public class ClickMovementMethod extends ScrollingMovementMethod {
private Object FROM_BELOW = new NoCopySpan.Concrete();

private static final int CLICK = 1;
private static final int UP = 2;
private static final int DOWN = 3;

private Listener listener;

public void setListener(Listener listener) {
    this.listener = listener;
}

@Override
public boolean canSelectArbitrarily() {
    return true;
}

@Override
protected boolean handleMovementKey(TextView widget, Spannable buffer, int keyCode,
                                    int movementMetaState, KeyEvent event) {
    switch (keyCode) {
        case KeyEvent.KEYCODE_DPAD_CENTER:
        case KeyEvent.KEYCODE_ENTER:
            if (KeyEvent.metaStateHasNoModifiers(movementMetaState)) {
                if (event.getAction() == KeyEvent.ACTION_DOWN &&
                        event.getRepeatCount() == 0 && action(CLICK, widget, buffer)) {
                    return true;
                }
            }
            break;
    }
    return super.handleMovementKey(widget, buffer, keyCode, movementMetaState, event);
}

@Override
protected boolean up(TextView widget, Spannable buffer) {
    if (action(UP, widget, buffer)) {
        return true;
    }

    return super.up(widget, buffer);
}

@Override
protected boolean down(TextView widget, Spannable buffer) {
    if (action(DOWN, widget, buffer)) {
        return true;
    }

    return super.down(widget, buffer);
}

@Override
protected boolean left(TextView widget, Spannable buffer) {
    if (action(UP, widget, buffer)) {
        return true;
    }

    return super.left(widget, buffer);
}

@Override
protected boolean right(TextView widget, Spannable buffer) {
    if (action(DOWN, widget, buffer)) {
        return true;
    }

    return super.right(widget, buffer);
}

private boolean action(int what, TextView widget, Spannable buffer) {
    Layout layout = widget.getLayout();

    int padding = widget.getTotalPaddingTop() +
            widget.getTotalPaddingBottom();
    int areatop = widget.getScrollY();
    int areabot = areatop + widget.getHeight() - padding;

    int linetop = layout.getLineForVertical(areatop);
    int linebot = layout.getLineForVertical(areabot);

    int first = layout.getLineStart(linetop);
    int last = layout.getLineEnd(linebot);

    ClickableSpan[] candidates = buffer.getSpans(first, last, URLSpan.class);

    int a = Selection.getSelectionStart(buffer);
    int b = Selection.getSelectionEnd(buffer);

    int selStart = Math.min(a, b);
    int selEnd = Math.max(a, b);

    if (selStart < 0) {
        if (buffer.getSpanStart(FROM_BELOW) >= 0) {
            selStart = selEnd = buffer.length();
        }
    }

    if (selStart > last)
        selStart = selEnd = Integer.MAX_VALUE;
    if (selEnd < first)
        selStart = selEnd = -1;

    switch (what) {
        case CLICK:
            if (selStart == selEnd) {
                return false;
            }

            if (listener != null) {
                URLSpan[] link = buffer.getSpans(selStart, selEnd, URLSpan.class);
                if (link.length >= 1) {
                    listener.onClick(link[0].getURL());
                } else {
                    ImageSpan[] image = buffer.getSpans(selStart, selEnd, ImageSpan.class);
                    if (image.length >= 1) {
                        listener.onImageClicked(image[0].getSource());
                    } else {
                        listener.onTextClicked();
                    }
                }
            }
            break;

        case UP:
            int beststart, bestend;

            beststart = -1;
            bestend = -1;

            for (int i = 0; i < candidates.length; i++) {
                int end = buffer.getSpanEnd(candidates[i]);

                if (end < selEnd || selStart == selEnd) {
                    if (end > bestend) {
                        beststart = buffer.getSpanStart(candidates[i]);
                        bestend = end;
                    }
                }
            }

            if (beststart >= 0) {
                Selection.setSelection(buffer, bestend, beststart);
                return true;
            }

            break;

        case DOWN:
            beststart = Integer.MAX_VALUE;
            bestend = Integer.MAX_VALUE;

            for (int i = 0; i < candidates.length; i++) {
                int start = buffer.getSpanStart(candidates[i]);

                if (start > selStart || selStart == selEnd) {
                    if (start < beststart) {
                        beststart = start;
                        bestend = buffer.getSpanEnd(candidates[i]);
                    }
                }
            }

            if (bestend < Integer.MAX_VALUE) {
                Selection.setSelection(buffer, beststart, bestend);
                return true;
            }

            break;
    }

    return false;
}

@Override
public boolean onTouchEvent(TextView widget, Spannable buffer,
                            MotionEvent event) {
    int action = event.getAction();

    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);

        URLSpan[] link = buffer.getSpans(off, off, URLSpan.class);

        if (action == MotionEvent.ACTION_UP) {
            if (listener != null) {
                if (link.length >= 1) {
                    listener.onClick(link[0].getURL());
                } else {
                    ImageSpan[] image = buffer.getSpans(off, off, ImageSpan.class);
                    if (image.length >= 1) {
                        listener.onImageClicked(image[0].getSource());
                    } else if (Selection.getSelectionStart(buffer) == Selection.getSelectionEnd(buffer)) {
                        listener.onTextClicked();
                    }
                }
            }
        }

        if (action == MotionEvent.ACTION_DOWN && link.length != 0) {
            Selection.setSelection(buffer,
                    buffer.getSpanStart(link[0]),
                    buffer.getSpanEnd(link[0]));
            return true;
        }

        if (link.length == 0) {
            Selection.removeSelection(buffer);
        }
    }

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

@Override
public void initialize(TextView widget, Spannable text) {
    Selection.removeSelection(text);
    text.removeSpan(FROM_BELOW);
}

@Override
public void onTakeFocus(TextView view, Spannable text, int dir) {
    Selection.removeSelection(text);

    if ((dir & View.FOCUS_BACKWARD) != 0) {
        text.setSpan(FROM_BELOW, 0, 0, Spannable.SPAN_POINT_POINT);
    } else {
        text.removeSpan(FROM_BELOW);
    }
}

public interface Listener {

    void onClick(String clicked);

    void onTextClicked();

    void onImageClicked(String source);

}

}

0

คำตอบทั่วไปเพิ่มเติมใน kotlin

   fun setClickableText(view: TextView, firstSpan: String, secondSpan: String) {
    val context = view.context
    val builder = SpannableStringBuilder()
    val unClickableSpan = SpannableString(firstSpan)
    val span = SpannableString(" "+secondSpan)

    builder.append(unClickableSpan);
    val clickableSpan: ClickableSpan = object : ClickableSpan() {
        override fun onClick(textView: View) {
            val intent = Intent(context, HomeActivity::class.java)
         context.startActivity(intent)
        }

        override fun updateDrawState(ds: TextPaint) {
            super.updateDrawState(ds)
            ds.isUnderlineText = true
            ds.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.ITALIC));
        }
    }
    builder.append(span);
    builder.setSpan(clickableSpan, firstSpan.length, firstSpan.length+secondSpan.length+1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)

    view.setText(builder,TextView.BufferType.SPANNABLE)
    view.setMovementMethod(LinkMovementMethod.getInstance());


}

0

โซลูชั่นที่ให้มานั้นค่อนข้างดี อย่างไรก็ตามโดยทั่วไปฉันใช้วิธีที่ง่ายกว่า

นี่คือฟังก์ชั่นยูทิลิตี้ linkify

/**
 * Method is used to Linkify words in a TextView
 *
 * @param textView TextView who's text you want to change
 * @param textToLink The text to turn into a link
 * @param url   The url you want to send the user to
 */
fun linkify(textView: TextView, textToLink: String, url: String) {
    val pattern = Pattern.compile(textToLink)
    Linkify.addLinks(textView, pattern, url, { _, _, _ -> true })
    { _, _ -> "" }
}

การใช้ฟังก์ชั่นนี้ค่อนข้างง่าย นี่คือตัวอย่าง

    // terms and privacy
    val tvTerms = findViewById<TextView>(R.id.tv_terms)
    val tvPrivacy = findViewById<TextView>(R.id.tv_privacy)
    Utils.linkify(tvTerms, resources.getString(R.string.terms),
            Constants.TERMS_URL)
    Utils.linkify(tvPrivacy, resources.getString(R.string.privacy),
            Constants.PRIVACY_URL)

0

ฉันเขียนตัวอย่างเพื่อแก้ปัญหาของคุณใน Kotlin

นี่คือรหัส:

    val completeText = getString(R.string.terms_description)
    val textToFind = getString(R.string.show_terms)
    val spannableString: Spannable = SpannableString(completeText)
    val startFocus = completeText.indexOf(textToFind)
    val endFocus = startFocus + textToFind.length

    spannableString.setSpan(object: ClickableSpan() {
        override fun onClick(p0: View) {
            showMessage()
        }
    }, startFocus, endFocus, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
    show_terms.text = spannableString
    show_terms.movementMethod = LinkMovementMethod.getInstance();
    show_terms.highlightColor = Color.TRANSPARENT;

นี่คือ XML

    <CheckBox
            android:id="@+id/check_agree_terms"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

    <TextView
            android:id="@+id/show_terms"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColorLink="@color/colorPrimary"
            android:layout_toEndOf="@id/check_agree_terms"/>

นี่คือลักษณะที่ปรากฏ

ป้อนคำอธิบายรูปภาพที่นี่


-1

มันมีประโยชน์มากสำหรับส่วนที่คลิกได้สำหรับข้อความบางส่วน

จุดเป็นอักขระพิเศษในนิพจน์ทั่วไป หากคุณต้องการ spanable ความจำเป็นที่จะหลบหนี dot dot \\เป็น แทนที่จะแค่ส่งผ่าน " ." ไปยังวิธีข้อความแบบขยายได้ หรือคุณสามารถใช้นิพจน์ทั่วไป[.]เพื่อขยายสตริงด้วยจุดใน Java


-1

ในการเพิ่มข้อความที่เชื่อมโยงในมุมมองข้อความคุณสามารถใช้ตัวอย่างทรัพยากรสตริง "footer_text" ด้านล่างและแก้ไขวิธี onCreate ของคุณสำหรับกิจกรรมของคุณคุณสามารถใช้ตัวอย่างด้านล่าง

string.xml

<?xml version="1.0" charset="utf-8"?>
<resources>
     <string name="app_name">Name of My Application</string>

    <string name="footer_text">
        <a href="https://www.google.com/tos">Terms of Service</a>
        <a href="https://www.google.com/contact">Contact</a>
        <a href="https://www.google.com/privacy">Privacy Policy</a>
    </string>
</resources>

MainActivity.java

...

@Override
public void onCreate(Bundle savedInstance) {
    super.onCreate(savedInstance);
    setContentView(R.layout.activity_main);

    TextView textView = findViewById(R.id.textViewLink);
    textView.setMovementMethod(LinkMovermentMethod.getInstance());
}

....
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.