feat: 支持贴内B站视频/音频/专栏号直接跳转

This commit is contained in:
HuanChengFly 2020-08-20 21:03:23 +08:00
parent 3a0387487b
commit 57d23f9b8e
4 changed files with 90 additions and 9 deletions

View File

@ -26,6 +26,7 @@ import com.huanchengfly.tieba.post.api.models.CommonResponse;
import com.huanchengfly.tieba.post.api.models.SubFloorListBean;
import com.huanchengfly.tieba.post.api.models.ThreadContentBean;
import com.huanchengfly.tieba.post.components.LinkMovementClickMethod;
import com.huanchengfly.tieba.post.components.LinkTouchMovementMethod;
import com.huanchengfly.tieba.post.components.spans.MyURLSpan;
import com.huanchengfly.tieba.post.components.spans.MyUserSpan;
import com.huanchengfly.tieba.post.fragments.ConfirmDialogFragment;
@ -33,6 +34,7 @@ import com.huanchengfly.tieba.post.fragments.MenuDialogFragment;
import com.huanchengfly.tieba.post.models.PhotoViewBean;
import com.huanchengfly.tieba.post.models.ReplyInfoBean;
import com.huanchengfly.tieba.post.utils.AccountUtil;
import com.huanchengfly.tieba.post.utils.BilibiliUtil;
import com.huanchengfly.tieba.post.utils.EmotionUtil;
import com.huanchengfly.tieba.post.utils.ImageUtil;
import com.huanchengfly.tieba.post.utils.NavigationHelper;
@ -41,6 +43,7 @@ import com.huanchengfly.tieba.post.utils.ThemeUtil;
import com.huanchengfly.tieba.post.utils.Util;
import com.huanchengfly.tieba.post.widgets.MyLinearLayout;
import com.huanchengfly.tieba.post.widgets.VoicePlayerView;
import com.huanchengfly.tieba.post.widgets.theme.TintMySpannableTextView;
import com.huanchengfly.tieba.post.widgets.theme.TintTextView;
import com.othershe.baseadapter.ViewHolder;
import com.othershe.baseadapter.base.CommonBaseAdapter;
@ -235,15 +238,25 @@ public class RecyclerFloorAdapter extends CommonBaseAdapter<SubFloorListBean.Pos
}
private TextView createTextView(int type) {
TintTextView textView = new TintTextView(mContext);
textView.setMovementMethod(LinkMovementClickMethod.getInstance());
textView.setClickable(false);
TextView textView;
if (type == TEXT_VIEW_TYPE_CONTENT) {
TintMySpannableTextView mySpannableTextView = new TintMySpannableTextView(mContext);
mySpannableTextView.setTintResId(R.color.default_color_text);
mySpannableTextView.setLinkTouchMovementMethod(LinkTouchMovementMethod.getInstance());
textView = mySpannableTextView;
} else {
TintTextView tintTextView = new TintTextView(mContext);
tintTextView.setTintResId(R.color.default_color_text);
tintTextView.setMovementMethod(LinkMovementClickMethod.getInstance());
textView = tintTextView;
}
textView.setFocusable(false);
textView.setFocusableInTouchMode(false);
textView.setClickable(false);
textView.setLongClickable(false);
textView.setTextIsSelectable(false);
textView.setOnClickListener(null);
textView.setOnLongClickListener(null);
textView.setTintResId(R.color.default_color_text);
textView.setLetterSpacing(0.02F);
if (type == TEXT_VIEW_TYPE_CONTENT) {
textView.setTextSize(16);
}
@ -251,7 +264,9 @@ public class RecyclerFloorAdapter extends CommonBaseAdapter<SubFloorListBean.Pos
}
private void setText(TextView textView, CharSequence content) {
textView.setText(StringUtil.getEmotionContent(EmotionUtil.EMOTION_ALL_TYPE, textView, content));
content = BilibiliUtil.replaceVideoNumberSpan(mContext, content);
content = StringUtil.getEmotionContent(EmotionUtil.EMOTION_ALL_TYPE, textView, content);
textView.setText(content);
}
private LinearLayout.LayoutParams getLayoutParams(ThreadContentBean.ContentBean contentBean) {

View File

@ -40,6 +40,7 @@ import com.huanchengfly.tieba.post.models.PhotoViewBean;
import com.huanchengfly.tieba.post.models.ReplyInfoBean;
import com.huanchengfly.tieba.post.ui.theme.utils.ThemeUtils;
import com.huanchengfly.tieba.post.utils.AccountUtil;
import com.huanchengfly.tieba.post.utils.BilibiliUtil;
import com.huanchengfly.tieba.post.utils.BlockUtil;
import com.huanchengfly.tieba.post.utils.DisplayUtil;
import com.huanchengfly.tieba.post.utils.EmotionUtil;
@ -316,7 +317,7 @@ public class RecyclerThreadAdapter extends MultiBaseAdapter<ThreadContentBean.Po
break;
}
}
textView.setText(StringUtil.getEmotionContent(EmotionUtil.EMOTION_ALL_TYPE, textView, builder));
textView.setText(BilibiliUtil.replaceVideoNumberSpan(mContext, StringUtil.getEmotionContent(EmotionUtil.EMOTION_ALL_TYPE, textView, builder)));
textView.setPadding(DisplayUtil.dp2px(mContext, 8),
8,
DisplayUtil.dp2px(mContext, 8),
@ -710,7 +711,9 @@ public class RecyclerThreadAdapter extends MultiBaseAdapter<ThreadContentBean.Po
}
private void setText(TextView textView, CharSequence content) {
textView.setText(StringUtil.getEmotionContent(EmotionUtil.EMOTION_ALL_TYPE, textView, content));
content = BilibiliUtil.replaceVideoNumberSpan(mContext, content);
content = StringUtil.getEmotionContent(EmotionUtil.EMOTION_ALL_TYPE, textView, content);
textView.setText(content);
}
private LinearLayout.LayoutParams getLayoutParams(ThreadContentBean.ContentBean contentBean, String floor) {

View File

@ -0,0 +1,63 @@
package com.huanchengfly.tieba.post.utils
import android.content.Context
import android.text.SpannableString
import android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
import com.huanchengfly.tieba.post.components.spans.MyURLSpan
import org.intellij.lang.annotations.RegExp
import java.util.regex.Pattern
object BilibiliUtil {
@RegExp
const val REGEX_BV = "BV([a-zA-Z0-9]{10})"
@RegExp
const val REGEX_AV = "av([0-9]{1,})"
@RegExp
const val REGEX_CV = "cv([0-9]{1,})"
@RegExp
const val REGEX_AU = "au([0-9]{1,})"
@JvmStatic
fun replaceVideoNumberSpan(
context: Context,
source: CharSequence?
): SpannableString {
if (source == null) {
return SpannableString("")
}
return if (source is SpannableString) {
source
} else {
SpannableString(source)
}.also {
replace(context, REGEX_BV, it)
replace(context, REGEX_AV, it)
replace(context, REGEX_CV, it, "https://www.bilibili.com/read/")
replace(context, REGEX_AU, it, "https://www.bilibili.com/audio/")
}
}
private fun replace(
context: Context,
regex: String,
source: SpannableString,
urlPrefix: String = "https://www.bilibili.com/video/"
): CharSequence {
try {
val pattern = Pattern.compile(regex)
val matcher = pattern.matcher(source)
while (matcher.find()) {
val found: String = matcher.group()
val start: Int = matcher.start()
val span = MyURLSpan(context, "$urlPrefix$found")
source.setSpan(span, start, start + found.length, SPAN_EXCLUSIVE_EXCLUSIVE)
}
} catch (e: Exception) {
e.printStackTrace()
}
return source
}
}

View File

@ -26,7 +26,7 @@ public class EmotionUtil {
@RegExp
private static final String REGEX_WEB = "\\(#([\u4e00-\u9fa5\\w\u007e])+\\)";
@RegExp
private static final String REGEX = "#\\(([\u4e00-\u9fa5\\w\u007e])+\\)";
private static final String REGEX = "#\\(([一-龥\\w~])+\\)";
private static Map<String, Integer> EMPTY_MAP;
private static Map<String, Integer> EMOTION_ALL_MAP;
private static Map<String, Integer> EMOTION_CLASSIC_MAP;