├── sample
├── lint.xml
├── libs
│ └── android-support-v4.jar
├── res
│ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ │ └── ic_launcher.png
│ ├── values-sw600dp
│ │ └── dimens.xml
│ ├── values
│ │ ├── dimens.xml
│ │ ├── color.xml
│ │ ├── styles.xml
│ │ └── strings.xml
│ ├── menu
│ │ └── main.xml
│ ├── values-sw720dp-land
│ │ └── dimens.xml
│ ├── values-v11
│ │ └── styles.xml
│ ├── values-v14
│ │ └── styles.xml
│ └── layout
│ │ └── activity_main.xml
├── project.properties
├── proguard-project.txt
├── AndroidManifest.xml
└── src
│ └── ir
│ └── mohsennavabi
│ └── justifiedtextviewtest
│ └── MainActivity.java
├── raw
└── JustifiedTextView.png
├── res
├── drawable-hdpi
│ └── ic_launcher.png
├── drawable-mdpi
│ └── ic_launcher.png
├── drawable-xhdpi
│ └── ic_launcher.png
├── values
│ ├── strings.xml
│ └── styles.xml
├── values-v11
│ └── styles.xml
└── values-v14
│ └── styles.xml
├── AndroidManifest.xml
├── .gitignore
├── project.properties
├── proguard-project.txt
├── README.md
└── src
└── ir
└── noghteh
├── XmlToClassAttribHandler.java
└── JustifiedTextView.java
/sample/lint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/raw/JustifiedTextView.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/navabi/JustifiedTextView/HEAD/raw/JustifiedTextView.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/navabi/JustifiedTextView/HEAD/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/navabi/JustifiedTextView/HEAD/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/navabi/JustifiedTextView/HEAD/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | JustifiedTextViewLibrary
4 |
5 |
--------------------------------------------------------------------------------
/sample/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/navabi/JustifiedTextView/HEAD/sample/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/sample/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/navabi/JustifiedTextView/HEAD/sample/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/navabi/JustifiedTextView/HEAD/sample/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/navabi/JustifiedTextView/HEAD/sample/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/navabi/JustifiedTextView/HEAD/sample/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/res/values-sw600dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/sample/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 | 20sp
7 |
8 |
9 |
--------------------------------------------------------------------------------
/sample/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/sample/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 |
--------------------------------------------------------------------------------
/sample/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/sample/res/values/color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #FF5000
5 | #F84545
6 | #30E35A
7 | #309BE3
8 | #E2E2E2
9 | #F1F1F1
10 | #D2D2D2
11 |
12 |
--------------------------------------------------------------------------------
/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/sample/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # built application files
2 | *.apk
3 | *.ap_
4 |
5 | # files for the dex VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # generated files
12 | bin/
13 | gen/
14 | /.settings/org.eclipse.jdt.core.prefs
15 | /sample/.settings/org.eclipse.jdt.core.prefs
16 | /sample/bin/
17 | /sample/gen/
18 |
19 | # Local configuration file (sdk path, etc)
20 | local.properties
21 | /sample/local.properties
22 |
23 | # Eclipse project files
24 | .classpath
25 | .project
26 | /sample/.classpath
27 | /sample/.project
28 |
--------------------------------------------------------------------------------
/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-18
15 | android.library=true
16 |
--------------------------------------------------------------------------------
/sample/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 | android.library.reference.1=..
16 |
--------------------------------------------------------------------------------
/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
--------------------------------------------------------------------------------
/sample/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/sample/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 |
--------------------------------------------------------------------------------
/sample/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
16 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # JustifiedTextView for Android
2 |
3 | This project provides a view for android apps that implements justified text view.
4 |
5 | 
6 |
7 | Android 2.0+ support
8 |
9 | ## Quick Setup
10 |
11 | #### 1. Include library
12 |
13 | **Manual:**
14 | * Downlaod the JustifiedTextView Library
15 | * Add it to your eclipse workspace
16 | * there is a sample project with the library that you can import as well
17 | * Go to your project properties and add JustifiedTextView as library
18 |
19 | #### 2. Application class
20 | ``` java
21 | public class MainActivity extends Activity {
22 |
23 | private JustifiedTextView mJTv;
24 |
25 | @Override
26 | protected void onCreate(Bundle savedInstanceState) {
27 | super.onCreate(savedInstanceState);
28 | setContentView(R.layout.activity_main);
29 |
30 | mJTv=(JustifiedTextView) findViewById(R.id.activity_main_jtv_text);
31 | mJTv.setText(getResources().getString(R.string.test));
32 | mJTv.setTextSize(TypedValue.COMPLEX_UNIT_SP,20);
33 | mJTv.setLineSpacing(15);
34 | mJTv.setBackgroundColor(Color.RED);
35 | mJTv.setAlignment(Align.LEFT);
36 | mJTv.setTypeFace(Typeface.createFromAsset(getAssets(), "fonts/naskh_bold.ttf"));
37 |
38 | }
39 | }
40 | ```
41 |
42 | ## 3. Xml
43 | ``` xml
44 |
49 |
50 |
61 |
62 |
63 |
64 | ```
65 |
66 |
67 | ## 4.License
68 | please inform us if you use this library ( navabi70-at-gmail)
69 |
70 | Copyright 2013-2014 Mohsen Navabi
71 |
72 |
--------------------------------------------------------------------------------
/sample/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | JustifiedTextViewTest
5 | Settings
6 | در اوت ۲۰۰۵، گوگل شرکت اندروید واقع در پالو آلتو، کالیفرنیا را خرید. شرکت کوچک اندروید که توسط اندی رابین، ریچ ماینرز، نیک سیرز و کریس وایت پایهگذاری شده بود، در زمینه تولید نرمافزار و برنامههای کاربردی برای تلفنهای همراه فعالیت میکرد. اندی رابین مدیر عامل اجرایی این شرکت پس از پیوستن اندروید به گوگل به سمت قائممقام مدیریت مهندسی این شرکت و مسئول پروژه اندروید در گوگل منصوب شد. تیم اندروید به رهبری رابین فعالیت خود را برای تولید سکوی تلفن همراه مبتنی بر هسته لینوکس آغاز کردند و نتیجه اولیه این پروژه در نشست خبری شرکت گوگل در ۵ نوامبر سال ۲۰۰۷، مطرح کردن اتحادیه گوشی باز بود. ۳۴ شرکت فعال در زمینه تولید نرمافزار، تولید تلفنهای همراه، اپراتور تلفن همراه و تولیدکننده نیمه رساناها و پردازندههای تلفن همراه اعضای بنیانگذار این اتحادیه بودند. در میان نامهای مشهور در بین اعضای مؤسس، شرکتهایی چون سامسونگ، الجی الکترونیکس، موتورولا، اچتیسی، تی-موبایل، انتیتی دوکومو، اینتل، انویدیا، تگزاس اینسترومنتس، کوالکام، برودکام، تلفونیکا، اسپرینت، ایبی و البته گوگل به چشم میخوردند. اریک اشمیت مدیر ارشد اجرایی گوگل در این مراسم گفت: «اعلام امروز بسیار جاهطلبانهتر از معرفی تنها یک تلفن گوگلی است که در چند هفته اخیر توسط رسانهها پیشبینی شده بود. از دیدگاه ما سکویی که ما ارائه کردهایم، هزاران تلفن گوناگون را به بازار روانه خواهد کرد.» نخستین گوشی مبتنی بر اندروید توسط شرکت اچتیسی با همکاری تی-موبایل تولید شد. این گوشی که به فاصله کمتر از یک سال از تشکیل اتحادیه گوشی باز یعنی در ۲۲ اکتبر ۲۰۰۸ تولید شد، در بازارهای مختلف به نامهای اچتیسی دریم، تی-موبایل جی۱ و ارا جی۱ به بازار عرضه گردید.
7 | Google acquired Android Inc. on August 17, 2005; key employees of Android Inc., including Rubin, Miner, and White, stayed at the company after the acquisition.Not much was known about Android Inc. at the time, but many assumed that Google was planning to enter the mobile phone market with this move.At Google, the team led by Rubin developed a mobile device platform powered by the Linux kernel. Google marketed the platform to handset makers and carriers on the promise of providing a flexible, upgradable system. Google had lined up a series of hardware component and software partners and signaled to carriers that it was open to various degrees of cooperation on their part.
8 | Speculation about Google\'s intention to enter the mobile communications market continued to build through December 2006.An earlier prototype codenamed "Sooner" had a closer resemblance to a BlackBerry phone, with no touchscreen, and a physical, QWERTY keyboard, but was later re-engineered to support a touchscreen, to compete with other announced devices such as the 2006 LG Prada and 2007 Apple iPhone.In September 2007, InformationWeek covered an Evalueserve study reporting that Google had filed several patent applications in the area of mobile telephony
9 |
10 |
--------------------------------------------------------------------------------
/sample/src/ir/mohsennavabi/justifiedtextviewtest/MainActivity.java:
--------------------------------------------------------------------------------
1 | package ir.mohsennavabi.justifiedtextviewtest;
2 |
3 | import ir.noghteh.JustifiedTextView;
4 | import android.os.Bundle;
5 | import android.app.Activity;
6 | import android.graphics.Paint.Align;
7 | import android.util.Log;
8 | import android.util.TypedValue;
9 | import android.view.Menu;
10 | import android.view.View;
11 | import android.view.View.OnClickListener;
12 | import android.widget.LinearLayout;
13 | import android.widget.SeekBar;
14 | import android.widget.SeekBar.OnSeekBarChangeListener;
15 | import android.widget.TextView;
16 |
17 | public class MainActivity extends Activity implements OnClickListener,
18 | OnSeekBarChangeListener {
19 |
20 | private JustifiedTextView mJTv;
21 | private TextView mTv;
22 | private SeekBar mSbSize;
23 | private LinearLayout mLlGreen, mLlRed;
24 | private TextView mTvEng, mTvFa;
25 |
26 | @Override
27 | protected void onCreate(Bundle savedInstanceState) {
28 | super.onCreate(savedInstanceState);
29 | setContentView(R.layout.activity_main);
30 | initViews();
31 | }
32 |
33 | private void initViews() {
34 | mJTv = (JustifiedTextView) findViewById(R.id.activity_main_jtv);
35 | mTv = (TextView) findViewById(R.id.activity_main_tv);
36 | mLlGreen = (LinearLayout) findViewById(R.id.activity_main_ll_green);
37 | mLlRed = (LinearLayout) findViewById(R.id.activity_main_ll_red);
38 | mTvEng = (TextView) findViewById(R.id.activity_main_tv_eng);
39 | mTvFa = (TextView) findViewById(R.id.activity_main_tv_fa);
40 |
41 | mSbSize = (SeekBar) findViewById(R.id.activity_main_sb_size);
42 | mSbSize.setMax(20);
43 | mSbSize.setProgress(10);
44 |
45 | mSbSize.setOnSeekBarChangeListener(this);
46 |
47 | mLlGreen.setOnClickListener(this);
48 | mLlRed.setOnClickListener(this);
49 | mTvEng.setOnClickListener(this);
50 | mTvFa.setOnClickListener(this);
51 | }
52 |
53 | @Override
54 | public void onClick(View arg0) {
55 | switch (arg0.getId()) {
56 | case R.id.activity_main_ll_red:
57 | mJTv.setTextColor(getResources().getColor(R.color.red));
58 | mTv.setTextColor(getResources().getColor(R.color.red));
59 | break;
60 | case R.id.activity_main_ll_green:
61 | mJTv.setTextColor(getResources().getColor(R.color.green));
62 | mTv.setTextColor(getResources().getColor(R.color.green));
63 | break;
64 | case R.id.activity_main_tv_eng:
65 | mJTv.setAlignment(Align.LEFT);
66 | mJTv.setText(R.string.text_eng);
67 | mTv.setText(R.string.text_eng);
68 | break;
69 | case R.id.activity_main_tv_fa:
70 | mJTv.setAlignment(Align.RIGHT);
71 | mJTv.setText(R.string.text_fa);
72 | mTv.setText(R.string.text_fa);
73 | break;
74 | default:
75 | break;
76 | }
77 | }
78 |
79 | @Override
80 | public void onProgressChanged(SeekBar arg0, int pos, boolean arg2) {
81 |
82 | int size = 10;
83 | mTv.setTextSize(TypedValue.COMPLEX_UNIT_SP, pos + size);
84 | mJTv.setTextSize(TypedValue.COMPLEX_UNIT_SP, pos + size);
85 | mJTv.setLineSpacing(pos - size);
86 | mTv.setLineSpacing(pos - size, 1);
87 | }
88 |
89 | @Override
90 | public void onStartTrackingTouch(SeekBar arg0) {
91 |
92 | }
93 |
94 | @Override
95 | public void onStopTrackingTouch(SeekBar arg0) {
96 |
97 | }
98 |
99 | }
100 |
--------------------------------------------------------------------------------
/src/ir/noghteh/XmlToClassAttribHandler.java:
--------------------------------------------------------------------------------
1 | package ir.noghteh;
2 |
3 | import android.content.Context;
4 | import android.content.res.Resources;
5 | import android.graphics.Color;
6 | import android.util.AttributeSet;
7 | import android.util.TypedValue;
8 |
9 | public class XmlToClassAttribHandler {
10 | private Resources mRes;
11 | private Context mContext;
12 | private AttributeSet mAttributeSet;
13 |
14 | private String namespace="http://noghteh.ir";
15 | private final String KEY_TEXT="text";
16 | private final String KEY_TEXT_SIZE="textSize";
17 | private final String KEY_TEXT_COLOR="textColor";
18 |
19 | public XmlToClassAttribHandler(Context context,AttributeSet attributeSet){
20 | mContext=context;
21 | mRes=mContext.getResources();
22 | mAttributeSet=attributeSet;
23 |
24 |
25 | }
26 |
27 | public String getTextValue(){
28 |
29 | String value=mAttributeSet.getAttributeValue(namespace, KEY_TEXT);
30 |
31 | if (value==null)
32 | return "";
33 |
34 | if (value.length()>1 &&
35 | value.charAt(0)=='@' &&
36 | value.contains("@string/")){
37 | int resId=mRes.getIdentifier(mContext.getPackageName()+":"+value.substring(1), null,null);
38 | value=mRes.getString(resId);
39 | }
40 |
41 | return value;
42 |
43 | }
44 |
45 | public int getColorValue(){
46 |
47 | String value=mAttributeSet.getAttributeValue(namespace, KEY_TEXT_COLOR);
48 |
49 | int color=Color.BLACK;
50 |
51 | if (value==null)
52 | return color;
53 |
54 | if (value.length()>1 &&
55 | value.charAt(0)=='@' &&
56 | value.contains("@color/")){
57 | int resId=mRes.getIdentifier(mContext.getPackageName()+":"+value.substring(1), null,null);
58 | color=mRes.getColor(resId);
59 |
60 | return color;
61 | }
62 |
63 |
64 | try{
65 | color=Color.parseColor(value);
66 | }
67 | catch(Exception e){
68 | return Color.BLACK;
69 | }
70 |
71 |
72 | return color;
73 | }
74 |
75 |
76 | public int getTextSize() {
77 | int textSize=12;
78 |
79 | String value=mAttributeSet.getAttributeValue(namespace, KEY_TEXT_SIZE );
80 |
81 | if (value==null)
82 | return textSize;
83 |
84 | if (value.length()>1 &&
85 | value.charAt(0)=='@' &&
86 | value.contains("@dimen/")){
87 | int resId=mRes.getIdentifier(mContext.getPackageName()+":"+value.substring(1), null,null);
88 | textSize=mRes.getDimensionPixelSize(resId);
89 |
90 | return textSize;
91 | }
92 |
93 | try{
94 | textSize=Integer.parseInt(value.substring(0, value.length()-2));
95 | }
96 | catch(Exception e){
97 | return 12;
98 | }
99 |
100 | return textSize;
101 | }
102 |
103 |
104 | public int gettextSizeUnit() {
105 |
106 | String value=mAttributeSet.getAttributeValue(namespace, KEY_TEXT_SIZE );
107 |
108 | if (value==null)
109 | return TypedValue.COMPLEX_UNIT_SP;
110 |
111 | try{
112 | String type=value.substring(value.length()-2, value.length());
113 |
114 | if (type.equals("dp"))
115 | return TypedValue.COMPLEX_UNIT_DIP;
116 | else if (type.equals("sp"))
117 | return TypedValue.COMPLEX_UNIT_SP;
118 | else if (type.equals("pt"))
119 | return TypedValue.COMPLEX_UNIT_PT;
120 | else if (type.equals("mm"))
121 | return TypedValue.COMPLEX_UNIT_MM;
122 | else if (type.equals("in"))
123 | return TypedValue.COMPLEX_UNIT_IN;
124 | else if (type.equals("px"))
125 | return TypedValue.COMPLEX_UNIT_PX;
126 | }
127 | catch(Exception e){
128 | return -1;
129 | }
130 |
131 | return -1;
132 | }
133 |
134 | }
135 |
--------------------------------------------------------------------------------
/sample/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
13 |
14 |
19 |
20 |
30 |
31 |
32 |
33 |
39 |
40 |
45 |
46 |
55 |
56 |
57 |
63 |
64 |
69 |
70 |
71 |
78 |
79 |
80 |
87 |
88 |
89 |
98 |
99 |
108 |
109 |
110 |
--------------------------------------------------------------------------------
/src/ir/noghteh/JustifiedTextView.java:
--------------------------------------------------------------------------------
1 | package ir.noghteh;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import android.content.Context;
7 | import android.graphics.Canvas;
8 | import android.graphics.Paint.Align;
9 | import android.graphics.Rect;
10 | import android.graphics.Typeface;
11 | import android.text.TextPaint;
12 | import android.util.AttributeSet;
13 | import android.util.Log;
14 | import android.util.TypedValue;
15 | import android.view.View;
16 | import android.view.ViewTreeObserver;
17 | import android.view.ViewTreeObserver.OnGlobalLayoutListener;
18 |
19 | /**
20 | * @author Mohsen Navabi
21 | * @version 1.0
22 | * @see http://www.mohsennavabi.ir
23 | * @see http://www.noghteh.ir
24 | */
25 | public class JustifiedTextView extends View {
26 |
27 | private Context mContext;
28 |
29 | private XmlToClassAttribHandler mXmlParser;
30 |
31 | private TextPaint textPaint;
32 |
33 | private int lineSpace=0;
34 |
35 | private int lineHeight;
36 |
37 | private int textAreaWidth;
38 |
39 | private int measuredViewHeight,measuredViewWidth;
40 |
41 | private String text;
42 |
43 | private List lineList=new ArrayList();
44 |
45 |
46 | /**
47 | * when we want to draw text after view created to avoid loop in drawing we use this boolean
48 | */
49 | boolean hasTextBeenDrown=false;
50 |
51 | public JustifiedTextView(Context context, AttributeSet attrs, int defStyle) {
52 | super(context, attrs, defStyle);
53 | constructor(context,attrs);
54 | }
55 | public JustifiedTextView(Context context, AttributeSet attrs) {
56 | super(context, attrs);
57 | constructor(context,attrs);
58 | }
59 | public JustifiedTextView(Context context) {
60 | super(context);
61 | constructor(context,null);
62 |
63 | }
64 |
65 | private void constructor(Context context, AttributeSet attrs) {
66 |
67 | mContext=context;
68 | mXmlParser=new XmlToClassAttribHandler(mContext,attrs);
69 | initTextPaint();
70 |
71 | if (attrs!=null){
72 | String text;
73 | int textColor;
74 | int textSize;
75 | int textSizeUnit;
76 |
77 | text=mXmlParser.getTextValue();
78 | textColor=mXmlParser.getColorValue();
79 | textSize=mXmlParser.getTextSize();
80 | textSizeUnit=mXmlParser.gettextSizeUnit();
81 |
82 |
83 | setText(text);
84 | setTextColor(textColor);
85 | if (textSizeUnit==-1)
86 | setTextSize(textSize);
87 | else
88 | setTextSize(textSizeUnit, textSize);
89 |
90 | // setText(XmlToClassAttribHandler.GetAttributeStringValue(mContext, attrs, namespace, key, ""));
91 |
92 | }
93 |
94 | ViewTreeObserver observer=getViewTreeObserver();
95 |
96 |
97 | observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
98 |
99 | @Override
100 | public void onGlobalLayout() {
101 |
102 | if (hasTextBeenDrown)
103 | return;
104 | hasTextBeenDrown=true;
105 | setTextAreaWidth(getWidth()-(getPaddingLeft()+getPaddingRight()));
106 | calculate();
107 |
108 | }
109 |
110 |
111 | });
112 |
113 | }
114 |
115 | private void calculate() {
116 | setLineHeight(getTextPaint());
117 | lineList.clear();
118 | lineList=divideOriginalTextToStringLineList(getText());
119 | setMeasuredDimentions(lineList.size(),getLineHeight(),getLineSpace());
120 | measure(getMeasuredViewWidth(),getMeasuredViewHeight());
121 | }
122 |
123 | private void initTextPaint(){
124 | textPaint=new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
125 | textPaint.setTextAlign(Align.RIGHT);
126 | }
127 |
128 | @Override
129 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
130 | if (getMeasuredViewWidth()>0){
131 | requestLayout();
132 | setMeasuredDimension(getMeasuredViewWidth(),getMeasuredViewHeight());
133 | }
134 | else{
135 | super.onMeasure(widthMeasureSpec, heightMeasureSpec );
136 | }
137 | invalidate();
138 | }
139 |
140 |
141 | private int rowIndex=0,colIndex=0;
142 | @Override
143 | protected void onDraw(Canvas canvas) {
144 |
145 | rowIndex=getPaddingTop();
146 | if (getAlignment()==Align.RIGHT)
147 | colIndex=getPaddingLeft()+getTextAreaWidth();
148 | else
149 | colIndex=getPaddingLeft();
150 |
151 | for (int i=0;i divideOriginalTextToStringLineList(String originalText) {
166 |
167 | List listStringLine=new ArrayList();
168 |
169 | String line="";
170 | float textWidth;
171 |
172 | String[] listParageraphes = originalText.split("\n");
173 |
174 | for(int j=0;j0){
237 |
238 | gapIndex=lineString.indexOf(" ", gapIndex+2);
239 | if (gapIndex==-1){
240 | gapIndex=0;
241 | gapIndex=lineString.indexOf(" ", gapIndex+1);
242 | if (gapIndex==-1)
243 | return lineString;
244 | }
245 |
246 | lineString=lineString.substring(0, gapIndex)+ " " +lineString.substring(gapIndex+1, lineString.length());
247 |
248 | lineWidth=textPaint.measureText(lineString);
249 | }
250 | return lineString;
251 | }
252 | /***
253 | * this method calculate height for a line of text according to defined TextPaint
254 | * @param textPaint
255 | */
256 | private void setLineHeight(TextPaint textPaint) {
257 |
258 | Rect bounds=new Rect();
259 | String sampleStr="این حسین کیست که عالم همه دیوانه اوست";
260 | textPaint.getTextBounds(sampleStr, 0,sampleStr.length(), bounds);
261 |
262 | setLineHeight(bounds.height());
263 |
264 | }
265 |
266 | /***
267 | * this method calculate view's height according to line count and line height and view's width
268 | * @param lineListSize
269 | * @param lineHeigth
270 | * @param lineSpace
271 | */
272 | public void setMeasuredDimentions(int lineListSize,int lineHeigth, int lineSpace){
273 | int mHeight=lineListSize*(lineHeigth+lineSpace)+lineSpace;
274 |
275 | mHeight+=getPaddingRight()+getPaddingLeft();
276 |
277 | setMeasuredViewHeight(mHeight);
278 |
279 | setMeasuredViewWidth(getWidth());
280 | }
281 |
282 |
283 | private int getTextAreaWidth() {
284 | return textAreaWidth;
285 | }
286 | private void setTextAreaWidth(int textAreaWidth) {
287 | this.textAreaWidth = textAreaWidth;
288 | }
289 |
290 | private int getLineHeight() {
291 | return lineHeight;
292 | }
293 | private int getMeasuredViewHeight() {
294 | return measuredViewHeight;
295 | }
296 | private void setMeasuredViewHeight(int measuredViewHeight) {
297 | this.measuredViewHeight = measuredViewHeight;
298 | }
299 | private int getMeasuredViewWidth() {
300 | return measuredViewWidth;
301 | }
302 | private void setMeasuredViewWidth(int measuredViewWidth) {
303 | this.measuredViewWidth = measuredViewWidth;
304 | }
305 | private void setLineHeight(int lineHeight) {
306 | this.lineHeight = lineHeight;
307 | }
308 |
309 | public String getText() {
310 | return text;
311 | }
312 |
313 | /***
314 | * Sets the string value of the JustifiedTextView. JustifiedTextView does not accept HTML-like formatting.
315 | * Related XML Attributes
316 | * -noghteh:text
317 | * @param text
318 | */
319 | public void setText(String text) {
320 | this.text = text;
321 | calculate();
322 | invalidate();
323 | }
324 |
325 | public void setText(int resid) {
326 | setText(mContext.getResources().getString(resid));
327 | }
328 |
329 | public Typeface getTypeFace() {
330 | return getTextPaint().getTypeface();
331 | }
332 | public void setTypeFace(Typeface typeFace) {
333 | getTextPaint().setTypeface(typeFace);
334 | }
335 |
336 | public float getTextSize() {
337 | return getTextPaint().getTextSize();
338 | }
339 | public void setTextSize(int unit,float textSize) {
340 | textSize=TypedValue.applyDimension(unit, textSize, mContext.getResources().getDisplayMetrics());
341 | setTextSize(textSize);
342 | }
343 |
344 | private void setTextSize(float textSize) {
345 | getTextPaint().setTextSize(textSize);
346 | calculate();
347 | invalidate();
348 | }
349 |
350 | public TextPaint getTextPaint() {
351 | return textPaint;
352 | }
353 | public void setTextPaint(TextPaint textPaint) {
354 | this.textPaint = textPaint;
355 | }
356 |
357 | /***
358 | * set text color
359 | * @param textColor
360 | */
361 | public void setTextColor(int textColor) {
362 | getTextPaint().setColor(textColor);
363 | invalidate();
364 | }
365 | /***
366 | * define space between lines
367 | * @param lineSpace
368 | */
369 | public void setLineSpacing(int lineSpace) {
370 | this.lineSpace = lineSpace;
371 | invalidate();
372 | }
373 |
374 | /***
375 | *
376 | * @return text color
377 | */
378 | public int getTextColor() {
379 | return getTextPaint().getColor();
380 | }
381 |
382 |
383 |
384 | /***
385 | * space between lines - default is 0
386 | * @return
387 | */
388 | public int getLineSpace() {
389 | return lineSpace;
390 | }
391 |
392 |
393 | /***
394 | * get text alignment
395 | * @return
396 | */
397 | public Align getAlignment() {
398 | return getTextPaint().getTextAlign();
399 | }
400 | /***
401 | * Align text according to your language
402 | * @param align
403 | */
404 | public void setAlignment(Align align) {
405 | getTextPaint().setTextAlign(align);
406 | invalidate();
407 | }
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 | }
417 |
--------------------------------------------------------------------------------