Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android自定義組件之TextView

Android自定義組件之TextView

編輯:關於Android編程

   今天我們學習如何自定義TextView組件,讓它既能顯示文本,又能顯示圖像,達到“圖文並茂”的效果。這種情景在新聞、文章、彩信內容中很常見。下面給出該場景的案例:

一、案例技術要點

1.創建attrs.xml文件用於設置自定義組件的屬性、類型和樣式。

2.利用android.content.res.TypedArray類將自定義組件裝載到程序,以供程序調用。

[java] 
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.customTextView); 

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.customTextView);3.布局文件引入自定義組件需要如下設置

自定義組件命名空間:

[html]
xmlns:custom="http://schemas.android.com/apk/res/com.custom.textview" 

xmlns:custom="http://schemas.android.com/apk/res/com.custom.textview"自定義組件標簽:

[html] view plaincopyprint?
<com.custom.textview.CustomTextView .../> 

<com.custom.textview.CustomTextView .../>4.構造一個HashMap數據結構,用於保存自定義組件的內容類型和值。

key:自定義組件的內容類型(image、text)

value:自定義組件的內容值(imageUrl,CharSequence)

5.利用android.widget.LinearLayout.LayoutParams類用於設置組件的布局參數。這裡需要根據顯示內容的類型動態地設置組件的布局參數。

二、案例代碼陳列

AndroidManifest.xml

[html] 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.custom.textview" 
    android:versionCode="1" 
    android:versionName="1.0" > 
 
    <uses-sdk 
        android:minSdkVersion="8" 
        android:targetSdkVersion="15" /> 
     
    <uses-permission android:name="android.permission.INTERNET"/> 
     
    <application 
        android:icon="@drawable/ic_launcher" 
        android:label="@string/app_name"> 
        <activity 
            android:name=".MainActivity" 
            android:label="@string/app_name" > 
            <intent-filter> 
                <action android:name="android.intent.action.MAIN" /> 
 
                <category android:name="android.intent.category.LAUNCHER" /> 
            </intent-filter> 
        </activity> 
    </application> 
     
</manifest> 

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.custom.textview"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />
   
    <uses-permission android:name="android.permission.INTERNET"/>
   
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
   
</manifest>strings.xml

[html] view plaincopyprint?
<resources> 
    <string name="app_name">自定義TextView實現圖文並茂</string> 
</resources> 

<resources>
    <string name="app_name">自定義TextView實現圖文並茂</string>
</resources>自定義TextView組件的屬性類型樣式文件:attrs.xml[html] view plaincopyprint?
<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <declare-styleable name="customTextView"> 
        <attr name="image_width" format="dimension" /> 
        <attr name="image_height" format="dimension" /> 
        <attr name="text_color" format="color" /> 
        <attr name="text_size" format="dimension" /> 
    </declare-styleable> 
</resources> 

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="customTextView">
        <attr name="image_width" format="dimension" />
        <attr name="image_height" format="dimension" />
        <attr name="text_color" format="color" />
        <attr name="text_size" format="dimension" />
    </declare-styleable>
</resources>main.xml

[java] view plaincopyprint?
<?xml version="1.0" encoding="utf-8" ?> 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:custom="http://schemas.android.com/apk/res/com.custom.textview" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" 
    android:background="@android:color/white" > 
 
    <com.custom.textview.CustomTextView 
        android:id="@+id/textView" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        custom:image_width="200dp" 
        custom:image_height="50dp" /> 
 
</LinearLayout> 

<?xml version="1.0" encoding="utf-8" ?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res/com.custom.textview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@android:color/white" >

    <com.custom.textview.CustomTextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        custom:image_width="200dp"
        custom:image_height="50dp" />

</LinearLayout>自定義組件類:CustomTextView.java

[java] 
package com.custom.textview; 
 
import java.net.URL; 
import java.util.ArrayList; 
import java.util.HashMap; 
 
import android.content.Context; 
import android.content.res.TypedArray; 
import android.graphics.drawable.Drawable; 
import android.os.Handler; 
import android.os.Message; 
import android.os.SystemClock; 
import android.text.Html; 
import android.util.AttributeSet; 
import android.view.Gravity; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 
import android.widget.TextView; 
 
public class CustomTextView extends LinearLayout { 
    private Context context; 
    private TypedArray typedArray; 
    private LayoutParams params; 
 
    public CustomTextView(Context context) { 
        super(context); 
    } 
 
    public CustomTextView(Context context, AttributeSet attrs) { 
        super(context, attrs); 
        this.context = context; 
        this.setOrientation(LinearLayout.VERTICAL); 
        // 從attrs.xml中獲取自定義屬性  
        typedArray = context.obtainStyledAttributes(attrs, R.styleable.customTextView); 
    } 
 
    public void setText(ArrayList<HashMap<String, String>> data) { 
        for (HashMap<String, String> hashMap : data) { 
            String type = hashMap.get("type"); 
            String value = hashMap.get("value"); 
            // 如果內容類型是圖片  
            if (type.equals("image")) { 
                // 設置圖片顯示寬高、集中  
                int imageWidth = typedArray.getDimensionPixelOffset(R.styleable.customTextView_image_width, 100); 
                int imageHeight = typedArray.getDimensionPixelOffset(R.styleable.customTextView_image_height, 100); 
                ImageView imageView = new ImageView(context); 
                params = new LayoutParams(imageWidth, imageHeight); 
                params.gravity = Gravity.CENTER_HORIZONTAL; 
                imageView.setLayoutParams(params); 
                // 顯示默認圖片  
                imageView.setImageResource(R.drawable.ic_launcher); 
                // 將ImageView添加到CustomTextView中  
                addView(imageView); 
                // 開啟工作線程異步加載圖片  
                new DownloadWork(value, imageView).start(); 
            } else if (type.equals("text")) { 
                int textColor = typedArray.getColor(R.styleable.customTextView_text_color, 0xFF0000FF); 
                float textSize = typedArray.getDimension(R.styleable.customTextView_text_size, 16); 
                TextView textView = new TextView(context); 
                textView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); 
                textView.setText(Html.fromHtml(value)); 
                textView.setTextColor(textColor); 
                textView.setTextSize(textSize); 
                addView(textView); 
            } 
        } 
    } 
 
    private class DownloadWork extends Thread { 
        private String imageUrl; 
        private ImageView imageView; 
 
        public DownloadWork(String imageUrl, ImageView imageView) { 
            this.imageUrl = imageUrl; 
            this.imageView = imageView; 
        } 
 
        @Override 
        public void run() { 
            URL url = null; 
            Drawable drawable = null; 
             int newImageWidth = 0; 
             int newImageHeight = 0; 
            try { 
                url = new URL(imageUrl); 
                drawable = Drawable.createFromStream(url.openStream(), "image"); 
                // 對圖片進行縮放  
                newImageWidth = drawable.getIntrinsicWidth() / 3; 
                newImageHeight = drawable.getIntrinsicHeight() / 3; 
            } catch (Exception e) { 
                e.printStackTrace(); 
            } 
            SystemClock.sleep(2000); 
 
            HashMap<String, Object> map = new HashMap<String, Object>(); 
            map.put("imageView", imageView); 
            map.put("drawable", drawable); 
            Message msg = handler.obtainMessage(); 
            msg.obj = map; 
            msg.arg1 = newImageWidth; 
            msg.arg2 = newImageHeight; 
            handler.sendMessage(msg); 
        } 
    } 
 
    private Handler handler = new Handler() { 
        public void handleMessage(Message msg) { 
            @SuppressWarnings("unchecked") 
            HashMap<String, Object> map = (HashMap<String, Object>) msg.obj; 
            ImageView imageView = (ImageView) map.get("imageView"); 
            LayoutParams params = new LayoutParams(msg.arg1, msg.arg2); 
            params.gravity = Gravity.CENTER_HORIZONTAL; 
            imageView.setLayoutParams(params); 
            Drawable drawable = (Drawable) map.get("drawable"); 
            imageView.setImageDrawable(drawable); 
        } 
    }; 

package com.custom.textview;

import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.text.Html;
import android.util.AttributeSet;
import android.view.Gravity;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class CustomTextView extends LinearLayout {
    private Context context;
    private TypedArray typedArray;
    private LayoutParams params;

    public CustomTextView(Context context) {
        super(context);
    }

    public CustomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        this.setOrientation(LinearLayout.VERTICAL);
        // 從attrs.xml中獲取自定義屬性
        typedArray = context.obtainStyledAttributes(attrs, R.styleable.customTextView);
    }

    public void setText(ArrayList<HashMap<String, String>> data) {
        for (HashMap<String, String> hashMap : data) {
            String type = hashMap.get("type");
            String value = hashMap.get("value");
            // 如果內容類型是圖片
            if (type.equals("image")) {
                // 設置圖片顯示寬高、集中
                int imageWidth = typedArray.getDimensionPixelOffset(R.styleable.customTextView_image_width, 100);
                int imageHeight = typedArray.getDimensionPixelOffset(R.styleable.customTextView_image_height, 100);
                ImageView imageView = new ImageView(context);
                params = new LayoutParams(imageWidth, imageHeight);
                params.gravity = Gravity.CENTER_HORIZONTAL;
                imageView.setLayoutParams(params);
                // 顯示默認圖片
                imageView.setImageResource(R.drawable.ic_launcher);
                // 將ImageView添加到CustomTextView中
                addView(imageView);
                // 開啟工作線程異步加載圖片
                new DownloadWork(value, imageView).start();
            } else if (type.equals("text")) {
                int textColor = typedArray.getColor(R.styleable.customTextView_text_color, 0xFF0000FF);
                float textSize = typedArray.getDimension(R.styleable.customTextView_text_size, 16);
                TextView textView = new TextView(context);
                textView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
                textView.setText(Html.fromHtml(value));
                textView.setTextColor(textColor);
                textView.setTextSize(textSize);
                addView(textView);
            }
        }
    }

    private class DownloadWork extends Thread {
        private String imageUrl;
        private ImageView imageView;

        public DownloadWork(String imageUrl, ImageView imageView) {
            this.imageUrl = imageUrl;
            this.imageView = imageView;
        }

        @Override
        public void run() {
            URL url = null;
            Drawable drawable = null;
             int newImageWidth = 0;
             int newImageHeight = 0;
            try {
                url = new URL(imageUrl);
                drawable = Drawable.createFromStream(url.openStream(), "image");
                // 對圖片進行縮放
                newImageWidth = drawable.getIntrinsicWidth() / 3;
                newImageHeight = drawable.getIntrinsicHeight() / 3;
            } catch (Exception e) {
                e.printStackTrace();
            }
            SystemClock.sleep(2000);

            HashMap<String, Object> map = new HashMap<String, Object>();
            map.put("imageView", imageView);
            map.put("drawable", drawable);
            Message msg = handler.obtainMessage();
            msg.obj = map;
            msg.arg1 = newImageWidth;
            msg.arg2 = newImageHeight;
            handler.sendMessage(msg);
        }
    }

    private Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            @SuppressWarnings("unchecked")
            HashMap<String, Object> map = (HashMap<String, Object>) msg.obj;
            ImageView imageView = (ImageView) map.get("imageView");
            LayoutParams params = new LayoutParams(msg.arg1, msg.arg2);
            params.gravity = Gravity.CENTER_HORIZONTAL;
            imageView.setLayoutParams(params);
            Drawable drawable = (Drawable) map.get("drawable");
            imageView.setImageDrawable(drawable);
        }
    };
}
MainActivity.java

[java]
package com.custom.textview; 
 
import java.util.ArrayList; 
import java.util.HashMap; 
 
import android.app.Activity; 
import android.os.Bundle; 
 
public class MainActivity extends Activity { 
     
    private final String text = " <p>  今年浙江衛視憑《中國好聲音》一舉做大" + 
            ",其巨大的影響力直接波及到了各家衛視“跨年晚會”的戰略部署。日前" + 
            ",“跨年晚會”概念的鼻祖湖南衛視率先表示“退出跨年燒錢大戰”。" + 
            "但據湖南衛視內部人士透露,即使如此,今年的湖南跨年晚會也將會掂出“跨年季”這個概念" + 
            ",“也就是從12月27日到12月31日,連續五天,我們將相繼用《百變大咖秀》、《快樂大本營》" + 
            "、《女人如歌》、《天天向上》的特別節目來連續打造這個”季“的概念,直到12月31日的那場晚會。”</p>"; 
 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
        // 采集顯示內容數據  
        ArrayList<HashMap<String, String>> data = new ArrayList<HashMap<String,String>>(); 
        HashMap<String, String> part1 = new HashMap<String, String>(); 
        part1.put("type", "image"); 
        part1.put("value", "http://www.linuxidc.com/upload/2012_12/121218101020341.png"); 
        HashMap<String, String> part2 = new HashMap<String, String>(); 
        part2.put("type", "text"); 
        part2.put("value", text); 
        HashMap<String, String> part3 = new HashMap<String, String>(); 
        part3.put("type", "image"); 
        part3.put("value", "http://www.linuxidc.com/upload/2012_12/121218101020341.png"); 
        data.add(part1); 
        data.add(part2); 
        data.add(part3); 
         
        CustomTextView customTextView = (CustomTextView) findViewById(R.id.textView); 
        customTextView.setText(data); 
    } 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved