自定义View_2_关于自定义组合View
自定义View(2)
Android当中给我们提供了丰富的UI控件,当然也许满足不了我们的需求,我们就必须学会自定义自己的View,我们怎么算是自定义自己的view呢! 我们会根据原来有的View对View进行功能的扩展,对已有的控件进行组合来生成新的View,或者又我们自己完全的自定义一个View
所以自定义View 大致的分为三种:
1、创建复合控件
2、对现有的View进行扩展,
3、重写View来实现全新的View。
当然难度也是慢慢的上升的,下面我们先介绍几个在自定义控件当中,比较常用的几个回调方法。
- onFinishInfate():在我们加载XML的时候,当加载完最后一个节点的时候,会做回调处理
- onSizeChanged():在组件的大小改变的时候会做回调处理
- onMeasure():在测量组件的大小的时候会做回调处理
- onLayout():在确定组件位置的时候会做回调处理
- onTouchEvent():在发生触摸事件的时候会做回调处理
在我们自定义控件的时候,有可能会去用到上述自己比较重要的方法,所以在开始的时候我们先来学习一下这些方法的用法,学习完以后我们来看第一种自定义控件的方法,创建复合型控件
1、创建复合控件
这种自定义控件通常需要继承一个ViewGroup,再给它添加指定功能的控件,从而组合成为新的功能的控件,通过这种方式创建的控件,我们一般会给他们指定一些自己的属性,让它可以更加灵活的使用,下面我们就以“自定义TopBar”为例。
1、定义自己的属性,
我们自定义的控件有时候也希望和原生的控件一样,要有自己的属性,我们也可以像原生控件那样舒适的去使用我们自己的控件,当然了Android为用户提供了这种实现,我们首先在res资源目录下的values目录下创建一个名字为attrs.xml的一个属性创建文件,并且在该文件当中定义如下代码定义相应的资源
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TopBar">
<attr name="titleText" format="string"/>
<attr name="titleTextSize" format="dimension"/>
<attr name="titleTextColor" format="color"/>
<attr name="leftTextColor" format="color"/>
<attr name="leftBackground" format="color|reference"/>
<attr name="leftText" format="string"/>
<attr name="rightTextColor" format="color"/>
<attr name="rightBackground" format="color|reference"/>
<attr name="rightText" format="string"/>
</declare-styleable>
</resources>
2、我们创建一个自定义控件-TopBar,并且让它继承ViewGroup,从而组合一些需要的控件。在构造方法里面我们通过TypedArray来获取在XML布局文件里面自定义的哪些属性,
package com.suansuan.view;
import com.suansuan.customcombinationcontrol.R;
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.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.view.View.OnClickListener;
/**
* 自定义的组合控件TopBar
* @author liusuansuan
*
*/
@SuppressLint("NewApi")
public class TopBar extends RelativeLayout implements OnClickListener{
private int mLeftTextColor,mRightTextColor,mTitleColor;
private String mLeftText,mRightText,mTitleText;
private Drawable mLeftBackground,mRightBackground;
private float mTitleSize;
private TopbarClickListener mListener;
private Button mLeftButton,mRightButton;
private TextView mTitle;
public TopBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context,attrs);
}
public TopBar(Context context, AttributeSet attrs) {
super(context, attrs);
init(context,attrs);
}
public TopBar(Context context) {
super(context);
}
/**
* 初始化操作
* @param context
* @param attrs
*/
private void init(Context context, AttributeSet attrs) {
TypedArray attributes = context.obtainStyledAttributes(attrs,R.styleable.TopBar);
mLeftTextColor = attributes.getColor(R.styleable.TopBar_leftTextColor, 0);
mLeftBackground = attributes.getDrawable(R.styleable.TopBar_leftBackground);
mLeftText = attributes.getString(R.styleable.TopBar_leftText);
mRightTextColor = attributes.getColor(R.styleable.TopBar_rightTextColor, 0);
mRightBackground = attributes.getDrawable(R.styleable.TopBar_rightBackground);
mRightText = attributes.getString(R.styleable.TopBar_rightText);
mTitleSize = attributes.getDimension(R.styleable.TopBar_titleTextSize, 10);
mTitleColor = attributes.getColor(R.styleable.TopBar_titleTextColor, 0);
mTitleText = attributes.getString(R.styleable.TopBar_titleText);
//注意:一定要调用recycle()
attributes.recycle();
initDataForView(context);
}
/**
* 把数据放到空间之中
* @param context
*/
private void initDataForView(Context context) {
mLeftButton = new Button(context);
mRightButton = new Button(context);
mTitle = new TextView(context);
mLeftButton.setBackground(mLeftBackground);
mLeftButton.setText(mLeftText);
mLeftButton.setTextColor(mLeftTextColor);
mLeftButton.setOnClickListener(this);
SetViewLocation(RelativeLayout.ALIGN_PARENT_LEFT,mLeftButton);
mRightButton.setBackground(mRightBackground);
mRightButton.setText(mRightText);
mRightButton.setTextColor(mRightTextColor);
mRightButton.setOnClickListener(this);
SetViewLocation(RelativeLayout.ALIGN_PARENT_RIGHT,mRightButton);
mTitle.setTextSize(mTitleSize);
mTitle.setTextColor(mTitleColor);
mTitle.setText(mTitleText);
SetViewLocation(RelativeLayout.CENTER_IN_PARENT,mTitle);
}
/**
* 设置控件的位置
* @param location
* @param view
*/
private void SetViewLocation(int location, View view) {
LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
layoutParams.addRule(location,TRUE);
addView(view,layoutParams);
}
/**
* 设置监听
* @param topbarClickListener
*/
public void setOnTopBarClickListener(TopbarClickListener topbarClickListener){
this.mListener = topbarClickListener;
}
/**
* 暴露对外接口
* @author suansuan
*
*/
public interface TopbarClickListener{
void leftClick();
void rightClick();
}
@Override
public void onClick(View view) {
if(view == mRightButton){
if(mListener != null){
mListener.leftClick();
}
}else if(view == mLeftButton){
if(mListener != null){
mListener.rightClick();
}
}
}
}
并且暴露相应的回调方法。
3、然后在我们自己的activity_main.xml布局文件当中去使用他,图片资源没有的自己配上,
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.suansuan.view.TopBar
android:id="@+id/tp"
android:layout_width="match_parent"
android:layout_height="40dip"
android:background="#333"
custom:leftBackground="@drawable/cs_channel_focus"
custom:leftText="Back"
custom:leftTextColor="#ddd"
custom:rightBackground="@drawable/cs_channel_focus"
custom:rightText="More"
custom:rightTextColor="#ddd"
custom:titleText="网易新闻"
custom:titleTextColor="#DDD"
custom:titleTextSize="10sp" />
</RelativeLayout>
4、像一般控件那样去使用它
package com.suansuan.customcombinationcontrol;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.Toast;
import com.suansuan.view.TopBar;
import com.suansuan.view.TopBar.TopbarClickListener;
/**
*
* @author liusuansuan
*
*/
public class MainActivity extends ActionBarActivity {
private TopBar mTopBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
mTopBar = (TopBar) findViewById(R.id.tp);
mTopBar.setOnTopBarClickListener(new TopbarClickListener() {
@Override
public void rightClick() {
Toast.makeText(getApplicationContext(), "右边被点击了", Toast.LENGTH_SHORT).show();
}
@Override
public void leftClick() {
Toast.makeText(getApplicationContext(), "左边被点击了", Toast.LENGTH_SHORT).show();
}
});
}
}
这就是效果,嘿嘿 虽然不是很美观 但是还不错
自定义View_2_关于自定义组合View的更多相关文章
- android自定义view之---组合view
最近工作比较轻松,没有什么事情干,于是进入高产模式(呃....高产似xx). 应该很多童鞋对自定义view这个东西比较抵触,可能是听网上说view比较难吧,其实自定义view并没有很难 自定义view ...
- Android 自定义View修炼-【2014年最后的分享啦】Android实现自定义刮刮卡效果View
一.简介: 今天是2014年最后一天啦,首先在这里,我祝福大家在新的2015年都一个个的新健康,新收入,新顺利,新如意!!! 上一偏,我介绍了用Xfermode实现自定义圆角和椭圆图片view的博文& ...
- asp.net MVC 自定义@helper 和自定义函数@functions小结
asp.net Razor 视图具有.cshtml后缀,可以轻松的实现c#代码和html标签的切换,大大提升了我们的开发效率.但是Razor语法还是有一些棉花糖值得我们了解一下,可以更加强劲的提升我们 ...
- activiti自定义流程之自定义表单(三):表单列表及预览和删除
注:(1)环境配置:activiti自定义流程之自定义表单(一):环境配置 (2)创建表单:activiti自定义流程之自定义表单(二):创建表单 自定义表单创建成功,要拿到activiti中使用,自 ...
- activiti自定义流程之自定义表单(二):创建表单
注:环境配置:activiti自定义流程之自定义表单(一):环境配置 在上一节自定义表单环境搭建好以后,我就正式开始尝试自己创建表单,在后台的处理就比较常规,主要是针对ueditor插件的功能在前端进 ...
- MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器
实现MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器 MVC开发中几种以AOP方式实现的Filters是非常好用的,默认情况下,我们通过A ...
- C#自定义按钮、自定义WinForm无边框窗体、自定义MessageBox窗体
C#自定义按钮.自定义WinForm无边框窗体.自定义MessageBox窗体 C#自定义Button按钮控件 效果展示 C#自定义Winform无边框窗体 效果展示 C#自定义无边框MessageB ...
- 在ASP.NET MVC中使用Knockout实践02,组合View Model成员、Select绑定、通过构造器创建View Model,扩展View Model方法
本篇体验使用ko.computed(fn)计算.组合View Model成员.Select元素的绑定.使用构造器创建View Model.通过View Model的原型(Prototype)为View ...
- 『NiFi 学习之路』自定义 —— 组件的自定义及使用
一.概述 许多业务仅仅使用官方提供的组件不能够满足性能上的需求,往往要通过高度可定制的组件来完成特定的业务需求. 而 NiFi 提供了自定义组件的这种方式. 二.自定义 Processor 占坑待续 ...
随机推荐
- MailMessage to EML
EML格式是微软公司在Outlook中所使用的一种遵循RFC822及其后续扩展的文件格式,并成为各类电子邮件软件的通用格式. 做个笔记,C# 邮件处理保存为eml格式: 一.网上好多这样的写法,可以在 ...
- 完成端口(Completion Port)详解(转)
手把手叫你玩转网络编程系列之三 完成端口(Completion Port)详解 ...
- PHP 常见语法 集合
1.die()与exit()的真正区别 die 为 exit 的别名, 执行过程 将释放内存,停止代码执行 echo "begin exec <br/>"; show( ...
- tengine + mysql + nginx + php
tengine + mysql + nginx + php 1.配置防火墙vim /etc/sysconfig/iptables # 允许80端口通过防火墙-A INPUT -m state --st ...
- python watchdog
监视文件变更 #!/usr/bin/python # -*- coding:UTF-8 -*- import time from watchdog.observers import Observer ...
- 理解RxJava:(三)RxJava的优点
理解RxJava:(三)RxJava的优点 在第一部分,讲解了RxJava的基本结构.在第二部分,展示了operators的强大之处.但是你们可能仍然没有被说服,也没有足够的理由信服.下面是一些能让你 ...
- 安卓开发笔记——关于照片墙的实现(完美缓存策略LruCache+DiskLruCache)
这几天一直研究在安卓开发中图片应该如何处理,在网上翻了好多资料,这里做点小总结,如果朋友们有更好的解决方案,可以留言一起交流下. 内存缓存技术 在我们开发程序中要在界面上加载一张图片是件非常容易的事情 ...
- 另类angularjs应用
回顾 上一篇文章主要讲解了创建兼容任意浏览器(主要是ie的一些奇葩问题)的angularjs web应用,但是项目开发中其实更重要的还是在功能的模块化.代码自动压缩上面,这样项目在后期维护或者功能的重 ...
- [转]Android dex分包方案
转载自:https://m.oschina.net/blog/308583 当一个app的功能越来越复杂,代码量越来越多,也许有一天便会突然遇到下列现象: 1. 生成的apk在2.3以前的机器无法安装 ...
- React Native Android增加本地图片
将图片文件 UePbdph.png 放入与index.android.js的同目录中,在index.android.js中引入: <Image source={require('./UePbdp ...