├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml └── runConfigurations.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── igeek │ │ └── expandtextview │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── java │ ├── com │ │ └── igeek │ │ │ └── expandtextview │ │ │ └── MainActivity.java │ └── widget │ │ ├── ExpandTextView.java │ │ └── LineText.java │ └── res │ ├── layout │ └── activity_main.xml │ ├── menu │ └── menu_main.xml │ ├── mipmap-hdpi │ ├── down.png │ ├── ic_launcher.png │ └── up.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values-v21 │ └── styles.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── attrs.xml │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── pic ├── expandtextview.gif └── expandtextview2.gif └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | ExpandTextView -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | #### 效果图 (带提示图标) 4 | 5 | 960 6 | 7 | 8 | #### 效果图 (不带提示图标) 9 | 10 | 960 11 | 12 | #### activity 文件 13 | 14 | ExpandTextView textView; 15 | 16 | @Override 17 | protected void onCreate(Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | setContentView(R.layout.activity_main); 20 | textView= (ExpandTextView) findViewById(R.id.cusTextView); 21 | textView.updateText(getResources().getString(R.string.test_expandtext)); 22 | } 23 | 24 | 25 | 26 | #### xml文件 27 | 28 | 45 | 46 | 47 | 48 | #### 属性说明 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 22 5 | buildToolsVersion "22.0.1" 6 | 7 | defaultConfig { 8 | applicationId "com.igeek.expandtextview" 9 | minSdkVersion 15 10 | targetSdkVersion 22 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | compile 'com.android.support:appcompat-v7:22.2.1' 25 | compile 'com.android.support:design:22.2.1' 26 | } 27 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/Allen1/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/igeek/expandtextview/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.igeek.expandtextview; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/igeek/expandtextview/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.igeek.expandtextview; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | 6 | import widget.ExpandTextView; 7 | 8 | 9 | public class MainActivity extends Activity { 10 | 11 | ExpandTextView textView; 12 | 13 | 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | setContentView(R.layout.activity_main); 18 | textView= (ExpandTextView) findViewById(R.id.cusTextView); 19 | textView.updateText(getResources().getString(R.string.test_expandtext)); 20 | } 21 | 22 | @Override 23 | protected void onResume() { 24 | super.onResume(); 25 | // textView.updateText(getResources().getString(R.string.test_expandtext)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/widget/ExpandTextView.java: -------------------------------------------------------------------------------- 1 | package widget; 2 | 3 | import android.animation.ObjectAnimator; 4 | import android.content.Context; 5 | import android.content.res.TypedArray; 6 | import android.graphics.Bitmap; 7 | import android.graphics.Canvas; 8 | import android.graphics.Matrix; 9 | import android.graphics.Paint; 10 | import android.graphics.PixelFormat; 11 | import android.graphics.drawable.Drawable; 12 | import android.text.Layout; 13 | import android.text.StaticLayout; 14 | import android.text.TextPaint; 15 | import android.text.TextUtils; 16 | import android.util.AttributeSet; 17 | import android.view.View; 18 | import android.view.animation.AccelerateDecelerateInterpolator; 19 | 20 | import com.igeek.expandtextview.R; 21 | 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | /** 26 | * 缩放展开的动画简单Textview 27 | * 28 | * Created by igeek on 2016/9/1. 29 | * @author igeek2014@hotmail.com 30 | */ 31 | public class ExpandTextView extends View implements View.OnClickListener { 32 | 33 | //行文本记录集 34 | private List lineTexts = new ArrayList(); 35 | //最大显示文本行数 36 | private int maxLines; 37 | //目标文本行 38 | private int targetLine; 39 | //收缩收起时候的提示图标 40 | private Drawable expandDrawable; 41 | //展开时候的提示图标 42 | private Drawable shrinkDrawable; 43 | //提示图标的宽度 44 | private int drawableWidth; 45 | //提示图标的高度 46 | private int drawableHeight; 47 | //最大显示文本行对应的本视图高度 48 | private int maxLinesHeight; 49 | //展开时候的视图高度 50 | private int expandHeight; 51 | //当前视图的高度 52 | private int viewHeight; 53 | //收缩行结尾提示语文本宽度 54 | private float ellipsizWidth; 55 | //收缩行结尾提示语文本绘制水平起点 56 | private float ellipsizStartX; 57 | 58 | //文本字体大小 59 | private int textSize; 60 | //文本颜色 61 | private int textColor; 62 | //当前文本 63 | private String text; 64 | private String ellipsizText = "..."; 65 | //收缩行文本 66 | private String shrinkLineText; 67 | //动画显示时间 68 | private int animDuration; 69 | //是否能够显示 ellipsizText 【需要收缩行当前文本的宽度】 70 | private boolean showEllipsizText = false; 71 | private boolean showTipDrawalbe = false; 72 | private boolean needMeasure = true; 73 | 74 | private StaticLayout layout; 75 | private TextPaint textPaint; 76 | 77 | 78 | public ExpandTextView(Context context) { 79 | this(context, null); 80 | } 81 | 82 | public ExpandTextView(Context context, AttributeSet attrs) { 83 | this(context, attrs, 0); 84 | } 85 | 86 | public ExpandTextView(Context context, AttributeSet attrs, int defStyleAttr) { 87 | super(context, attrs, defStyleAttr); 88 | 89 | TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ExpandTextView); 90 | 91 | maxLines = ta.getInt(R.styleable.ExpandTextView_maxLines, -1); 92 | animDuration = ta.getInt(R.styleable.ExpandTextView_animDuration, 300); 93 | textSize = ta.getDimensionPixelSize(R.styleable.ExpandTextView_textSize, 14); 94 | textColor = ta.getColor(R.styleable.ExpandTextView_textColor, 14); 95 | drawableWidth = ta.getDimensionPixelSize(R.styleable.ExpandTextView_drawableWidth, 14); 96 | drawableHeight = ta.getDimensionPixelSize(R.styleable.ExpandTextView_drawableHeight, 14); 97 | expandDrawable = ta.getDrawable(R.styleable.ExpandTextView_expandDrawable); 98 | shrinkDrawable = ta.getDrawable(R.styleable.ExpandTextView_shrinkDrawable); 99 | 100 | ta.recycle(); 101 | 102 | textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); 103 | textPaint.density = context.getResources().getDisplayMetrics().density; 104 | textPaint.setColor(textColor); 105 | textPaint.setStyle(Paint.Style.FILL_AND_STROKE); 106 | textPaint.setTextSize(textSize); 107 | 108 | } 109 | 110 | @Override 111 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 112 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 113 | 114 | int width = MeasureSpec.getSize(widthMeasureSpec); 115 | 116 | if (needMeasure && (!TextUtils.isEmpty(text))) { 117 | needMeasure = false; 118 | measureHeightState(text, width); 119 | startDrawAnim(0, viewHeight); 120 | }else{ 121 | heightMeasureSpec = MeasureSpec.makeMeasureSpec(viewHeight, MeasureSpec.EXACTLY); 122 | setMeasuredDimension(widthMeasureSpec, heightMeasureSpec); 123 | } 124 | 125 | } 126 | 127 | public void updateText(String text) { 128 | if (!TextUtils.isEmpty(text)) { 129 | this.text = text; 130 | needMeasure = true; 131 | requestLayout(); 132 | } 133 | } 134 | 135 | private synchronized void measureHeightState(String text, int width) { 136 | 137 | layout = new StaticLayout(text, textPaint, width - getPaddingLeft() - getPaddingRight(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0f, true); 138 | final int lineCount = layout.getLineCount(); 139 | maxLines = (maxLines == -1 || maxLines > lineCount) ? lineCount : maxLines; 140 | 141 | int text_Height = 0; 142 | 143 | List tempLines = new ArrayList(); 144 | 145 | for (int index = 0; index < lineCount; index++) { 146 | int start = layout.getLineStart(index); 147 | int end = layout.getLineEnd(index); 148 | LineText lineText = new LineText(); 149 | lineText.setStartIndex(start); 150 | lineText.setEndIndex(end - 1); 151 | lineText.setText(text.substring(start, end)); 152 | lineText.setTopOffset(layout.getLineTop(index)); 153 | lineText.setBottomOffset(layout.getLineBottom(index)); 154 | lineText.setBaseLine(layout.getLineBaseline(index)+getPaddingTop()); 155 | lineText.setWidth(layout.getLineWidth(index)); 156 | lineText.setHeight(lineText.getBottomOffset() - lineText.getTopOffset()); 157 | tempLines.add(lineText); 158 | 159 | if (index < maxLines) { 160 | maxLinesHeight += lineText.getHeight(); 161 | } 162 | 163 | text_Height += lineText.getHeight(); 164 | } 165 | 166 | maxLinesHeight+=getPaddingTop()+getPaddingBottom(); 167 | expandHeight+=getPaddingTop()+getPaddingBottom(); 168 | 169 | ellipsizWidth = textPaint.measureText(ellipsizText); 170 | 171 | if (maxLines < lineCount) { 172 | 173 | showTipDrawalbe = expandDrawable != null && shrinkDrawable != null; 174 | 175 | float textWidth = tempLines.get(maxLines - 1).getWidth(); 176 | float contentWidth = width - getPaddingLeft() - getPaddingRight(); 177 | float toMarginRight = ellipsizWidth + (showTipDrawalbe ? drawableWidth : 0); 178 | 179 | String ellipsizLineText = tempLines.get(maxLines - 1).getText(); 180 | 181 | if (contentWidth - textWidth < toMarginRight) { 182 | showEllipsizText = true; 183 | String subString = null; 184 | for (int index = ellipsizLineText.length() - 1; index > 0; index--) { 185 | subString = ellipsizLineText.substring(0, index); 186 | float subStrWidth = textPaint.measureText(subString); 187 | if (contentWidth - subStrWidth >= toMarginRight) { 188 | ellipsizStartX = subStrWidth + getPaddingLeft(); 189 | shrinkLineText = subString; 190 | break; 191 | } 192 | } 193 | } else { 194 | shrinkLineText = ellipsizLineText; 195 | showEllipsizText = false; 196 | } 197 | } else { 198 | showTipDrawalbe = false; 199 | showEllipsizText = false; 200 | } 201 | 202 | expandHeight += text_Height + ((expandDrawable != null && showTipDrawalbe) ? drawableHeight : 0); 203 | 204 | viewHeight = maxLines == lineCount ? expandHeight : maxLinesHeight; 205 | 206 | targetLine = maxLines; 207 | 208 | lineTexts = tempLines; 209 | 210 | 211 | if (viewHeight < expandHeight) { 212 | setClickable(true); 213 | setOnClickListener(this); 214 | } else { 215 | setClickable(false); 216 | } 217 | 218 | } 219 | 220 | 221 | @Override 222 | protected void onDraw(Canvas canvas) { 223 | super.onDraw(canvas); 224 | 225 | if (lineTexts.size() == 0) return; 226 | 227 | for (int index = 0; index < targetLine; index++) { 228 | 229 | LineText lineText = lineTexts.get(index); 230 | 231 | if (index < targetLine - 1) { 232 | canvas.drawText(lineText.getText(), getPaddingLeft(), lineText.getBaseLine(), textPaint); 233 | } else { 234 | if (targetLine == maxLines && maxLines < lineTexts.size()) { 235 | //收缩转态 236 | if (showEllipsizText) 237 | canvas.drawText(ellipsizText, ellipsizStartX, lineText.getBaseLine(), textPaint); 238 | canvas.drawText(shrinkLineText, getPaddingLeft(), lineText.getBaseLine(), textPaint); 239 | if (showTipDrawalbe){ 240 | int left=getWidth() - drawableWidth - getPaddingRight(); 241 | int top=getHeight() - drawableHeight-getPaddingBottom(); 242 | canvas.drawBitmap(drawabletoZoomBitmap(shrinkDrawable, drawableWidth, drawableHeight), left, top, null); 243 | } 244 | } else if (targetLine == lineTexts.size()) { 245 | //展开状态 246 | canvas.drawText(lineText.getText(), getPaddingLeft(), lineText.getBaseLine(), textPaint); 247 | if (showTipDrawalbe){ 248 | int left=getWidth() - drawableWidth - getPaddingRight(); 249 | int top=getHeight() - drawableHeight-getPaddingBottom(); 250 | canvas.drawBitmap(drawabletoZoomBitmap(expandDrawable, drawableWidth, drawableHeight), left, top, null); 251 | } 252 | } 253 | } 254 | } 255 | 256 | } 257 | 258 | 259 | @Override 260 | public void onClick(View view) { 261 | 262 | if (maxLines == lineTexts.size()) 263 | return; 264 | 265 | if (targetLine == maxLines) { 266 | targetLine = lineTexts.size(); 267 | startDrawAnim(maxLinesHeight, expandHeight); 268 | } else if (targetLine == lineTexts.size()) { 269 | targetLine = maxLines; 270 | startDrawAnim(expandHeight, maxLinesHeight); 271 | } 272 | } 273 | 274 | private void startDrawAnim(int startHeight, int endHeight) { 275 | ObjectAnimator animator = ObjectAnimator.ofInt(this, "viewHeight", startHeight, endHeight); 276 | animator.setDuration(animDuration); 277 | // animator.setInterpolator(new AccelerateDecelerateInterpolator()); 278 | animator.start(); 279 | } 280 | 281 | 282 | public int getViewHeight() { 283 | return viewHeight; 284 | } 285 | 286 | public void setViewHeight(int viewHeight) { 287 | this.viewHeight = viewHeight; 288 | requestLayout(); 289 | } 290 | 291 | public String getText() { 292 | return text; 293 | } 294 | 295 | public void setText(String text) { 296 | this.text = text; 297 | } 298 | 299 | /** 300 | * drawlable 缩放 301 | * 302 | * @return 303 | */ 304 | public static Bitmap drawabletoZoomBitmap(Drawable drawable, int w, int h) { 305 | // 取 drawable 的长宽 306 | int width = drawable.getIntrinsicWidth(); 307 | int height = drawable.getIntrinsicHeight(); 308 | // drawable转换成bitmap 309 | Bitmap oldbmp = drawabletoBitmap(drawable); 310 | // 创建操作图片用的Matrix对象 311 | Matrix matrix = new Matrix(); 312 | // 计算缩放比例 313 | float sx = ((float) w / width); 314 | float sy = ((float) h / height); 315 | // 设置缩放比例 316 | matrix.postScale(sx, sy); 317 | // 建立新的bitmap,其内容是对原bitmap的缩放后的图 318 | Bitmap newbmp = Bitmap.createBitmap(oldbmp, 0, 0, width, height, 319 | matrix, true); 320 | return newbmp; 321 | } 322 | 323 | /** 324 | * Drawable转换成Bitmap 325 | */ 326 | public static Bitmap drawabletoBitmap(Drawable drawable) { 327 | // 取 drawable 的长宽 328 | int width = drawable.getIntrinsicWidth(); 329 | int height = drawable.getIntrinsicHeight(); 330 | // 取 drawable 的颜色格式 331 | Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 332 | : Bitmap.Config.RGB_565; 333 | Bitmap bitmap = Bitmap.createBitmap(width, height, config); 334 | Canvas canvas = new Canvas(bitmap); 335 | drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), 336 | drawable.getIntrinsicHeight()); 337 | drawable.draw(canvas); 338 | return bitmap; 339 | } 340 | 341 | 342 | } 343 | -------------------------------------------------------------------------------- /app/src/main/java/widget/LineText.java: -------------------------------------------------------------------------------- 1 | package widget; 2 | 3 | /** 4 | * Created by igeek on 2016/9/1. 5 | * @author igeek2014@hotmail.com 6 | */ 7 | public class LineText { 8 | private String text; 9 | private int startIndex; 10 | private int endIndex; 11 | private int lineIndex; 12 | private int topOffset; 13 | private int bottomOffset; 14 | private int paddingTop; 15 | private int paddingBottom; 16 | private float width; 17 | private int height; 18 | private int baseLine; 19 | 20 | public String getText() { 21 | return text; 22 | } 23 | 24 | public void setText(String text) { 25 | this.text = text; 26 | } 27 | 28 | public int getStartIndex() { 29 | return startIndex; 30 | } 31 | 32 | public void setStartIndex(int startIndex) { 33 | this.startIndex = startIndex; 34 | } 35 | 36 | public int getEndIndex() { 37 | return endIndex; 38 | } 39 | 40 | public void setEndIndex(int endIndex) { 41 | this.endIndex = endIndex; 42 | } 43 | 44 | public int getLineIndex() { 45 | return lineIndex; 46 | } 47 | 48 | public void setLineIndex(int lineIndex) { 49 | this.lineIndex = lineIndex; 50 | } 51 | 52 | public int getTopOffset() { 53 | return topOffset; 54 | } 55 | 56 | public void setTopOffset(int topOffset) { 57 | this.topOffset = topOffset; 58 | } 59 | 60 | public int getPaddingTop() { 61 | return paddingTop; 62 | } 63 | 64 | public void setPaddingTop(int paddingTop) { 65 | this.paddingTop = paddingTop; 66 | } 67 | 68 | public int getPaddingBottom() { 69 | return paddingBottom; 70 | } 71 | 72 | public void setPaddingBottom(int paddingBottom) { 73 | this.paddingBottom = paddingBottom; 74 | } 75 | 76 | public float getWidth() { 77 | return width; 78 | } 79 | 80 | public void setWidth(float width) { 81 | this.width = width; 82 | } 83 | 84 | public int getHeight() { 85 | return height; 86 | } 87 | 88 | public void setHeight(int height) { 89 | this.height = height; 90 | } 91 | 92 | public int getBaseLine() { 93 | return baseLine; 94 | } 95 | 96 | public void setBaseLine(int baseLine) { 97 | this.baseLine = baseLine; 98 | } 99 | 100 | public int getBottomOffset() { 101 | return bottomOffset; 102 | } 103 | 104 | public void setBottomOffset(int bottomOffset) { 105 | this.bottomOffset = bottomOffset; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 25 | 26 | 27 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_main.xml: -------------------------------------------------------------------------------- 1 | 5 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igeek-YZ/ExpandTextView/1756ab22db25569bcf4b170980bbea8d3f1c19fa/app/src/main/res/mipmap-hdpi/down.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igeek-YZ/ExpandTextView/1756ab22db25569bcf4b170980bbea8d3f1c19fa/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igeek-YZ/ExpandTextView/1756ab22db25569bcf4b170980bbea8d3f1c19fa/app/src/main/res/mipmap-hdpi/up.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igeek-YZ/ExpandTextView/1756ab22db25569bcf4b170980bbea8d3f1c19fa/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igeek-YZ/ExpandTextView/1756ab22db25569bcf4b170980bbea8d3f1c19fa/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igeek-YZ/ExpandTextView/1756ab22db25569bcf4b170980bbea8d3f1c19fa/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igeek-YZ/ExpandTextView/1756ab22db25569bcf4b170980bbea8d3f1c19fa/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 16dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | ExpandTextView 3 | Settings 4 | 作为Android开发人员,免不了会研读下Android源码,之前在Windows平台一直使用SourceInsight这款优秀的代码分析阅读工具.转移到Mac平台后,一直没有找到合适的代替品,也用过 Eclipse , AndroidStudio 来导入源码,但是用起来还是别扭(主要是卡).在此推荐一款Mac下的SourceInsight替代品,代码分析阅读工具Understand. 5 | Main2ActivityMain2ActivityMain2ActivityMain2ActivityMain2ActivityMain2ActivityMain2ActivityMain2ActivityMain2ActivityMain2ActivityMain2ActivityMain2ActivityMain2ActivityMain2ActivityMain2ActivityMain2Activity 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 15 | 16 |