自定义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的更多相关文章

  1. android自定义view之---组合view

    最近工作比较轻松,没有什么事情干,于是进入高产模式(呃....高产似xx). 应该很多童鞋对自定义view这个东西比较抵触,可能是听网上说view比较难吧,其实自定义view并没有很难 自定义view ...

  2. Android 自定义View修炼-【2014年最后的分享啦】Android实现自定义刮刮卡效果View

    一.简介: 今天是2014年最后一天啦,首先在这里,我祝福大家在新的2015年都一个个的新健康,新收入,新顺利,新如意!!! 上一偏,我介绍了用Xfermode实现自定义圆角和椭圆图片view的博文& ...

  3. asp.net MVC 自定义@helper 和自定义函数@functions小结

    asp.net Razor 视图具有.cshtml后缀,可以轻松的实现c#代码和html标签的切换,大大提升了我们的开发效率.但是Razor语法还是有一些棉花糖值得我们了解一下,可以更加强劲的提升我们 ...

  4. activiti自定义流程之自定义表单(三):表单列表及预览和删除

    注:(1)环境配置:activiti自定义流程之自定义表单(一):环境配置 (2)创建表单:activiti自定义流程之自定义表单(二):创建表单 自定义表单创建成功,要拿到activiti中使用,自 ...

  5. activiti自定义流程之自定义表单(二):创建表单

    注:环境配置:activiti自定义流程之自定义表单(一):环境配置 在上一节自定义表单环境搭建好以后,我就正式开始尝试自己创建表单,在后台的处理就比较常规,主要是针对ueditor插件的功能在前端进 ...

  6. MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器

    实现MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器 MVC开发中几种以AOP方式实现的Filters是非常好用的,默认情况下,我们通过A ...

  7. C#自定义按钮、自定义WinForm无边框窗体、自定义MessageBox窗体

    C#自定义按钮.自定义WinForm无边框窗体.自定义MessageBox窗体 C#自定义Button按钮控件 效果展示 C#自定义Winform无边框窗体 效果展示 C#自定义无边框MessageB ...

  8. 在ASP.NET MVC中使用Knockout实践02,组合View Model成员、Select绑定、通过构造器创建View Model,扩展View Model方法

    本篇体验使用ko.computed(fn)计算.组合View Model成员.Select元素的绑定.使用构造器创建View Model.通过View Model的原型(Prototype)为View ...

  9. 『NiFi 学习之路』自定义 —— 组件的自定义及使用

    一.概述 许多业务仅仅使用官方提供的组件不能够满足性能上的需求,往往要通过高度可定制的组件来完成特定的业务需求. 而 NiFi 提供了自定义组件的这种方式. 二.自定义 Processor 占坑待续 ...

随机推荐

  1. 安装vim中文帮助vimcdoc

    1. 下载: 下载页面:http://vimcdoc.sourceforge.net/ 选择“Latest platform independent tarball, including an Lin ...

  2. SQL 操作结果集 -并集、差集、交集、结果集排序

    操作结果集 为了配合测试,特地建了两个表,并且添加了一些测试数据,其中重复记录为东吴的人物. 表:Person_1魏国人物 表:Person_2蜀国人物 A.Union形成并集 Union可以对两个或 ...

  3. android自定义view仿照MIUI中音量控制效果

    先看效果图: 这就是miui中的音量效果图,实现思路是自定义视图,绘制圆环,然后设置进度显示. 核心代码在onDraw中实现如下: @Override protected void onDraw(Ca ...

  4. [Tip] 如何在BeyondCompare中忽略不重要的区别.

    在使用BeyondCompare时,有时需要忽略一些不重要的区别,下面的链接教你如何通过定义语法元素来实现这个功能. http://www.scootersoftware.com/support.ph ...

  5. vs.net 2005 C# WinForm GroupBOX 的BUG?尝试读取或写入受保护的内存。这通常指示其他内存已损坏

    其实很久没有写程序了,国庆难得有空闲,写了个游戏辅助机器人,程序写好能用后本想把UI控件放到GroupBox里归下分类,美化下界面,结果一运行报“尝试读取或写入受保护的内存.这通常指示其他内存已损坏” ...

  6. 跟随标准与Webkit源码探究DOM -- 获取元素之querySelector,querySelectorAll

    使用CSS选择器获取元素 -- querySelector,querySelectorAll(HTML5) 标准 W3C Selector API Level 1为Document,DocumentF ...

  7. 终于找到全annotation配置springMVC的方法了(事务不失效)

    如果带上事务,那么用annotation方式的事务注解和bean配置,事务会失效,要将service bean配置到xml文件中才行 这个问题是由于问答上有解决方案 引用 这个问题很经典了 在主容器中 ...

  8. Android应用安全之Content Provider安全

    android平台提供了Content Provider,将一个应用程序的指定数据集提供给其它应用程序.这些数据可以存储在文件系统.SQLite数据库中,或以任何其它合理的方式存储.其他应用可以通过C ...

  9. bower的使用

    一.bower的安装 安装nodejs的最新版本: 安装npm. 由于npm是nodejs的包管理器,所以在将nodejs安装完成后,npm也就自动安装完成. 安装git. 安装bower. 使用 n ...

  10. 斐波那契堆(二)之 C++的实现

    概要 上一章介绍了斐波那契堆的基本概念,并通过C语言实现了斐波那契堆.本章是斐波那契堆的C++实现. 目录1. 斐波那契堆的介绍2. 斐波那契堆的基本操作3. 斐波那契堆的C++实现(完整源码)4.  ...