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

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情
传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229

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

1案例技术要点

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

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

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

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

自定义组件标签:

  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

  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

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

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

  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

  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

  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

  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该属性为空时,效果如下图:

0

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

1

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

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

2.1

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

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

2

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

3

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

4

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

5


Android开发:自定义TabLayout,神奇效果竟是如此简单,android音视频何俊林 //中间的形 Path pathCenter = new Path(); pathCenter.moveTo(tabPosition * textWidth + tabPosition * arcWidth, 0); pathCenter.cubicTo(tabPosition * textWidth + tabPosition * arcWidth - arcControlX, arcControlY, tabPosition * textWidth + tabPosition * arcWidth - 阅读详情

相关推荐

TableLayout制作自定义可点击表格

自定义表格,可以点击单元格事件,可以根据需要调整列的宽度。效果请参考: http://blog.csdn.net/shoneworn/article/details/52223277

android 可编辑的表格框架,GitHub - Tell-me502/smartTable: 一款android自动生成表格框架---An Android automatically genera...

SmartTableandroid自动生成表格框架功能介绍快速配置自动生成表格;自动计算表格宽高;表格列标题组合;表格固定左序列、顶部序列、第一行、列标题、统计行;自动统计,排序(自定义统计规则);表格图文、序列号、列标题格式化;表格各组成背景、文字、网格、padding等配置;表格批注;表格内容、列标题点击事件;缩放模式和滚动模式;注解模式;内容多行显示;分页模式;首尾动态添加数据;丰富的格式化...

weixin_30402231的博客 1033

glibc手动升级高版本导致系统(RedHat/Centos)异常(无法开机等)的解决方法(回退低版本glibc)

我的系统是Redhat7.6, 理论上Redhat7/Centos7都可以使用该方法解决问题。 首先慎重提醒各位:glibc升级会产生无法预料的后果!由于Android NDK需要高版本的glibc才可以使用,所以作死手动去更新了glibc2.18,使得重启系统后形界面消失。(Redhat/Centos升级此安装包最好用yum升级,因为系统内的程序对他们的依赖很大,升级会导致大部分程序无法使用...

weixin_42881528的博客 9678

android tible控件_Android自定义表格控件

Android平台已经给我们提供了很多标准的组件,如:TextView、EditView、Button、ImageView、Menu等,还有许多布局控件,常见的有:AbsoluteLayout、LinerLayout、RelativeLayout、TableLayout等。但随着人们对视觉的需求,基本组件已无法满足人们求新求异的要求,于是我们常常会自定义组件,用来实现更美观的UI界面。实现自定义...

weixin_39575007的博客 546

androidtableLayout自定义表格一

工作中遇到这样一个需求,要求在app端实现一个自定义table表格的模板,网上各种的实现方式有多种,但是对于tableLayout 组件的介绍以及实现,都不全面,不能实现自定义表格模板,尤其是划线部分,也让我困扰了好久,不过功夫不负有心人, 经过多次实践和努力,终于实现了利用tableLayout组件完成自定义table。 实现的效果如下: 实例1   实例2 实现过程如下: ...

hao10119的博客 2126

android图文混排的组件,Android 自定义控件进阶:图文混排

首先我们来看一下要达到的效果: 继续自定义View之旅,前面已经介绍过一个自定义View的基础的例子,Android 自定义控件起步:自定义TextView,如果你还对自定义View不了解可以去看看。今天给大家带来一个稍微复杂点的例子。自定义View显示一张片,下面包含片的文本介绍,似相片介绍什么的,不过不重要,主要是学习自定义View的用法么。还记得上一篇讲的4个步骤么:1、自定义View...

weixin_39798031的博客 321

Android Tablayout 自定义Tab布局的使用

开发公司的项目中需要实现以下效果,需要自定义TabLayout 中的TabTablayout xml <android.support.design.widget.TabLayout android:id="@+id/dialog_mod_icon_tablayout" android:layout_width="wrap_content" andr

Kenway090704的博客 1万+

android 高度等分,自定义TableLayout 整齐堆叠宽度等分布局

需求现有需求,按总宽度N等分,从左往右放置子布局,至最右处换下行继续,整体布局高度按照子布局高度逐级扩张。Android 自带的 GridLayout 和 TableLayout都不够好用,就自己写了个,原理和StackLabel似。代码import android.content.Context;import android.content.res.Resources;import andro...

weixin_30737899的博客 619

Android常用布局之TableLayout(表格布局)

Android常用布局之TableLayout(表格布局)

qq_62277763的博客 4563

android studio中表格的表头,表格组件GridManager的嵌套表头详解

嵌套表头这个功能在经历了多次调整后,终于在V2.13.0这个版本内发布。效果展示先来一张嵌套表头的效果如何使用配置起来相当简单,只需要在配置项中的columnData中增加children属性即可实现。children属性为数组型, 与columnData使用方式相同,children可无限嵌套。new GridManager(document.querySelector('table'), ...

weixin_33914679的博客 892

android表格布局最后一个组件,Android布局之TableLayout表格布局

Tablelayout以行和列的形式对控件进行管理,每一行为一个TableRow对象,或一个View控件。当为TableRow对象时,可在TableRow下添加子控件,默认情况下,每个子控件占据一列。 当为View时,该View将独占一行。三个常用的属性android:collapseColumns:设置需要被隐藏的列的序号android:shrinkColumns:设置允许被收缩的列的列序号a...

weixin_33491377的博客 294

android tible控件_android自定义表单,表格控件TableRowTextView

先上:TableRowTextView----单元格宽度自适应[app:cell_mode="wrapContent"]单元格宽度属性【app:cell_mode=wrapContent】 ,文字对齐方式【app:align=center】,是否绘制每个单元格之间的分割线【app:cell_divider=true】是否绘制表格上,下,左,右的线条【app:row_divider=left|to...

weixin_29157533的博客 375

安卓Tablayout自定义文字、指示器长度和颜色

安卓Tablayout自定义文字、指示器长度和颜色废话不多说,先上效果。没有效果的文章都是扯淡:安卓Tablayout自定义文字、指示器长度和颜色新的改变以上就是所有的代码附上demo源码。**如果有什么问题,欢迎大家指导。并相互联系,希望能够通过文章互相学习。** 废话不多说,先上效果。没有效果的文章都是扯淡: 安卓Tablayout自定义文字、指示器长度和颜色 之前写过一篇博客是tablayout+viewpager的基本实现,似今日头条的界面。随着需求和UI的不断提升,Android端需要

小口口的博客 2620

Android控件——Tablayout使用浅析(一)

1. Tablelayout序言 在一个app中,Tabs 使不同视和功能之间的切换变得简单。使用 tabs 将大量关联的数据或者选项划分成更易理解的分组,可以在不需要切换出当先上下文的情况下,有效的进行内容导航和内容组织。 Tablayout继承自HorizontalScrollView,用作页面切换指示器 这里给出一个相关Tablayout实现的效果: 从效果上可以看出,可以操作的属性...

zhewen的博客 1534

【andorid进阶篇之View-自定义tablayout】

这里写自定义目录标题 啥话不说,先亮出效果: 最近公司UI设计了一个这样的tab切换的样式,刚一看到UI的设计,感觉还是不错滴。但是几秒钟后,下意识想到,这个效果,Android自带的 tablayout 控件应该并不能实现这效果呢。顿时一脸茫然,我还要自定义一个不成!但是这个弧度怎么搞… 此时有的小伙伴可能会想,自定义view太麻烦,不如让UI直接把这个弧度切出来,不是一共就三个tab项嘛,Textview,ImageView… 这样横着排起来,然后做适当的显示和隐藏不就行啦。 是的,确实是可以,但

da_caoyuan的博客 6258

Android原生TabLayout使用全解析,看这篇就够了

前言 为什么会有这篇文章呢,是因为之前关于TabLayout的使用陆陆续续也写了好几篇了,感觉比较分散,且不成体系,写这篇文章的目的就是希望能把各种效果的实现一次性讲齐,所以也有了标题的「看这篇就够了」。 TabLayout作为导航组件来说,使用场景非常的多,也意味着要满足各种各样的需求。 在效果实现上,有很多同学都选择自定义View来做,定制性高,但易用性、稳定性、维护性不敢保证,使用官方组件能避免这些不确定性,一是开源,有很多大佬共建;二是经过大型app验证,比如google play;有了这两点,基本

yechaoa 4万+

Android TabLayout的自定义Tab

实现效果如下: 上代码: xml activity: 普通的tablayout实现起来比较麻烦,但是升级后的com.google.android.material.tabs.TabLayout就很棒,实现其他效果也很方便~

std7879的博客 2817

android 课表布局,自定义布局---TimeTableLayout(课程表布局)

一直在做一款教务系统的移动端应用,先前做的课程表控件不太满意,最近又在布局和功能上稍作调整。实现方式很普通,可以说是low,但效果如期就好,下面就开始给大家介绍此布局如何实现。1.还是先看效果:在电脑上显示效果不太好,部署到真机上,还是蛮不错的。演示.gif真机录完转GIF不清楚,来看大:a.pngb.pngc.png此自定义布局直接继承自RelativeLayout,思路就是动态计算尺寸,ad...

weixin_31741827的博客 701

Android 自定义表格控件

maven :gradle:compile ‘com.hlq:tableview:1.1.0’此外还需在项目根目录下的build.gradle中添加:xml布局中:上述设置为6行4列的表格在java代

feifei99_8820的博客 1226
上一篇: 快速排序算法的深入分析 -- 十二 July
下一篇: Json转换利器Gson之实例一-简单对象转化和带泛型的List转化
某笨緢_Jun
博客等级 码龄14年 128粉丝 54原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值