您的位置:首页 > 移动开发 > Android开发

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

2013-08-14 23:23 771 查看
传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229
        今天我们学习如何自定义TextView组件,让它既能显示文本,又能显示图像,达到“图文并茂”的效果。这种图文混搭的方式常常被用来展现新闻、文章、彩信等内容。下面给出该情景的案例:

1案例技术要点

1.1创建attrs.xml文件用于设置自定义组件的属性、类型和样式。

1.2利用android.content.res.TypedArray类将自定义组件装载到程序,以供程序调用。

[java]
view plaincopyprint?

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

1.3布局文件引入自定义组件需要如下设置

自定义组件命名空间:

[html]
view plaincopyprint?

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

自定义组件标签:

[html]
view plaincopyprint?

<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 plaincopyprint?

<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>  

2.3strings.xml

[html]
view plaincopyprint?

<resources>  
    <string name="app_name">自定义TextView实现图文并茂</string>  
</resources>  

2.4自定义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>  

2.5main.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>  

2.6自定义组件类:CustomTextView.java

[java]
view plaincopyprint?

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);  
        }  
    };  
}  

2.7MainActivity.java

[java]
view plaincopyprint?

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);  
    }  
}  

3案例效果展示


 


TableLayout经常用到的属性有:

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

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



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



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

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



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

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



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



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



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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息