自定义组合控件一

原创 2015年07月08日 01:55:39

最近在做一个项目,用到了自定义组合控件。一直来对自定义一组合控件都是有点映像,但是亲手做的时候发现有个地方卡主了。百度了很多资料才将问题给解决,就将它记下。


先上个效果图:



自定义组合控件首先当然少不了一个布局,它就是将一个自定义的布局通过LayoutInflater变成一个View加载的。


自定义布局代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="15dp" >

    <ImageView
        android:id="@+id/firstpage_icon"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_centerVertical="true"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"/>

    <TextView
        android:id="@+id/firstpage_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/firstpage_icon"
        android:textSize="20sp" />


    <TextView
        android:id="@+id/firstpage_desc"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/firstpage_title"
        android:layout_toRightOf="@+id/firstpage_icon"
        android:textColor="#777777" />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="15dp"
        android:src="@drawable/clicktogo" />    //这里有设置值,因为该组合控件的这个值都是一个箭头

</RelativeLayout>


接着自定义一个类(FirstPageCustomView),一般继承自RelativeLayout或者LinearLayout。这里继承自RelativeLayout。该类中首先要做的就是实现父类构造函数,父类有三个构造函数,对于有自定义布局加载方式的应该实现两个参数或者三个参数的构造。这里拿两个参数的构造函数作为例子。


下面上FirstPageCustomView的代码:

public class FirstPageCustomView extends RelativeLayout {
private ImageView firstpage_icon;
private TextView firstpage_title;
private TextView firstpage_desc;


// 加载布局文件
private void initView(Context context) {
View.inflate(context, R.layout.customview_firstpage, this);


firstpage_icon = (ImageView) this.findViewById(R.id.firstpage_icon);
firstpage_title = (TextView) this.findViewById(R.id.firstpage_title);
firstpage_desc = (TextView) this.findViewById(R.id.firstpage_desc);
}

public FirstPageCustomView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView(context);
}

//这是两个参数的构造函数
public FirstPageCustomView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);

}

}


上面的代码就已经将自定义的布局加载进自定义的类中。关键代码是:View.inflate(context, R.layout.customview_firstpage, this);

接下来就可以在Activity中使用该控件了。

如在界面的布局文件中如下:

    <com.example.qzz.customview.FirstPageCustomView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:background="#ffffff">
    </com.example.qzz.customview.FirstPageCustomView>


但是上面这样做了还不够,因为自定义组合控件的每个子控件没有设置值,要在FirstPageCustomView类中对每个子控件进行设置:

public class FirstPageCustomView extends RelativeLayout {
private ImageView firstpage_icon;
private TextView firstpage_title;
private TextView firstpage_desc;


// 加载布局文件
private void initView(Context context) {
View.inflate(context, R.layout.customview_firstpage, this);
firstpage_icon = (ImageView) this.findViewById(R.id.firstpage_icon);
firstpage_title = (TextView) this.findViewById(R.id.firstpage_title);
firstpage_desc = (TextView) this.findViewById(R.id.firstpage_desc);
}


public FirstPageCustomView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView(context);

}

public FirstPageCustomView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);

firstpage_icon.setImageResource(R.drawable.news_icon);
firstpage_title.setText("最新活动新闻");
firstpage_desc.setText("最新赞助活动一键浏览...");

}

}


这样做完,就可以很好的显示我们想要的效果了。但是还没有结束,以上我们会发现一个问题,那就是自定义控件的每个子控件都要在类中赋值,这个根本不能满足我们的要求。想下,如果我们的布局中要用到两个这个控件,那就实现不了了,不可能每用一次这个控件就要重新定义一个控件。

这个时候就要用到自定义控件属性了。

自定义属性的步骤为:在res/values下定义一个attrs.xml文件,在文件中自定义属性。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="FirstPageCustomView">
        <attr name="icon" format="reference" /> 
        <attr name="title" format="string" />
        <attr name="desc" format="string" />
    </declare-styleable>
</resources>


declare-styleable name="FirstPageCustomView"指定是哪一个自定义控件的自定义属性,这里表示给FirstPageCustomView这个自定义控件自定义属性。

format="reference"表示该属性的值引用一个资源id值。对于format的可以取值,网上一堆资料,而且很详细,这里就不说了。

每个attr标签表示一个自定义属性,name属性指定自定义属性名


这样就可以在布局文件中使用自定义属性了,但是自定义属性的前缀要自己定义,也就是要自定义一个命名空间。如:

    <RelativeLayout

 xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="50dp"
        android:background="#40a1ff"
        android:gravity="center_vertical" >


        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:gravity="center"
            android:text="自定义组合控件学习"
            android:textColor="#ffffff"
            android:textSize="22sp"
            android:textStyle="bold" />
    </RelativeLayout>

红色字体部分就是一个命名空间,它指定了属性前缀是android:,并且指定了属性的定义在android系统内部。要自己定义属性就要自己定义一个命名空间。说来其实很简单:

xmlns:firstpage(前缀)="http://schemas.android.com/apk/res/包名"。这样一写就可以直接在布局文件中使用自定义属性了。

    <com.example.qzz.customview.FirstPageCustomView
        firstpage:icon="@drawable/news_icon"
        firstpage:title="最新新闻"
        firstpage:desc="最新活动一键浏览..."
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:background="#ffffff">

   </com.example.qzz.customview.FirstPageCustomView>


之后就直接在FirstPageCustomView类构造函数中拿到属性值进行设置就行了。

public FirstPageCustomView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
/**
* 获得我们所定义的自定义样式属性
*/
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.FirstPageCustomView);
int n = a.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.FirstPageCustomView_icon:
int resource = a.getResourceId(i, 0);//对于属性值是一个资源id的,这里拿到资源id值再复制给子控件
firstpage_icon.setImageResource(resource);
break;
case R.styleable.FirstPageCustomView_title:
// 默认颜色设置为黑色
String title = a.getString(i);
firstpage_title.setText("最新新闻");
break;
case R.styleable.FirstPageCustomView_desc:
// 默认设置为16sp,TypeValue也可以把sp转化为px
String desc = a.getString(i);
firstpage_desc.setText("最新活动一键浏览...");
break;
}
}
}


自定义控件就说到这里,有什么地方有问题的,欢迎大家提出来,一起进步。

版权声明:本文为博主原创文章,未经博主允许不得转载。

自定义控件(一):组合控件的使用

一.组合控件的作用   对于view控件的理解,对于一个控件能够在应用中显示出来.需要java代码的实现,在布局文件中的xml格式的出现简化了布局.但布局文件中的属性,也是需要事先人为指定的.这里需...
  • dygcomed
  • dygcomed
  • 2016年08月22日 14:48
  • 196

Android自定义控件之自定义组合控件

Android自定义控件之自定义组合控件 前言:      前两篇介绍了自定义控件的基础原理Android自定义控件之基本原理(一)、自定义属性Android自定义控件之自定义属性(二)。今天...
  • duoluo9
  • duoluo9
  • 2017年01月17日 15:55
  • 216

Android自定义组合控件之自定义属性

自定义组合控件:就是将一大段定义样式的代码通过用一个java类的全路径作为标签名就能代替使用。(相当于封装代码)...
  • xuxiaocheng1
  • xuxiaocheng1
  • 2014年02月28日 17:00
  • 1059

自定义控件-组合控件

自定义控件当原生控件不能满足需要时,需要进行自定义控件,自定义控件可分为三种方式: 对现有控件进行拓展 通过现有控件的组合实现新的控件 完全自定义一个新的控件 组合控件的使用方式1、新建控件类首先控件...
  • u013632190
  • u013632190
  • 2016年06月10日 02:42
  • 659

Android自定义控件——自定义组合控件

前面几篇博文介绍了Android如何自定义控件,其实就是讲一下如何“从无到有”的自定义一个全新的控件,继承View或者继承ViewGroup,复写其相关方法,这种自定义控件的方式相对来说难度较大,而且...
  • lee_tianya
  • lee_tianya
  • 2014年09月26日 16:42
  • 2611

Android View体系(十)自定义组合控件

上一篇我们讲到了自定义View,接着我们来讲讲常用的自定义组合控件,自定义组合控件就是多个控件组合起来成为一个新的控件,主要用来解决多次重复的使用同一类型的布局。比如我们应用的顶部的标题栏,还有弹出的...
  • itachi85
  • itachi85
  • 2016年05月19日 17:10
  • 10503

自定义组合控件,自定义View,接口点击事件

 先写自定义组合控件的布局LoginView 继承自LinearLayout public class LoginViewextends LinearLayoutimplements Vi...
  • Developer_Sir
  • Developer_Sir
  • 2017年11月05日 20:11
  • 156

Android组合控件(无限轮播图)

android 自定义控件 是的,真的是自定义控件。 相对于自定义控件的控件是什么呢?当然是原生的控件啦! 比如说: 1、Button 、TextView 、ImageView...
  • TrillGates
  • TrillGates
  • 2016年12月27日 17:10
  • 300

Android进阶——自定义View之重写ViewGroup组合系统控件实现自定义ToolBar模板

利用重写ViewGroup组合系统控件实现,模板化自定义ToolBar
  • CrazyMo_
  • CrazyMo_
  • 2016年12月29日 15:54
  • 866

Android自定义控件View(三)组合控件

不少人应该见过小米手机系统音量控制UI,一个圆形带动画效果的音量加减UI,效果很好看。它是怎么实现的呢?这篇博客来揭开它的神秘面纱。先上效果图 相信很多人都知道Android自定义控件的三种方式,A...
  • feidu804677682
  • feidu804677682
  • 2015年05月30日 09:49
  • 6582
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:自定义组合控件一
举报原因:
原因补充:

(最多只允许输入30个字)