Wednesday, May 5, 2010

Android Custom TextView

Custom Text View
It will have following behavior-
1. A Single TextView will be having 2 segments of texts with different font and color options e.g. first and last name having different appearance
2. Two custom attributes to specify these 2 segments of text from XML layout e.g. “first_name” and “last_name”.
Following sections will guide you with the changes you need to make on Java code and XML files-
Creating Custom View
Important methods to overwrite-
-onMeasure()
-onDraw()
-Constructor (extend TextView class and its default constructors)
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
widthMeasureSpec – this contains some integer constant value rather than actual width. It indicates whether user has mentioned custom width or standard width definition e.g. fill_parent
heightMeasureSpec- constant value which indicates the procedure to find out drawing area height.
Width and Height calculation should be based on the text size (pixel width) and font height, unless user specifies values. Once width and height calculation is done using (widthMeasureSpec and heightMeasureSpec), you should set the required drawing area using-
setMeasuredDimension(reqWidth, reqHeight);
Note: It’s really important to define the correct size of the required drawing area. Android platform will not let you draw anywhere except your defined drawing area.
protected void onDraw(Canvas canvas)
Note: Android color is 4 byte value and Most Significant byte indicates Alpha value (00- complete transparent i.e. background will be visible and FF- complete non transparent, background is not visible)
Create Paint object with desired Font and Color information. Paint objects need to be passed as design briefing while drawing text or shapes.
Constructor- if you are not passing information of any attribute through layout XML.
Constructor with Attributes- if you want to define the TextView attributes e.g. width, height, initial text etc.
Adding Custom Attributes
1. Define a new NameSpace: xmlns:my="http://schemas.android.com/apk/res/com.my" (“com.my” is the package name defined in Manifest.xml)
2. Define the custom attributes in /res/values/attrs.xml file. Android platform need to know the new attributes that you will be using. Attrs.xml file solves the purpose. Specify the attributes within . Multiple “attr” tags can be grouped inside of “declare-styleable”. Please refer “Custom Layout Resources”. We will define 2 attributes- “first_name” and “last_name”.
xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyTextView">
<attr name="first_name" format="string"/>
<attr name="last_name" format="string"/>
declare-styleable>
resources>
3. Using custom attributes (first_name and last_name) in layout file-
Define attribute values in XML Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:my="http://schemas.android.com/apk/res/com.my"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<com.my.ui.MyTextView
android:id="@+id/MyTextView"
android:layout_width="fill_parent"
android:layout_height="50px"
my:first_name="Phil"
my:last_name="Jones"
/>
Read Attribute values in Java Code
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
for(int i=0; i < getAttributeCount(); i++){
Log.i(TAG, attrs.getAttributeName(i));
/*
* Read value of custom attributes
*/
this.firstText = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.my", "first_name");
this.lastText = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.my", "last_name");
}
Download the complete sample application, CustomTextView.zip

12 comments:

  1. thanks you ,that is very good
    save much my time

    ReplyDelete
  2. Ah very informative, fixed my problem (not even on Custom TextViews, other stuff, but the info was helpful). Thanks.

    ReplyDelete
  3. plz provide example source code...
    download link not working..
    thanks

    ReplyDelete
  4. not able to download the zip redirecting to this link....http://blogresources.googlegroups.com/web/CustomTextView.rar?hl=en

    ReplyDelete
  5. i wish i still can download the CustomTextView demo! =/

    ReplyDelete
  6. Pls download the code from-
    http://code.google.com/p/android-java-sample-code/downloads/list

    -Prasanta

    ReplyDelete
    Replies
    1. huray, my wish come true! thankyou so much!^_^!

      Delete
  7. Unlike the regular TextView in which if the text is too long to fit on the screen, it would start a new line; However, on your example if the text is too long to fit the screen, it would just continue on the same line and then disappeared(the part that doesn't fit). Do you know of a way to draw the text(if its too long to fit in one line) on a newline instead?

    thanks for the great tutorial and let me know if you think of a solution. thanks

    ReplyDelete
  8. To add the text wrap functionality, you need to calculate Width of your complete Text and based on the Width available for TextView, need to break the text and shift Y-co-ordinate by the char height and some padding.
    Well you need to right this logic. I don't have any existing sample.

    ReplyDelete
  9. Thank you very much Prasanta...very good tutorial...helped me a lot...

    ReplyDelete
  10. i don't usually comments on articles , but really you maaaaaade my daaaaaaaay , i have been searching every where , i was trying to get the attributes from the class , but i was writing the schema name only without the full url , thaaaaanks a lot

    ReplyDelete