├── .classpath ├── .gitignore ├── .project ├── AndroidManifest.xml ├── README.md ├── bin ├── AndroidManifest.xml ├── classes │ └── com │ │ └── example │ │ └── justifytwodemo │ │ ├── BuildConfig.class │ │ ├── MainActivity.class │ │ ├── R$attr.class │ │ ├── R$dimen.class │ │ ├── R$drawable.class │ │ ├── R$id.class │ │ ├── R$layout.class │ │ ├── R$menu.class │ │ ├── R$string.class │ │ ├── R$style.class │ │ ├── R.class │ │ ├── TextJustifyUtils.class │ │ └── TextViewEx.class └── jarlist.cache ├── proguard-project.txt ├── project.properties ├── res ├── drawable-hdpi │ └── ic_launcher.png ├── drawable-mdpi │ └── ic_launcher.png ├── drawable-xhdpi │ └── ic_launcher.png ├── drawable-xxhdpi │ └── ic_launcher.png ├── layout │ └── activity_main.xml ├── menu │ └── main.xml ├── values-sw600dp │ └── dimens.xml ├── values-sw720dp-land │ └── dimens.xml ├── values-v11 │ └── styles.xml ├── values-v14 │ └── styles.xml └── values │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── screen-shot.png └── src └── com └── example └── justifytwodemo ├── MainActivity.java ├── TextJustifyUtils.java └── TextViewEx.java /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /libs 2 | /gen 3 | /bin 4 | /assets 5 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | TextJustifyDemo 4 | 5 | 6 | 7 | 8 | 9 | com.android.ide.eclipse.adt.ResourceManagerBuilder 10 | 11 | 12 | 13 | 14 | com.android.ide.eclipse.adt.PreCompilerBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | com.android.ide.eclipse.adt.ApkBuilder 25 | 26 | 27 | 28 | 29 | 30 | com.android.ide.eclipse.adt.AndroidNature 31 | org.eclipse.jdt.core.javanature 32 | 33 | 34 | -------------------------------------------------------------------------------- /AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ###TextJustifyDemo是在[TextJustify-Android](https://github.com/bluejamesbond/TextJustify-Android)的基础上做一些改进,适用于大部分语系居中对齐。 2 | 3 | ##效果图 4 | ![result](/screen-shot.png) 5 | -------------------------------------------------------------------------------- /bin/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /bin/classes/com/example/justifytwodemo/BuildConfig.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VernonLee/TextJustifyDemo/54a914c17e400c6af955cad3d3f6f27803f525be/bin/classes/com/example/justifytwodemo/BuildConfig.class -------------------------------------------------------------------------------- /bin/classes/com/example/justifytwodemo/MainActivity.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VernonLee/TextJustifyDemo/54a914c17e400c6af955cad3d3f6f27803f525be/bin/classes/com/example/justifytwodemo/MainActivity.class -------------------------------------------------------------------------------- /bin/classes/com/example/justifytwodemo/R$attr.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VernonLee/TextJustifyDemo/54a914c17e400c6af955cad3d3f6f27803f525be/bin/classes/com/example/justifytwodemo/R$attr.class -------------------------------------------------------------------------------- /bin/classes/com/example/justifytwodemo/R$dimen.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VernonLee/TextJustifyDemo/54a914c17e400c6af955cad3d3f6f27803f525be/bin/classes/com/example/justifytwodemo/R$dimen.class -------------------------------------------------------------------------------- /bin/classes/com/example/justifytwodemo/R$drawable.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VernonLee/TextJustifyDemo/54a914c17e400c6af955cad3d3f6f27803f525be/bin/classes/com/example/justifytwodemo/R$drawable.class -------------------------------------------------------------------------------- /bin/classes/com/example/justifytwodemo/R$id.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VernonLee/TextJustifyDemo/54a914c17e400c6af955cad3d3f6f27803f525be/bin/classes/com/example/justifytwodemo/R$id.class -------------------------------------------------------------------------------- /bin/classes/com/example/justifytwodemo/R$layout.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VernonLee/TextJustifyDemo/54a914c17e400c6af955cad3d3f6f27803f525be/bin/classes/com/example/justifytwodemo/R$layout.class -------------------------------------------------------------------------------- /bin/classes/com/example/justifytwodemo/R$menu.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VernonLee/TextJustifyDemo/54a914c17e400c6af955cad3d3f6f27803f525be/bin/classes/com/example/justifytwodemo/R$menu.class -------------------------------------------------------------------------------- /bin/classes/com/example/justifytwodemo/R$string.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VernonLee/TextJustifyDemo/54a914c17e400c6af955cad3d3f6f27803f525be/bin/classes/com/example/justifytwodemo/R$string.class -------------------------------------------------------------------------------- /bin/classes/com/example/justifytwodemo/R$style.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VernonLee/TextJustifyDemo/54a914c17e400c6af955cad3d3f6f27803f525be/bin/classes/com/example/justifytwodemo/R$style.class -------------------------------------------------------------------------------- /bin/classes/com/example/justifytwodemo/R.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VernonLee/TextJustifyDemo/54a914c17e400c6af955cad3d3f6f27803f525be/bin/classes/com/example/justifytwodemo/R.class -------------------------------------------------------------------------------- /bin/classes/com/example/justifytwodemo/TextJustifyUtils.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VernonLee/TextJustifyDemo/54a914c17e400c6af955cad3d3f6f27803f525be/bin/classes/com/example/justifytwodemo/TextJustifyUtils.class -------------------------------------------------------------------------------- /bin/classes/com/example/justifytwodemo/TextViewEx.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VernonLee/TextJustifyDemo/54a914c17e400c6af955cad3d3f6f27803f525be/bin/classes/com/example/justifytwodemo/TextViewEx.class -------------------------------------------------------------------------------- /bin/jarlist.cache: -------------------------------------------------------------------------------- 1 | # cache for current jar dependency. DO NOT EDIT. 2 | # format is 3 | # Encoding is UTF-8 4 | -------------------------------------------------------------------------------- /proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-19 15 | -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VernonLee/TextJustifyDemo/54a914c17e400c6af955cad3d3f6f27803f525be/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VernonLee/TextJustifyDemo/54a914c17e400c6af955cad3d3f6f27803f525be/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VernonLee/TextJustifyDemo/54a914c17e400c6af955cad3d3f6f27803f525be/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VernonLee/TextJustifyDemo/54a914c17e400c6af955cad3d3f6f27803f525be/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 15 | 16 | 21 | 22 | 28 | 29 | 33 | 34 | 38 | 39 | 43 | 44 | 48 | 49 | 55 | 56 | 61 | 62 | 67 | 68 | 73 | 74 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /res/menu/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /res/values-sw600dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /res/values-sw720dp-land/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 128dp 8 | 9 | 10 | -------------------------------------------------------------------------------- /res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /res/values-v14/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16dp 5 | 16dp 6 | 7 | 8 | -------------------------------------------------------------------------------- /res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | TextJustify 5 | Settings 6 | Before 7 | After 8 | 文中内容摘自互联网 9 | 10 | We challenged ourselves to create a visual language for our users that synthesizes 11 | the classic principles of good design with the innovation and possibility of technology and science. This is 12 | material design. This spec is a living document that will be updated as we continue to develop the tenets 13 | and specifics of material design 14 | 15 | 每个人都渴望自由,没有人不爱自由。打从出生开始一直都是规规矩矩的生活,小时候被家 16 | 里人各种教导各种告诫,长大之后被老师各种教训各种提醒,再之后,就是被社会被不得不继续的生活各种限制束缚。 17 | 很多选择都不是自己选的,很多事情都不是自己想要的。但是生活还在继续,不能真的像电视剧里面的主人公那样 18 | 勇敢那样冒险。生活没有剧本,编剧都不止我们自己。 19 | 20 | 세계적인 과학자 에디슨은 청각장애를 앓고 있었던 사람이었다. 그 때문에 그는 다른 소리를 21 | 듣지 않고 연구에 몰입하였기에 목적을 달성할 수 있었다.어느 날 에디슨의 친구가 아들을 데리고 와서 “여보게, 22 | 내 아들인데 이놈에게 평생 좌우명이 될만한 이야기를 좀 해주게”라고 말했다. 23 | 24 | 有島武郎(1878-1923年)東京生まれ。10歳で学習院予備科に入学。19歳で学 25 | 習院中東全科を卒。その後札幌農学校キリスと教に感化された。卒業して軍隊生活を送った後、渡米。帰国後はふ 26 | たたび予備見習士官や大学の英語講師として過ごしていたが、志賀直哉らと出会い同人誌『白樺』に参加。文学者 27 | としての活動を開始し、白樺派の中心人物の一人として小説や評論で活躍した。 28 | -------------------------------------------------------------------------------- /res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /screen-shot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VernonLee/TextJustifyDemo/54a914c17e400c6af955cad3d3f6f27803f525be/screen-shot.png -------------------------------------------------------------------------------- /src/com/example/justifytwodemo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.justifytwodemo; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | import android.view.Menu; 6 | 7 | public class MainActivity extends Activity { 8 | private TextViewEx tvEnglish, tvChinese, tvJapan, tvKorea; 9 | 10 | @Override 11 | protected void onCreate(Bundle savedInstanceState) { 12 | super.onCreate(savedInstanceState); 13 | setContentView(R.layout.activity_main); 14 | 15 | tvEnglish = (TextViewEx) findViewById(R.id.txt_english); 16 | tvEnglish.setText(getString(R.string.english), true); 17 | 18 | tvChinese = (TextViewEx) findViewById(R.id.txt_chinese); 19 | tvChinese.setText(getString(R.string.chinese), true); 20 | 21 | tvJapan = (TextViewEx) findViewById(R.id.txt_japan); 22 | tvJapan.setText(getString(R.string.japan), true); 23 | 24 | tvKorea = (TextViewEx) findViewById(R.id.txt_korea); 25 | tvKorea.setText(getString(R.string.korean), true); 26 | } 27 | 28 | @Override 29 | public boolean onCreateOptionsMenu(Menu menu) { 30 | getMenuInflater().inflate(R.menu.main, menu); 31 | return true; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/com/example/justifytwodemo/TextJustifyUtils.java: -------------------------------------------------------------------------------- 1 | package com.example.justifytwodemo; 2 | 3 | import android.graphics.Paint; 4 | import android.view.Gravity; 5 | import android.widget.TextView; 6 | 7 | public class TextJustifyUtils{ 8 | // Please use run(...) instead 9 | public static void justify(TextView textView) 10 | { 11 | Paint paint = new Paint(); 12 | 13 | String [] blocks; 14 | float spaceOffset = 0; 15 | float textWrapWidth = 0; 16 | 17 | int spacesToSpread; 18 | float wrappedEdgeSpace; 19 | String block; 20 | String [] lineAsWords; 21 | String wrappedLine; 22 | String smb = ""; 23 | Object [] wrappedObj; 24 | 25 | // Pull widget properties 26 | paint.setColor(textView.getCurrentTextColor()); 27 | paint.setTypeface(textView.getTypeface()); 28 | paint.setTextSize(textView.getTextSize()); 29 | 30 | textWrapWidth = textView.getWidth(); 31 | spaceOffset = paint.measureText(" "); 32 | blocks = textView.getText().toString().split("((?<=\n)|(?=\n))"); 33 | 34 | if(textWrapWidth < 20) 35 | { 36 | return; 37 | } 38 | 39 | for(int i = 0; i < blocks.length; i++) 40 | { 41 | block = blocks[i]; 42 | 43 | if(block.length() == 0) 44 | { 45 | continue; 46 | } 47 | else if(block.equals("\n")) 48 | { 49 | smb += block; 50 | continue; 51 | } 52 | 53 | block = block.trim(); 54 | 55 | if(block.length() == 0) continue; 56 | 57 | wrappedObj = TextJustifyUtils.createWrappedLine(block, paint, spaceOffset, textWrapWidth); 58 | wrappedLine = ((String) wrappedObj[0]); 59 | wrappedEdgeSpace = (Float) wrappedObj[1]; 60 | lineAsWords = wrappedLine.split(" "); 61 | spacesToSpread = (int) (wrappedEdgeSpace != Float.MIN_VALUE ? wrappedEdgeSpace/spaceOffset : 0); 62 | 63 | for(String word : lineAsWords) 64 | { 65 | smb += word + " "; 66 | 67 | if(--spacesToSpread > 0) 68 | { 69 | smb += " "; 70 | } 71 | } 72 | 73 | smb = smb.trim(); 74 | 75 | 76 | if(blocks[i].length() > 0) 77 | { 78 | blocks[i] = blocks[i].substring(wrappedLine.length()); 79 | 80 | if(blocks[i].length() > 0) 81 | { 82 | smb += "\n"; 83 | } 84 | 85 | i--; 86 | } 87 | } 88 | 89 | textView.setGravity(Gravity.LEFT); 90 | textView.setText(smb); 91 | } 92 | 93 | 94 | public static Object [] createWrappedLine(String block, Paint paint, float spaceOffset, float maxWidth) 95 | { 96 | float cacheWidth = maxWidth; 97 | float origMaxWidth = maxWidth; 98 | 99 | String line = ""; 100 | 101 | for(String word : block.split("\\s")) 102 | { 103 | cacheWidth = paint.measureText(word); 104 | maxWidth -= cacheWidth; 105 | 106 | if(maxWidth <= 0) 107 | { 108 | return new Object[] { line, maxWidth + cacheWidth + spaceOffset }; 109 | } 110 | 111 | line += word; 112 | } 113 | 114 | if(paint.measureText(block) <= origMaxWidth) 115 | { 116 | return new Object[] { block, Float.MIN_VALUE }; 117 | } 118 | return new Object[] { line, maxWidth }; // [The act, therefore, was designed to, fulfill , 32.0] 119 | } 120 | 121 | final static String SYSTEM_NEWLINE = "\n"; 122 | final static float COMPLEXITY = 5.12f; //Reducing this will increase efficiency but will decrease effectiveness 123 | final static Paint p = new Paint(); 124 | 125 | /* @author Mathew Kurian */ 126 | 127 | public static void run(final TextView tv, float origWidth) { 128 | String s = tv.getText().toString(); 129 | p.setTypeface(tv.getTypeface()); 130 | String [] splits = s.split(SYSTEM_NEWLINE); 131 | float width = origWidth - 5; 132 | for(int x = 0; xwidth){ 134 | splits[x] = wrap(splits[x], width, p); 135 | String [] microSplits = splits[x].split(SYSTEM_NEWLINE); 136 | for(int y = 0; ywidth) 158 | smb.append(SYSTEM_NEWLINE); 159 | }catch(Exception e){} 160 | smb.append(str[x] + " "); 161 | } 162 | return smb.toString().replaceFirst(SYSTEM_NEWLINE, ""); 163 | } 164 | private static String removeLast(String s, String g){ 165 | if(s.contains(g)){ 166 | int index = s.lastIndexOf(g); 167 | int indexEnd = index + g.length(); 168 | if(index == 0) return s.substring(1); 169 | else if(index == s.length()-1) return s.substring(0, index); 170 | else 171 | return s.substring(0, index) + s.substring(indexEnd); 172 | } 173 | return s; 174 | } 175 | private static String justifyOperation(String s, float width, Paint p){ 176 | float holder = (float) (COMPLEXITY*Math.random()); 177 | while(s.contains(Float.toString(holder))) 178 | holder = (float) (COMPLEXITY*Math.random()); 179 | String holder_string = Float.toString(holder); 180 | float lessThan = width; 181 | int timeOut = 100; 182 | int current = 0; 183 | while(p.measureText(s) lineAsWords; 53 | private Object[] wrappedObj; 54 | 55 | private Bitmap cache = null; 56 | private boolean cacheEnabled = false; 57 | private BreakIterator boundary; 58 | 59 | public TextViewEx(Context context, AttributeSet attrs, int defStyle) 60 | { 61 | super(context, attrs, defStyle); 62 | // set a minimum of left and right padding so that the texts are not too close to the side screen 63 | this.setPadding(10, 0, 10, 0); 64 | } 65 | 66 | public TextViewEx(Context context, AttributeSet attrs) 67 | { 68 | super(context, attrs); 69 | this.setPadding(10, 0, 10, 0); 70 | } 71 | 72 | public TextViewEx(Context context) 73 | { 74 | super(context); 75 | this.setPadding(10, 0, 10, 0); 76 | } 77 | 78 | @Override 79 | public void setPadding(int left, int top, int right, int bottom) { 80 | // TODO Auto-generated method stub 81 | super.setPadding(left, top, right, bottom); 82 | // super.setPadding(left+10, top, right+10, bottom); 83 | } 84 | 85 | @Override 86 | public void setDrawingCacheEnabled(boolean cacheEnabled) 87 | { 88 | this.cacheEnabled = cacheEnabled; 89 | } 90 | 91 | public void setText(String st, boolean wrap) 92 | { 93 | wrapEnabled = wrap; 94 | super.setText(st); 95 | } 96 | public void setTextAlign(Align align) 97 | { 98 | _align=align; 99 | } 100 | @SuppressLint({ "NewApi", "DrawAllocation" }) 101 | @Override 102 | protected void onDraw(Canvas canvas) 103 | { 104 | // If wrap is disabled then, 105 | // request original onDraw 106 | if(!wrapEnabled) 107 | { 108 | super.onDraw(canvas); 109 | return; 110 | } 111 | 112 | // Active canas needs to be set 113 | // based on cacheEnabled 114 | Canvas activeCanvas = null; 115 | 116 | // Set the active canvas based on 117 | // whether cache is enabled 118 | if (cacheEnabled) { 119 | 120 | if (cache != null) { 121 | // Draw to the OS provided canvas 122 | // if the cache is not empty 123 | canvas.drawBitmap(cache, 0, 0, paint); 124 | return; 125 | } else { 126 | // Create a bitmap and set the activeCanvas 127 | // to the one derived from the bitmap 128 | cache = Bitmap.createBitmap(getWidth(), getHeight(), 129 | Config.ARGB_4444); 130 | activeCanvas = new Canvas(cache); 131 | } 132 | } else { 133 | // Active canvas is the OS 134 | // provided canvas 135 | activeCanvas = canvas; 136 | } 137 | 138 | // Pull widget properties 139 | paint.setColor(getCurrentTextColor()); 140 | paint.setTypeface(getTypeface()); 141 | paint.setTextSize(getTextSize()); 142 | paint.setTextAlign(_align); 143 | paint.setFlags(Paint.ANTI_ALIAS_FLAG); 144 | 145 | //minus out the paddings pixel 146 | dirtyRegionWidth = getWidth()-getPaddingLeft()-getPaddingRight(); 147 | int maxLines = Integer.MAX_VALUE; 148 | int currentapiVersion = android.os.Build.VERSION.SDK_INT; 149 | if (currentapiVersion >= android.os.Build.VERSION_CODES.JELLY_BEAN) 150 | { 151 | maxLines = getMaxLines(); 152 | } 153 | 154 | int lines = 1; 155 | 156 | blocks = getText().toString().split("((?<=\n)|(?=\n))"); 157 | verticalOffset = horizontalFontOffset = getLineHeight() - 0.5f; // Temp fix 158 | spaceOffset = paint.measureText(" "); 159 | 160 | boundary = BreakIterator.getLineInstance(); 161 | lineAsWords = new Vector(); 162 | 163 | for(int i = 0; i 0) 231 | { 232 | blocks[i] = blocks[i].substring(wrappedLine.length()); 233 | verticalOffset += blocks[i].length() > 0 ? horizontalFontOffset : 0; 234 | i--; 235 | } 236 | } 237 | 238 | if (cacheEnabled) 239 | { 240 | // Draw the cache onto the OS provided 241 | // canvas. 242 | canvas.drawBitmap(cache, 0, 0, paint); 243 | } 244 | } 245 | 246 | public Object [] createWrappedLine(String block, Paint paint, float spaceOffset, float maxWidth) 247 | { 248 | float cacheWidth = maxWidth; 249 | float origMaxWidth = maxWidth; 250 | 251 | String line = ""; 252 | 253 | lineAsWords.clear(); 254 | boundary.setText(block); 255 | int start = boundary.first(); 256 | for(int end = boundary.next(); end!=BreakIterator.DONE; start=end, end = boundary.next()) 257 | { 258 | lineAsWords.add(block.substring(start, end)); 259 | } 260 | 261 | for(String word : lineAsWords) 262 | { 263 | cacheWidth = paint.measureText(word); 264 | maxWidth -= cacheWidth; 265 | 266 | if(maxWidth <= 0) 267 | { 268 | return new Object[] { line, maxWidth + cacheWidth + spaceOffset }; 269 | } 270 | 271 | line += word; 272 | } 273 | 274 | if(paint.measureText(block) <= origMaxWidth) 275 | { 276 | return new Object[] { block, Float.MIN_VALUE }; 277 | } 278 | return new Object[] { line, maxWidth }; 279 | } 280 | } --------------------------------------------------------------------------------