自定义复合控件并进行封装
来源:互联网 发布:mac打不开文件夹 编辑:程序博客网 时间:2024/05/22 09:50
首先这个控件的布局很简单(中间为标题文字,左右各有一个按钮)
但是这个类似的布局很常用,所以就想把它封装起来,通过这个封装来学习以下三点
1.创建了一个常用的复合控件,标题栏
2.为该控件添加自定义的属性值
3.为该控件添加自定义的接口
首先我们要先想好该控件的自定义属性
在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="reference|color"/> <attr name="leftText" format="string"/> <attr name="rightTextColor" format="color"/> <attr name="rightBackground" format="reference|color"/> <attr name="rightText" format="string"/> </declare-styleable></resources>我们在<declare-styleable name="自定义控件名">中声明是哪个控件的自定义属性,这里我命名为TopBar
<attr name="属性名" format="属性格式">
format可以有以下属性
1.reference: 某一资源的id
2.color : 颜色值
3.boolean: 布尔值
4.dimension: 尺寸值
5.float: 浮点值
6.integer:整形值
7.sting: 字符串
8.fraction: 百分数
9.enum:枚举值
10.flag:位或运算
至于我定义的属性用途,从名字就可以直接的看出来,不再赘述
然后就是关键的TopBar这个类的代码了,我们用TopBar继承RelativeLayout
package com.example.topbar;import android.content.Context;import android.content.res.TypedArray;import android.graphics.drawable.Drawable;import android.text.Layout;import android.util.AttributeSet;import android.util.Log;import android.view.Gravity;import android.view.LayoutInflater;import android.view.View;import android.widget.Button;import android.widget.RelativeLayout;import android.widget.TextView;import android.widget.RelativeLayout.LayoutParams;import android.view.View.OnClickListener;public class TopBar extends RelativeLayout implements OnClickListener{//定义与attrs.xml中的自定义属性对应的属性private int mLeftTextColor;private Drawable mLeftBackground;private String mLeftText;private int mRightTextColor;private Drawable mRightBackground;private String mRightText;private String mTitleText;private int mTitleTextColor;private float mTitleTextSize;/* * 定义我们要显示的布局 * 一个显示标题的TextView 两个分居两侧的标题 */private Button mLeftButton;private Button mRightButton;private TextView mTitleView;//用于控制控件的布局属性private LayoutParams mLeftParams;private LayoutParams mRightParams;private LayoutParams mTitleParams;//我们给button赋予一个id,便于在事件监听时候对应到相应buttonprivate final int mLeftButtonId = 1;private final int mRightButtonId = 2;//下面我们在这个类中定义的一个公共接口private OnTopBarClickListener onTopBarClickListener;//构造函数,attrs就是布局文件传过来的对应的属性public TopBar(Context context, AttributeSet attrs) {super(context, attrs);initAttrs(context,attrs);initView(context);}//将attrs.xml中定义的属性值存入typedArray中private void initAttrs(Context context, AttributeSet attrs){TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.TopBar);mLeftTextColor = ta.getColor(R.styleable.TopBar_leftTextColor,0);mLeftBackground = ta.getDrawable(R.styleable.TopBar_leftBackground);mLeftText = ta.getString(R.styleable.TopBar_leftText);mRightTextColor = ta.getColor(R.styleable.TopBar_rightTextColor,0);mRightBackground = ta.getDrawable(R.styleable.TopBar_rightBackground);mRightText = ta.getString(R.styleable.TopBar_rightText);mTitleTextSize = ta.getDimension(R.styleable.TopBar_titleTextSize, 10);mTitleTextColor =ta.getColor(R.styleable.TopBar_titleTextColor, 0);mTitleText = ta.getString(R.styleable.TopBar_titleText);ta.recycle();}//初始化布局中的控件,并将属性分配给他们,以及给他们注册监听事件private void initView(Context context){mLeftButton = new Button(context);mRightButton = new Button(context);mTitleView = new TextView(context);mLeftButton.setTextColor(mLeftTextColor);mLeftButton.setBackground(mLeftBackground);mLeftButton.setText(mLeftText);mRightButton.setTextColor(mRightTextColor);mRightButton.setBackground(mRightBackground);mRightButton.setText(mRightText);mTitleView.setText(mTitleText);mTitleView.setTextColor(mTitleTextColor);mTitleView.setTextSize(mTitleTextSize);mTitleView.setGravity(Gravity.CENTER);mLeftButton.setId(mLeftButtonId);mLeftParams = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);mLeftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT,TRUE);mLeftParams.addRule(RelativeLayout.CENTER_VERTICAL);addView(mLeftButton,mLeftParams);mRightButton.setId(mRightButtonId);mRightParams = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);mRightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,TRUE);mRightParams.addRule(RelativeLayout.CENTER_VERTICAL,TRUE);addView(mRightButton,mRightParams);mTitleParams = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);mTitleParams.addRule(RelativeLayout.CENTER_IN_PARENT,TRUE);addView(mTitleView,mTitleParams);mLeftButton.setOnClickListener(this);mRightButton.setOnClickListener(this);}/** * * @param id id=0标识leftButton else 标识着rightButton * @param flag flag = 0 意味着不显示该id控件 * button默认为显示 */public void setButtonVisable(int id, boolean flag){if(flag){if(id == 0){mLeftButton.setVisibility(View.VISIBLE);}else{mRightButton.setVisibility(View.VISIBLE);}}else{if(id == 0){mLeftButton.setVisibility(View.GONE);}else{mRightButton.setVisibility(View.GONE);}}}//重写借口的onclick方法,去调用自定义的接口的方法@Overridepublic void onClick(View v) {switch(v.getId()){case mLeftButtonId:onTopBarClickListener.leftClick();break;case mRightButtonId:onTopBarClickListener.rightClick();break;}}//为外部增加一个方法去添加接口的监听事件public void setOnTopBarClickListener(OnTopBarClickListener onTopBarClickListener){this.onTopBarClickListener = onTopBarClickListener;}//自定义一个接口,供使用者为两个button添加事件public interface OnTopBarClickListener{void leftClick();void rightClick();}}
然后就是我们定义一个布局,去引用这个自定义控件
activity_topbar_test.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context="com.example.topbar.TopBarTest" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <com.example.topbar.TopBar xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.com/apk/res-auto" android:id="@+id/topBar" android:layout_width="match_parent" android:layout_height="80dp" android:background="#ffccff" custom:leftText="Back" custom:leftTextColor="#000000" custom:leftBackground="#ff0000" custom:rightText="More" custom:rightTextColor="#000000" custom:rightBackground="#ff0000" custom:titleText="自定义标题" custom:titleTextColor="#123412" custom:titleTextSize="12sp" /></LinearLayout>
这个地方我们要注意一下,
xmlns:android="http://schemas.android.com/apk/res/android"
是声明android的命名空间,这样我们就可以通过android:来引用其中的属性了
xmlns:custom="http://schemas.android.com/apk/res-auto"
是我们为自定义的属性声明的命名空间,名字为custom
自定义属性的位置是 http://schemas.android.com/apk/res-auto
我们也可以写为 http://schema.android.com/apk/res/包路径
包路径指的是你在Manifest中定义的项目的包路径,而不是说TopBar这个类的包路径
总之就是为了找到我们这个项目,然后正确的识别values 的 attrs.xml
最后就是写一个activity去引用这个布局,然后测试我们是否成功啦
TopBarTestActivity.java
package com.example.topbar;import custom.TopBar;import custom.TopBar.OnTopBarClickListener;import android.support.v7.app.ActionBarActivity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.Window;import android.widget.Toast;public class TopBarTestActivity extends ActionBarActivity {TopBar topBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //去掉系统标题栏 this.requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_topbar_test); topBar = (TopBar)findViewById(R.id.topBar); //为topBar中的按钮注册监听事件 topBar.setOnTopBarClickListener(new OnTopBarClickListener(){@Overridepublic void leftClick() {Toast.makeText(TopBarTestActivity.this, "点击了leftButton", Toast.LENGTH_SHORT).show();}@Overridepublic void rightClick() {Toast.makeText(TopBarTestActivity.this, "点击了rightButton", Toast.LENGTH_SHORT).show();} }); /* * 可以用setButtonVisable(id,flag)来控制是否显示相应按钮 * 添加以下代码,两个按钮都被隐藏了 * topBar.setButtonVisable(0, false); * topBar.setButtonVisable(1, false); */ }}
好啦,运行可以看到我开始时候放的图片了!
注释都很详尽,我就不再解释了,有问题可以留言讨论~
这只是一个简单的复合控件,但是我们可以通过这个学习到如何自定义一个复合控件,与为他定制属性和一些接口,方法。
由简单到复杂,下一次,我们可以自定义一个SlidingMenu 然后把自定义属性也定制到里面~
github地址 Wizwizard/TopBar
- 自定义复合控件并进行封装
- android 自定义复合控件
- android自定义复合控件
- Android 自定义复合控件
- 自定义复合控件
- 自定义控件 创建复合控件
- 自定义控件(17)---布局方式组合系统控件,并封装自定义控件思想(自定义CheckBox)
- 【Android】创建自定义复合控件
- 自定义 ActionBar ,创建复合控件
- Android创建自定义复合控件
- 扩展控件 复合控件 自定义控件
- 自定义控件(16)---代码方式组合系统控件,并封装自定义控件思想
- 自定义控件(二)--复合控件
- 自定义控件二(创建复合控件)
- 自定义控件之复合控件详解
- 《C#中自定义控件并在Form中进行调用》
- 自定义个性化的web复合控件
- 用户名密码检测的自定义复合控件
- lucene建立索引时候的用到的一些文档和目录操作
- 公司100个用户桌面虚拟化该怎么做?
- TwoSum问题
- struct 大小计算
- hdu1856 More is better--并查集
- 自定义复合控件并进行封装
- Android 库依赖
- iOS中的URL处理中文乱码
- opengl载入多个3ds模型失败记
- JavaScript获取DOM元素位置和尺寸大小
- 比较lucene各种英文分析器Analyzer
- 自定义代码块在Xcode中的路径(方便下次换电脑时使用~)
- va_list 原理以及用法
- SQL数据修复,SQL数据库修复,SQL数据库修复软件,SQL数据库恢复,SQL数据库日志恢复软件