Android笔记(六十七) 自定义控件

      实际编程中,系统提供的控件往往无法满足我们的需求,一来是样子丑陋,二来是一些复杂的组合需要多次使用的话,每次都写一堆控件的组合会很耗费时间,所以我们将这些组件的组合自定义为一个新的控件,以后使用的时候直接用该控件,方便又简单。最常见的例子就是软件中的titleTar

 

      实现自定义控件的步骤:

      1.设置控件的属性

      2.实现我们的View

      3.引用我们自定的View

  官方文档:http://developer.android.com/training/custom-views/create-view.html

下面开始:

设置控件的属性:

  分析一下上面四个titleBar,都是由一个居中的文本和一个右边一个图片按钮组成,只不过后面两个没有按钮而已

  那么我们自定义的这个组件就得包含一下几个基本属性:文本内容,文本大小,文本颜色,按钮路径

  在value中新建一个xml文件attrs.xml,把这些属性创建出来

<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="MyCustomTitleBar"><attr name="titleText" format="string"/><attr name="titleTextSize" format="dimension"/><attr name="titleTextColor" format="color"/><attr name="titleButtonImage" format="reference"/></declare-styleable>
</resources>
  declare-styleable标签是用来定义自定义控件的属性的,我们的控件属性都以attr形式存放在declare-styleable标签中,format是用来形容该属性的类型,有如下值可选:string,color,dimension,integer,enum,reference,float,boolean,fraction,flag

实现我们的View

      定义一个继承自RelativeLayout的类MyCustomTitltBar,然后在他的构造方法中获取我们自定义的控件样式

package cn.lixyz.customviewdemo;import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.TextView;@SuppressLint("NewApi")
public class MyCustomTitleBar extends RelativeLayout {// 定义自定义控件包含的组件private TextView title;private ImageButton button;// 定义控件的属性private String titleText;private float titleTextSize;private int titleTextColor;private Drawable titleButtonImage;// 为每个控件定义LayoutParamsprivate LayoutParams textLayoutParams;private LayoutParams buttonLayoutParams;public MyCustomTitleBar(Context context, AttributeSet attrs) {super(context, attrs);// 获取我们定义的属性TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MyCustomTitleBar);titleText = array.getString(R.styleable.MyCustomTitleBar_titleText);titleTextColor = array.getColor(R.styleable.MyCustomTitleBar_titleTextColor, 0);titleTextSize = array.getDimension(R.styleable.MyCustomTitleBar_titleTextSize, 10);titleButtonImage = array.getDrawable(R.styleable.MyCustomTitleBar_titleButtonImage);// 回收,以防出错
        array.recycle();// 新建包含的子组件title = new TextView(context);button = new ImageButton(context);// 为子组件赋值
        title.setText(titleText);title.setTextColor(titleTextColor);title.setTextSize(titleTextSize);button.setBackground(titleButtonImage);// 设置背景色setBackgroundColor(0xFF38373c);// 设置包含控件的属性并添加到view中textLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);textLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);addView(title, textLayoutParams);buttonLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);buttonLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);addView(button, buttonLayoutParams);}
}

   其中LayoutParams是用于child view(子视图) 向 parent view(父视图)传达自己的意愿的一个东西

  在获取属性的时候,android定义的格式为控件名_属性名  例如上面的MyCustomTitleBar_titleText、MyCustomTitleBar_titleTextSize

      LayoutParams继承于Android.View.ViewGroup.LayoutParams. 
      LayoutParams相当于一个Layout的信息包,它封装了Layout的位置、高、宽等信息。假设在屏幕上一块区域是由一个Layout占领的,如果将一个View添加到一个Layout中,最好告诉Layout用户期望的布局方式,也就是将一个认可的layoutParams传递进去。 
      可以这样去形容LayoutParams,在象棋的棋盘上,每个棋子都占据一个位置,也就是每个棋子都有一个位置的信息,如这个棋子在4行4列,这里的“4行4列”就是棋子的LayoutParams。 
      但LayoutParams类也只是简单的描述了宽高,宽和高都可以设置成三种值: 
           1,一个确定的值; 
           2,FILL_PARENT,即填满(和父容器一样大小); 
           3,WRAP_CONTENT,即包裹住组件就好。 

           http://byandby.iteye.com/blog/816718

  TypedArray实例是个属性的容器,通过context.obtainStyledAttributes()方法返回得到

引用我们自定的View

      在布局文件中引入我们自定义的控件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:custom="http://schemas.android.com/apk/res/cn.lixyz.customviewdemo"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context="cn.lixyz.customviewdemo.MainActivity" ><cn.lixyz.customviewdemo.MyCustomTitleBarandroid:layout_width="wrap_content"android:layout_height="wrap_content"custom:titleButtonImage="@drawable/image"custom:titleText="通讯录"custom:titleTextColor="#ffffff"custom:titleTextSize="5dp" ></cn.lixyz.customviewdemo.MyCustomTitleBar><cn.lixyz.customviewdemo.MyCustomTitleBarandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="10dp"custom:titleButtonImage="@drawable/plus"custom:titleText="微信"custom:titleTextColor="#ffffff"custom:titleTextSize="5dp" ></cn.lixyz.customviewdemo.MyCustomTitleBar><cn.lixyz.customviewdemo.MyCustomTitleBarandroid:layout_width="wrap_content"android:layout_height="30dp"android:layout_marginTop="10dp"custom:titleText="发现"custom:titleTextColor="#ffffff"custom:titleTextSize="5dp" ></cn.lixyz.customviewdemo.MyCustomTitleBar><cn.lixyz.customviewdemo.MyCustomTitleBarandroid:layout_width="wrap_content"android:layout_height="30dp"android:layout_marginTop="10dp"custom:titleText="我"custom:titleTextColor="#ffffff"custom:titleTextSize="5dp" ></cn.lixyz.customviewdemo.MyCustomTitleBar></LinearLayout>

      一定要在布局中引入我们的命名空间

  格式为:xmlns:自定义名称="http://schemas.android.com/apk/res/包名"
  因为只有引入了我们的命名空间,才可以使用xxx:xxx格式来设置我们定义的属性,我们平时使用的android:xx也是因为上面的xmlns:android="http://schemas.android.com/apk/res/android"
  这样运行一下软件查看效果

      为按钮设置点击事件

      观察我们平时为按钮设置点击事件时候的方法:

bt.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stub
                }});

      我们通过按钮的setOnClickListener方法传入一个匿名内部类OnClickListener为按钮设置点击事件,我们查看OnClickListener的介绍

    /*** Interface definition for a callback to be invoked when a view is clicked.*/public interface OnClickListener {/*** Called when a view has been clicked.** @param v The view that was clicked.*/void onClick(View v);}

  

      我们也可以仿照这个形式,为我们的MyCustomTieleBar设置一个setCustomTitleBarListener,然后传入一个内部类来让这个按钮的点击调用这个类的click方法

      修改MyCustomTitleBar:

package cn.lixyz.customviewdemo;import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.TextView;@SuppressLint("NewApi")
public class MyCustomTitleBar extends RelativeLayout {// 定义自定义控件包含的组件private TextView title;private ImageButton button;// 定义控件的属性private String titleText;private float titleTextSize;private int titleTextColor;private Drawable titleButtonImage;// 为每个控件定义LayoutParamsprivate LayoutParams textLayoutParams;private LayoutParams buttonLayoutParams;private customTitleBarListener listener;public interface customTitleBarListener {public void click();}public void setCustomTitleBarListener(customTitleBarListener listener) {this.listener = listener;}public MyCustomTitleBar(Context context, AttributeSet attrs) {super(context, attrs);// 获取我们定义的属性TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MyCustomTitleBar);titleText = array.getString(R.styleable.MyCustomTitleBar_titleText);titleTextColor = array.getColor(R.styleable.MyCustomTitleBar_titleTextColor, 0);titleTextSize = array.getDimension(R.styleable.MyCustomTitleBar_titleTextSize, 10);titleButtonImage = array.getDrawable(R.styleable.MyCustomTitleBar_titleButtonImage);// 回收,以防出错
        array.recycle();// 新建包含的子组件title = new TextView(context);button = new ImageButton(context);// 为子组件赋值
        title.setText(titleText);title.setTextColor(titleTextColor);title.setTextSize(titleTextSize);button.setBackground(titleButtonImage);// 设置背景色setBackgroundColor(0xFF38373c);// 设置包含控件的属性并添加到view中textLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);textLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);addView(title, textLayoutParams);buttonLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);buttonLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);addView(button, buttonLayoutParams);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {listener.click();}});}
}

  这样我们在MainActivity中就可以为按钮设置点击事件了

package cn.lixyz.customviewdemo;import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;public class MainActivity extends Activity {private MyCustomTitleBar addressListBar, wechatBar;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button bt = new Button(this);bt.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stub
                }});addressListBar = (MyCustomTitleBar) findViewById(R.id.addressListBar);wechatBar = (MyCustomTitleBar) findViewById(R.id.wechatBar);addressListBar.setCustomTitleBarListener(new MyCustomTitleBar.customTitleBarListener() {@Overridepublic void click() {Toast.makeText(MainActivity.this, "通讯录按钮被点击", Toast.LENGTH_SHORT).show();}});wechatBar.setCustomTitleBarListener(new MyCustomTitleBar.customTitleBarListener() {@Overridepublic void click() {Toast.makeText(MainActivity.this, "微信按钮被点击", Toast.LENGTH_SHORT).show();}});}}

 

 

 
 

转载于:https://www.cnblogs.com/xs104/p/5077406.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/257906.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux系统rootpassword改动

重新启动系统。 进入系统引导界面&#xff1a; 按下e键&#xff1a; 选择第二项。内核启动參数设置&#xff0c;按下e键&#xff1a; 在结尾处&#xff0c;输入数字 1或者 英文 " single"&#xff0c;再回车&#xff1a; 按下b键启动。此时以单用户模式级别引导启动程…

(转) Quartz学习——SSMM(Spring+SpringMVC+Mybatis+Mysql)和Quartz集成详解(四)

http://blog.csdn.net/u010648555/article/details/60767633 当任何时候觉你得难受了&#xff0c;其实你的大脑是在进化&#xff0c;当任何时候你觉得轻松&#xff0c;其实都在使用以前的坏习惯。 通过前面的学习&#xff0c;你可能大致了解了Quartz&#xff0c;本篇博文为你打…

被流氓360设置浏览器主页的解决办法(如果你也遇到了跟我一样的问题,不妨看一下是不是这个原因)...

最近电脑罢工&#xff0c;重装了系统&#xff1b;很多常用软件都不得不重新安装&#xff0c;其实这都不是事儿&#xff0c;现在基本上都是百兆光纤了&#xff0c;下载安装都很顺溜。 浏览器也在安装之列&#xff0c;因为搞开发所以谷歌火狐浏览器都是必装的&#xff1b;平时基本…

BZOJ1834 [ZJOI2010]network 网络扩容

网络流训练好题。。。但是要给差评&#xff01;蒟蒻表示这就是板子题&#xff0c;然后做了半个小时T T 先跑一边最大流&#xff0c;得到第一问答案ans。 第二问&#xff1a;原先的边不动&#xff0c;费用为0。 然后对每条边在上面再加一条边&#xff0c;流量为inf&#xff0c;费…

android 更新平台,Android更新平台架构方案

这篇文章是去年写的&#xff0c;我们的两款app一直这使用umeng的更新服务&#xff0c;但是16年umeng开始放弃更新服务&#xff0c;考虑到切换到其他更新平台也会面临这样的问题&#xff0c;我开始着手自己搭建一个更新平台。整体方案包含前后端&#xff0c;客户端代码封装成jar…

Storm编程入门API系列之Storm的可靠性的ACK消息确认机制

概念&#xff0c;见博客 Storm概念学习系列之storm的可靠性 什么业务场景需要storm可靠性的ACK确认机制&#xff1f; 答&#xff1a;想要保住数据不丢&#xff0c;或者保住数据总是被处理。即若没被处理的&#xff0c;得让我们知道。 public void nextTuple() {num;System.out.…

iOS网络编程开发-数据加密

iOS网络编程开发-数据加密 一、简单说明 1.说明 在开发应用的时候&#xff0c;数据的安全性至关重要&#xff0c;而仅仅用POST请求提交用户的隐私数据&#xff0c;还是不能完全解决安全问题。 如&#xff1a;可以利用软件&#xff08;比如Charles&#xff09;设置代理服务器&am…

图片向上滚动字幕代码html,如何通过制作滚动字幕的软件实现这种片尾的向上滚动字幕效果...

如何制作滚动字幕 特殊滚动类字幕制作 向上向下向左向右滚动字幕制作效果 含拖动和消失全程 真是酷B了爽呆了&#xff0c;赶快学习吧&#xff01;电影、连续剧等影视作品片尾&#xff0c;都会在播放片尾曲时&#xff0c;出现向上滚动的字幕&#xff0c;显示演员表、导演、编剧等…

【图片服务器】搭建Nginx图片服务器

一、安装Nginx 二、安装vsftpd 三、开始搭建Nginx图片服务器 1、效果 例如&#xff1a;图片通过ftp服务上传到/home/ftpuser/www/images目录下&#xff0c;我想通过访问Nginx服务器来访问ftp目录下的图片文件&#xff0c;该url为http://192.168.128.128/images/xxx.jpg。即使用…

html怎么让方块自动旋转,如何使用纯CSS实现一个圆环旋转错觉的动画效果(附源码)...

本篇文章给大家带来的内容是关于如何使用纯CSS实现一个圆环旋转错觉的动画效果&#xff0c;有一定的参考价值&#xff0c;有需要的朋友可以参考一下&#xff0c;希望对你有所帮助。效果预览源代码下载https://github.com/comehope/front-end-daily-challenges代码解读定义 dom&…

同志亦凡人第五季/全集BQueer As Folk 5迅雷下载

同志亦凡人 第五季 Queer as Folk Season 5 (2005) 本季看点&#xff1a;这是一群生活在匹兹堡男人和男人&#xff0c;女人和女人的故事。在他们的王国里有各色人物。王国的国王Brian&#xff08;葛尔?哈罗德 Gale Harold 饰&#xff09;&#xff0c;只追求性不问爱&#xff1…

html怎么使图片无法另存为,如何禁止图片另存为?禁止网页另存为到本地的方法...

在很多企事业单位&#xff0c;处于商业机密保护的需要&#xff0c;常常需要禁止一些文件格式的“另存为”功能&#xff0c;防止通过“另存为”将文件另行保存&#xff0c;据为己有的目的&#xff1b;尤其是在局域网中访问服务器共享文件的时候&#xff0c;常常需要禁止将共享文…

正益工场为京西创客工场输送双创“软”实力

12月30日&#xff0c;中关村门头沟科技园“京西创客工场”正式揭牌&#xff0c;这里将成为京西“生态科创”的聚集地。正益工场作为唯一入驻的“移动互联网”双创生态平台&#xff0c;将为双创输送“移动技术移动模式”等软实力。北京市副市长隋振江、市政协、中关村管委会等领…

几种服务器端IO模型的简单介绍及实现(转载)

作者&#xff1a;阿凡卢 出处&#xff1a;http://www.cnblogs.com/luxiaoxun/服务器端几种模型&#xff1a; 1、阻塞式模型&#xff08;blocking IO&#xff09; 我们第一次接触到的网络编程都是从 listen()、accpet()、send()、recv() 等接口开始的。使用这些接口可以很方便的…

2021年高考成绩查询襄阳状元,大胆猜测一下,2021年高考,湖北省文理状元会花落谁家?...

随着2021年高考的逼近&#xff0c;考生进入紧张有序的复习中&#xff0c;家长也在为孩子筹谋着哪所学校更适合&#xff0c;作为吃瓜群众的我们&#xff0c;可能更关注今年湖北省的文理科状元会花落谁家&#xff0c;要知道&#xff0c;一所学校如果可以出现一名高考状元&#xf…

为什么写Java程序需要接口

为什么写Java程序需要接口 我之所以以这个作为标题&#xff0c;并不是为了玩噱头&#xff0c;讲一些似是而非的空话&#xff0c;还是以探索加发现&#xff0c; 追本溯源的讲解一下为什么Java需要接口&#xff0c;怎么理解&#xff0c;怎么用它。 首先接口并不是Java才有的&…

《领域特定语言》一1.5使用代码生成

1.5使用代码生成 在迄今为止的讨论中&#xff0c;要处理DSL&#xff0c;组装“语义模型”&#xff08;第11章&#xff09;&#xff0c;然后执行语义模型&#xff0c;提供我们希望从控制器得到的行为。在语言圈子里&#xff0c;这种方式称为解释&#xff08;interpretation&…

SVG 基础图形

SVG 基础图形 SVG包含了以下的基础图形元素&#xff1a; 矩形&#xff08;包括可选的圆角&#xff09;&#xff0c;使用<rect>元素创建圆形&#xff0c;使用<circle>元素创建椭圆形&#xff0c;使用<ellipse>元素创建直线&#xff0c;使用<line>元素创…

枣庄三中高考2021成绩查询,2021枣庄中考成绩查询系统入口

2021枣庄中考成绩查询系统入口2021-05-20 19:11:35文/王佳慧2021年&#xff0c;枣庄的中考时间快到了&#xff0c;本文分享了枣庄中考成绩查询入口&#xff0c;系统开通后考生可登陆查询成绩。枣庄中考成绩查询入口志愿填报须知1.录取标准&#xff1a;提前批、第一批、第三批学…

移动端”宴席知多少

转载(http://adt.aicai.com/index.php/archives/179/) 瞎折腾移动端的项目已经很长一段时间了&#xff0c;并不像其它企业一样&#xff0c;可以有项目组去完成&#xff0c;基本都是一个人瞎尝试&#xff0c;时而web&#xff0c;时而web app。恍恍惚惚过了这段岁月&#xff0c;也…