Android定制组件之图文 (自定义组件图) + TableLayout属性

传送门 ☞ 轮子的专栏  ☞  转载请注明  ☞  http://blog.csdn.net/leverage_1229

        今天我们学习如何自定义TextView组件,让它既能显示文本,又能显示图像,达到“图文并茂”的效果。这种图文混搭的方式常常被用来展现新闻、文章、彩信等内容。下面给出该情景的案例:

1案例技术要点

1.1创建attrs.xml文件用于设置自定义组件的属性、类型和样式。
1.2利用android.content.res.TypedArray类将自定义组件装载到程序,以供程序调用。

[java] view plain copy print ?
  1. TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.customTextView);  

1.3布局文件引入自定义组件需要如下设置
自定义组件命名空间:

[html] view plain copy print ?
  1. xmlns:custom="http://schemas.android.com/apk/res/com.custom.textview"  

自定义组件标签:

[html] view plain copy print ?
  1. <com.custom.textview.CustomTextView .../>  

1.4构造一个HashMap数据结构,用于保存自定义组件的内容类型和值。

key:自定义组件的内容类型(image、text)

value:自定义组件的内容值(imageUrl,CharSequence)

1.5利用android.widget.LinearLayout.LayoutParams类用于设置组件的布局参数。这里需要根据显示内容的类型动态地设置组件的布局参数。

2案例代码陈列

2.1工程包目录


2.2AndroidManifest.xml

[html] view plain copy print ?
  1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     package="com.custom.textview"  
  3.     android:versionCode="1"  
  4.     android:versionName="1.0" >  
  5.   
  6.     <uses-sdk  
  7.         android:minSdkVersion="8"  
  8.         android:targetSdkVersion="15" />  
  9.       
  10.     <uses-permission android:name="android.permission.INTERNET"/>  
  11.       
  12.     <application  
  13.         android:icon="@drawable/ic_launcher"  
  14.         android:label="@string/app_name">  
  15.         <activity  
  16.             android:name=".MainActivity"  
  17.             android:label="@string/app_name" >  
  18.             <intent-filter>  
  19.                 <action android:name="android.intent.action.MAIN" />  
  20.   
  21.                 <category android:name="android.intent.category.LAUNCHER" />  
  22.             </intent-filter>  
  23.         </activity>  
  24.     </application>  
  25.       
  26. </manifest>  

2.3strings.xml

[html] view plain copy print ?
  1. <resources>  
  2.     <string name="app_name">自定义TextView实现图文并茂</string>  
  3. </resources>  

2.4自定义TextView组件的属性类型样式文件:attrs.xml

[html] view plain copy print ?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.     <declare-styleable name="customTextView">  
  4.         <attr name="image_width" format="dimension" />  
  5.         <attr name="image_height" format="dimension" />  
  6.         <attr name="text_color" format="color" />  
  7.         <attr name="text_size" format="dimension" />  
  8.     </declare-styleable>  
  9. </resources>  

2.5main.xml

[java] view plain copy print ?
  1. <?xml version="1.0" encoding="utf-8" ?>  
  2.  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:custom="http://schemas.android.com/apk/res/com.custom.textview"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     android:orientation="vertical"  
  7.     android:background="@android:color/white" >  
  8.   
  9.     <com.custom.textview.CustomTextView  
  10.         android:id="@+id/textView"  
  11.         android:layout_width="match_parent"  
  12.         android:layout_height="wrap_content"  
  13.         custom:image_width="200dp"  
  14.         custom:image_height="50dp" />  
  15.   
  16. </LinearLayout>  

2.6自定义组件类:CustomTextView.java

[java] view plain copy print ?
  1. package com.custom.textview;  
  2.   
  3. import java.net.URL;  
  4. import java.util.ArrayList;  
  5. import java.util.HashMap;  
  6.   
  7. import android.content.Context;  
  8. import android.content.res.TypedArray;  
  9. import android.graphics.drawable.Drawable;  
  10. import android.os.Handler;  
  11. import android.os.Message;  
  12. import android.os.SystemClock;  
  13. import android.text.Html;  
  14. import android.util.AttributeSet;  
  15. import android.view.Gravity;  
  16. import android.widget.ImageView;  
  17. import android.widget.LinearLayout;  
  18. import android.widget.TextView;  
  19.   
  20. public class CustomTextView extends LinearLayout {  
  21.     private Context context;  
  22.     private TypedArray typedArray;  
  23.     private LayoutParams params;  
  24.   
  25.     public CustomTextView(Context context) {  
  26.         super(context);  
  27.     }  
  28.   
  29.     public CustomTextView(Context context, AttributeSet attrs) {  
  30.         super(context, attrs);  
  31.         this.context = context;  
  32.         this.setOrientation(LinearLayout.VERTICAL);  
  33.         // 从attrs.xml中获取自定义属性  
  34.         typedArray = context.obtainStyledAttributes(attrs, R.styleable.customTextView);  
  35.     }  
  36.   
  37.     public void setText(ArrayList<HashMap<String, String>> data) {  
  38.         for (HashMap<String, String> hashMap : data) {  
  39.             String type = hashMap.get("type");  
  40.             String value = hashMap.get("value");  
  41.             // 如果内容类型是图片  
  42.             if (type.equals("image")) {  
  43.                 // 设置图片显示宽高、集中  
  44.                 int imageWidth = typedArray.getDimensionPixelOffset(R.styleable.customTextView_image_width, 100);  
  45.                 int imageHeight = typedArray.getDimensionPixelOffset(R.styleable.customTextView_image_height, 100);  
  46.                 ImageView imageView = new ImageView(context);  
  47.                 params = new LayoutParams(imageWidth, imageHeight);  
  48.                 params.gravity = Gravity.CENTER_HORIZONTAL;  
  49.                 imageView.setLayoutParams(params);  
  50.                 // 显示默认图片  
  51.                 imageView.setImageResource(R.drawable.ic_launcher);  
  52.                 // 将ImageView添加到CustomTextView中  
  53.                 addView(imageView);  
  54.                 // 开启工作线程异步加载图片  
  55.                 new DownloadWork(value, imageView).start();  
  56.             } else if (type.equals("text")) {  
  57.                 int textColor = typedArray.getColor(R.styleable.customTextView_text_color, 0xFF0000FF);  
  58.                 float textSize = typedArray.getDimension(R.styleable.customTextView_text_size, 16);  
  59.                 TextView textView = new TextView(context);  
  60.                 textView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));  
  61.                 textView.setText(Html.fromHtml(value));  
  62.                 textView.setTextColor(textColor);  
  63.                 textView.setTextSize(textSize);  
  64.                 addView(textView);  
  65.             }  
  66.         }  
  67.     }  
  68.   
  69.     private class DownloadWork extends Thread {  
  70.         private String imageUrl;  
  71.         private ImageView imageView;  
  72.   
  73.         public DownloadWork(String imageUrl, ImageView imageView) {  
  74.             this.imageUrl = imageUrl;  
  75.             this.imageView = imageView;  
  76.         }  
  77.   
  78.         @Override  
  79.         public void run() {  
  80.             URL url = null;  
  81.             Drawable drawable = null;  
  82.              int newImageWidth = 0;  
  83.              int newImageHeight = 0;  
  84.             try {  
  85.                 url = new URL(imageUrl);  
  86.                 drawable = Drawable.createFromStream(url.openStream(), "image");  
  87.                 // 对图片进行缩放  
  88.                 newImageWidth = drawable.getIntrinsicWidth() / 3;  
  89.                 newImageHeight = drawable.getIntrinsicHeight() / 3;  
  90.             } catch (Exception e) {  
  91.                 e.printStackTrace();  
  92.             }  
  93.             SystemClock.sleep(2000);  
  94.   
  95.             HashMap<String, Object> map = new HashMap<String, Object>();  
  96.             map.put("imageView", imageView);  
  97.             map.put("drawable", drawable);  
  98.             Message msg = handler.obtainMessage();  
  99.             msg.obj = map;  
  100.             msg.arg1 = newImageWidth;  
  101.             msg.arg2 = newImageHeight;  
  102.             handler.sendMessage(msg);  
  103.         }  
  104.     }  
  105.   
  106.     private Handler handler = new Handler() {  
  107.         public void handleMessage(Message msg) {  
  108.             @SuppressWarnings("unchecked")  
  109.             HashMap<String, Object> map = (HashMap<String, Object>) msg.obj;  
  110.             ImageView imageView = (ImageView) map.get("imageView");  
  111.             LayoutParams params = new LayoutParams(msg.arg1, msg.arg2);  
  112.             params.gravity = Gravity.CENTER_HORIZONTAL;  
  113.             imageView.setLayoutParams(params);  
  114.             Drawable drawable = (Drawable) map.get("drawable");  
  115.             imageView.setImageDrawable(drawable);  
  116.         }  
  117.     };  
  118. }  

2.7MainActivity.java

[java] view plain copy print ?
  1. package com.custom.textview;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.HashMap;  
  5.   
  6. import android.app.Activity;  
  7. import android.os.Bundle;  
  8.   
  9. public class MainActivity extends Activity {  
  10.       
  11.     private final String text = " <p>  今年浙江卫视凭《中国好声音》一举做大" +  
  12.             ",其巨大的影响力直接波及到了各家卫视“跨年晚会”的战略部署。日前" +  
  13.             ",“跨年晚会”概念的鼻祖湖南卫视率先表示“退出跨年烧钱大战”。" +  
  14.             "但据湖南卫视内部人士透露,即使如此,今年的湖南跨年晚会也将会掂出“跨年季”这个概念" +  
  15.             ",“也就是从12月27日到12月31日,连续五天,我们将相继用《百变大咖秀》、《快乐大本营》" +  
  16.             "、《女人如歌》、《天天向上》的特别节目来连续打造这个”季“的概念,直到12月31日的那场晚会。”</p>";  
  17.   
  18.     @Override  
  19.     public void onCreate(Bundle savedInstanceState) {  
  20.         super.onCreate(savedInstanceState);  
  21.         setContentView(R.layout.main);  
  22.         // 采集显示内容数据  
  23.         ArrayList<HashMap<String, String>> data = new ArrayList<HashMap<String,String>>();  
  24.         HashMap<String, String> part1 = new HashMap<String, String>();  
  25.         part1.put("type""image");  
  26.         part1.put("value""http://www.linuxidc.com/upload/2012_12/121218101020341.png");  
  27.         HashMap<String, String> part2 = new HashMap<String, String>();  
  28.         part2.put("type""text");  
  29.         part2.put("value", text);  
  30.         HashMap<String, String> part3 = new HashMap<String, String>();  
  31.         part3.put("type""image");  
  32.         part3.put("value""http://www.linuxidc.com/upload/2012_12/121218101020341.png");  
  33.         data.add(part1);  
  34.         data.add(part2);  
  35.         data.add(part3);  
  36.           
  37.         CustomTextView customTextView = (CustomTextView) findViewById(R.id.textView);  
  38.         customTextView.setText(data);  
  39.     }  
  40. }  

3案例效果展示

 


TableLayout经常用到的属性有:

android:collapseColumns:以第0行为序,隐藏指定的列:

android:collapseColumns该属性为空时,效果如下图:

Android定制组件之图文 (自定义组件图) + TableLayout属性_第1张图片

把android:collapseColumns=0,2--------------》意思是把第0和第2列去掉,如下图:

1

android:shrinkColumns:以第0行为序,自动延伸指定的列填充可用部分:

当LayoutRow里面的控件还没有布满布局时,shrinkColumns不起作用,如下图:

2.1

设置了shrinkColumns=0,1,2,布局完全没有改变,因为LayoutRow里面还剩足够的空间。

当LayoutRow布满控件时,如下图:

2

设置设置了shrinkColumns=2,则结果如下图,控件自动向垂直方向填充空间:

android:stretchColumns:以第0行为序,尽量把指定的列填充空白部分:

4

设置stretchColumns=1,则结果如下图,第1列被尽量填充(Button02与TextView02同时向右填充,直到TextView03被压挤到最后边)。

5


你可能感兴趣的:(类,HashMap,imageview,自定义组件)