diff --git a/.idea/markdown-navigator.xml b/.idea/markdown-navigator.xml new file mode 100644 index 0000000..076726f --- /dev/null +++ b/.idea/markdown-navigator.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/markdown-navigator/profiles_settings.xml b/.idea/markdown-navigator/profiles_settings.xml new file mode 100644 index 0000000..57927c5 --- /dev/null +++ b/.idea/markdown-navigator/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/README.md b/README.md index d1898c1..abb0863 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,87 @@ # ExpandableTextView -可展开和收回的TextView + 实现类似微博内容,@用户,链接高亮,@用户和链接可点击跳转,可展开和收回的TextView。觉得好用别忘了star哦,你的star是对我最大的激励。 + + ### 实现效果: + + + +### 使用方式: + +#### Step 1. Add the JitPack repository to your build file + + Add it in your root build.gradle at the end of repositories: + + ``` + allprojects { + repositories { + ... + maven { url 'https://jitpack.io' } + } + } + ``` + +#### Step 2. Add the dependency + + ``` + dependencies { + implementation 'com.github.MZCretin:ExpandableTextView:v1.0' + } + ``` + +### 代码说明 + ++ 以下属性都可以在xml中设置 +```xml + + + + + + + + + + + + + + + + + + + + + + +``` + ++ java代码 +```java + ExpandableTextView expandableTextView = findViewById(R.id.ep_01); + //需要显示的内容 + String yourText = " 我所认识的中国,强大、友好。@奥特曼 “一带一路”经济带带动了沿线国家的经济发展,促进我国与他国的友好往来和贸易发展,可谓“双赢”。http://www.baidu.com 自古以来,中国以和平、友好的面孔示人。汉武帝派张骞出使西域,开辟丝绸之路,增进与西域各国的友好往来。http://www.baidu.com 胡麻、胡豆、香料等食材也随之传入中国,汇集于中华美食。@RNG 漠漠古道,驼铃阵阵,这条路奠定了“一带一路”的基础,让世界认识了中国。"; + //将内容设置给控件 + expandableTextView.setContent(yourText); + //xml中的属性也可以通过代码设置 比如 + expandableTextView.setmNeedExpend(true); + //还有很多。。。。 + //添加点击监听 + expandableTextView.setLinkClickListener(new ExpandableTextView.OnLinkClickListener() { + @Override + public void onLinkClickListener(ExpandableTextView.LinkType linkType, String content) { + //根据类型去判断 + if (linkType.equals(ExpandableTextView.LinkType.LINK_TYPE)) { + Toast.makeText(MainActivity.this, "你点击了链接 内容是:" + content, Toast.LENGTH_SHORT).show(); + } else if (linkType.equals(ExpandableTextView.LinkType.MENTION_TYPE)) { + Toast.makeText(MainActivity.this, "你点击了@用户 内容是:" + content, Toast.LENGTH_SHORT).show(); + } + } + }); +``` + +### 实现思路讲解 + +**简书:** [【需求解决系列之三】Android 自定义可展开收回的ExpandableTextView](https://www.jianshu.com/p/5519fbab6907) + +**掘金:** [【需求解决系列之三】Android 自定义可展开收回的ExpandableTextView](https://juejin.im/post/5b876a4de51d4571c5137660) diff --git a/app/build.gradle b/app/build.gradle index 77171a7..9088e13 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -23,11 +23,13 @@ android { } dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'com.android.support:appcompat-v7:26.1.0' implementation 'com.android.support.constraint:constraint-layout:1.1.2' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' - compile project(path: ':expandabletextviewlibrary') + //这里使用本地的 如果想设置可以打开自己测试下 + // implementation 'com.github.MZCretin:ExpandableTextView:v1.0' + implementation project(':expandabletextviewlibrary') } diff --git a/app/src/main/java/com/cretin/www/expandabletextview/MainActivity.java b/app/src/main/java/com/cretin/www/expandabletextview/MainActivity.java index 8bbe131..cf14355 100644 --- a/app/src/main/java/com/cretin/www/expandabletextview/MainActivity.java +++ b/app/src/main/java/com/cretin/www/expandabletextview/MainActivity.java @@ -1,6 +1,8 @@ package com.cretin.www.expandabletextview; +import android.content.Intent; import android.graphics.Color; +import android.net.Uri; import android.os.Bundle; import android.support.v4.text.util.LinkifyCompat; import android.support.v7.app.AppCompatActivity; @@ -10,6 +12,7 @@ import android.text.method.LinkMovementMethod; import android.text.style.ForegroundColorSpan; import android.text.util.Linkify; +import android.view.View; import android.widget.TextView; import android.widget.Toast; @@ -40,16 +43,13 @@ public class MainActivity extends AppCompatActivity { "3,5;6,9;10,11;14,16;21,22", }; - private String github = "https://github.com/MZCretin/ExpandableTextView"; - private String blogs = "https://www.jianshu.com/p/b7a8ddc639db"; - private String contact = "792075028@qq.com"; private TextView tvTips00; private ExpandableTextView.OnLinkClickListener linkClickListener = (type, content) -> { if (type.equals(ExpandableTextView.LinkType.LINK_TYPE)) { - Toast.makeText(MainActivity.this, "你点击了链接 " + content, Toast.LENGTH_SHORT).show(); + Toast.makeText(MainActivity.this, "你点击了链接 内容是:" + content, Toast.LENGTH_SHORT).show(); } else if (type.equals(ExpandableTextView.LinkType.MENTION_TYPE)) { - Toast.makeText(MainActivity.this, "你点击了@用户 " + content, Toast.LENGTH_SHORT).show(); + Toast.makeText(MainActivity.this, "你点击了@用户 内容是:" + content, Toast.LENGTH_SHORT).show(); } }; @@ -76,7 +76,7 @@ protected void onCreate(Bundle savedInstanceState) { setTips(); - String yourText = " hello...world 我所认识的中国,强大、友好。@奥特曼 “一带一路”经济带带动了沿线国家的经济发展,促进我国与他国的友好往来和贸易发展,可谓“双赢”。http://www.baidu.com 自古以来,中国以和平、友好的面孔示人。汉武帝派张骞出使西域,开辟丝绸之路,增进与西域各国的友好往来。http://www.baidu.com 胡麻、胡豆、香料等食材也随之传入中国,汇集于中华美食。@RNG 漠漠古道,驼铃阵阵,这条路奠定了“一带一路”的基础,让世界认识了中国。"; + String yourText = " 我所认识的中国,强大、友好。@奥特曼 “一带一路”经济带带动了沿线国家的经济发展,促进我国与他国的友好往来和贸易发展,可谓“双赢”。http://www.baidu.com 自古以来,中国以和平、友好的面孔示人。汉武帝派张骞出使西域,开辟丝绸之路,增进与西域各国的友好往来。http://www.baidu.com 胡麻、胡豆、香料等食材也随之传入中国,汇集于中华美食。@RNG 漠漠古道,驼铃阵阵,这条路奠定了“一带一路”的基础,让世界认识了中国。"; views[0].setContent(yourText); views[0].setLinkClickListener(linkClickListener); @@ -96,6 +96,12 @@ protected void onCreate(Bundle savedInstanceState) { views[5].setContent(yourText); views[5].setEndExpendContent(" 1小时前"); views[5].setLinkClickListener(linkClickListener); + + findViewById(R.id.ll_ad).setOnClickListener(v -> { + Uri uri = Uri.parse("http://a.app.qq.com/o/simple.jsp?pkgname=com.cretin"); + Intent intent = new Intent(Intent.ACTION_VIEW, uri); + startActivity(intent); + }); } /** @@ -108,7 +114,7 @@ private void setTips() { tvTips00.setMovementMethod(LinkMovementMethod.getInstance()); tvTips00.setText(value); - //处理圣剩下的 + //处理剩下的 for (int i = 0; i < indexs.length; i++) { String index = indexs[i]; TextView view = tips[i]; diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index c8f49f9..1c9b33b 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -10,20 +10,20 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - android:paddingBottom="100dp"> + android:paddingBottom="5dp"> + android:paddingTop="10dp" + android:text="ExpandTextView包含如下功能:\n1、实现类似微博@好友的功能,对@内容进行高亮显示,可以点击\n2、实现链接的高亮显示,可以点击,并且对链接进行原文隐藏\n3、实现内容超过指定行数折叠效果,点击可以展开内容\n4、在原文内容末尾添加指定内容,比如时间串,详情见效果图\n\n联系我:\n792075058@qq.com\n\n博客地址:\nhttps://www.jianshu.com/p/5519fbab6907\n\nGithub地址(您的star是对我最大的鼓励):\nhttps://github.com/MZCretin/ExpandableTextView\n\n" + android:textColor="#333333" + android:textSize="14sp" /> @@ -53,10 +53,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#e6e6e6" - android:paddingRight="15dp" android:lineSpacingExtra="4dp" android:paddingBottom="10dp" android:paddingLeft="15dp" + android:paddingRight="15dp" android:paddingTop="10dp" android:text="2、正常带链接和@用户,有展开和收回功能,有切换动画" android:textColor="#666666" @@ -78,10 +78,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#e6e6e6" - android:paddingRight="15dp" android:lineSpacingExtra="4dp" android:paddingBottom="10dp" android:paddingLeft="15dp" + android:paddingRight="15dp" android:paddingTop="10dp" android:text="3、正常带链接和@用户,有展开和收回功能,没有切换动画" android:textColor="#666666" @@ -102,11 +102,11 @@ android:id="@+id/tv_tips04" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingRight="15dp" android:background="#e6e6e6" android:lineSpacingExtra="4dp" android:paddingBottom="10dp" android:paddingLeft="15dp" + android:paddingRight="15dp" android:paddingTop="10dp" android:text="4、正常带链接和@用户,有展开,没有收回功能" android:textColor="#666666" @@ -129,9 +129,9 @@ android:layout_height="wrap_content" android:background="#e6e6e6" android:lineSpacingExtra="4dp" - android:paddingRight="15dp" android:paddingBottom="10dp" android:paddingLeft="15dp" + android:paddingRight="15dp" android:paddingTop="10dp" android:text="5、正常带链接和@用户,有展开,有收回功能,带附加内容(比如时间)" android:textColor="#666666" @@ -173,5 +173,43 @@ app:ep_need_contract="false" app:ep_need_expand="true" /> + + + + + + + + + + + + + + diff --git a/app/src/main/res/mipmap-xxhdpi/icon.png b/app/src/main/res/mipmap-xxhdpi/icon.png new file mode 100644 index 0000000..046a286 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/icon.png differ diff --git a/build.gradle b/build.gradle index e6b32bc..623969e 100644 --- a/build.gradle +++ b/build.gradle @@ -19,6 +19,7 @@ allprojects { repositories { google() jcenter() + maven { url 'https://jitpack.io' } } } diff --git a/expandabletextviewlibrary/src/main/java/com/ctetin/expandabletextviewlibrary/ExpandableTextView.java b/expandabletextviewlibrary/src/main/java/com/ctetin/expandabletextviewlibrary/ExpandableTextView.java index 73e9c8b..2ce9a29 100644 --- a/expandabletextviewlibrary/src/main/java/com/ctetin/expandabletextviewlibrary/ExpandableTextView.java +++ b/expandabletextviewlibrary/src/main/java/com/ctetin/expandabletextviewlibrary/ExpandableTextView.java @@ -345,7 +345,7 @@ public void updateDrawState(TextPaint ds) { ssb.setSpan(new ForegroundColorSpan(mEndExpandTextColor), ssb.length() - mEndExpandContent.length(), ssb.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); } } - //处理链接的处理 + //处理链接或者@用户 List positionDatas = formatData.getPositionDatas(); HH: for (FormatData.PositionData data : positionDatas) { @@ -735,4 +735,132 @@ public OnLinkClickListener getLinkClickListener() { public void setLinkClickListener(OnLinkClickListener linkClickListener) { this.linkClickListener = linkClickListener; } + + /** + * 设置 "展开" + * + * @param ssb + * @param formatData + * + */ + private void setExpandSpan(SpannableStringBuilder ssb, FormatData formatData) { + int index = currentLines - 1; + int endPosition = mDynamicLayout.getLineEnd(index); + int startPosition = mDynamicLayout.getLineStart(index); + float lineWidth = mDynamicLayout.getLineWidth(index); + + String endString = getHideEndContent(); + + //计算原内容被截取的位置下标 + int fitPosition = + getFitPosition(endPosition, startPosition, lineWidth, mPaint.measureText(endString), 0); + + ssb.append(formatData.formatedContent.substring(0, fitPosition)); + + //在被截断的文字后面添加 展开 文字 + ssb.append(endString); + + int expendLength = TextUtils.isEmpty(mEndExpandContent) ? 0 : 2 + mEndExpandContent.length(); + ssb.setSpan(new ClickableSpan() { + @Override + public void onClick(View widget) { + action(); + } + + @Override + public void updateDrawState(TextPaint ds) { + super.updateDrawState(ds); + ds.setColor(mExpandTextColor); + ds.setUnderlineText(false); + } + }, ssb.length() - TEXT_EXPEND.length() - expendLength, ssb.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); + } + + public Drawable getmLinkDrawable() { + return mLinkDrawable; + } + + public void setmLinkDrawable(Drawable mLinkDrawable) { + this.mLinkDrawable = mLinkDrawable; + } + + public boolean ismNeedContract() { + return mNeedContract; + } + + public void setmNeedContract(boolean mNeedContract) { + this.mNeedContract = mNeedContract; + } + + public boolean ismNeedExpend() { + return mNeedExpend; + } + + public void setmNeedExpend(boolean mNeedExpend) { + this.mNeedExpend = mNeedExpend; + } + + public boolean ismNeedAnimation() { + return mNeedAnimation; + } + + public void setmNeedAnimation(boolean mNeedAnimation) { + this.mNeedAnimation = mNeedAnimation; + } + + public int getmLineCount() { + return mLineCount; + } + + public void setmLineCount(int mLineCount) { + this.mLineCount = mLineCount; + } + + public int getmExpandTextColor() { + return mExpandTextColor; + } + + public void setmExpandTextColor(int mExpandTextColor) { + this.mExpandTextColor = mExpandTextColor; + } + + public int getmLinkTextColor() { + return mLinkTextColor; + } + + public void setmLinkTextColor(int mLinkTextColor) { + this.mLinkTextColor = mLinkTextColor; + } + + public int getmContractTextColor() { + return mContractTextColor; + } + + public void setmContractTextColor(int mContractTextColor) { + this.mContractTextColor = mContractTextColor; + } + + public String getmExpandString() { + return mExpandString; + } + + public void setmExpandString(String mExpandString) { + this.mExpandString = mExpandString; + } + + public String getmContractString() { + return mContractString; + } + + public void setmContractString(String mContractString) { + this.mContractString = mContractString; + } + + public int getmEndExpandTextColor() { + return mEndExpandTextColor; + } + + public void setmEndExpandTextColor(int mEndExpandTextColor) { + this.mEndExpandTextColor = mEndExpandTextColor; + } } diff --git a/extra/demo.apk b/extra/demo.apk new file mode 100644 index 0000000..ca382d9 Binary files /dev/null and b/extra/demo.apk differ diff --git a/extra/demo.png b/extra/demo.png new file mode 100644 index 0000000..d28576d Binary files /dev/null and b/extra/demo.png differ diff --git a/settings.gradle b/settings.gradle index a5a789f..2d12f5b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':app', ':expandabletextviewlibrary' +include ':app',':expandabletextviewlibrary'