首页 > 系统 > Android > 正文

【笔记】第三章Android控件架构与自定义控件详解(2)

2019-11-07 23:36:21
字体:
来源:转载
供稿:网友

详见《Android群英传》

3.6.2创建复合控件(本质是在讲如何自定义属性)

复合控件实质上是一个ViewGroup,通过自定义ViewGroup的子类来实现

其中关于自定义属性:

先在values下创建attrs资源文件,然后在styleable中声明自定义变量,变量名不应该与已有的重名

自定义类,并通过TypedArray类来获取自定义的属性值,赋给控件

在布局文件中指定命名空间,然后引入自定义控件,在其中通过命名空间来指定属性

此过程的本质是重写了传入属性的构造函数

代码如下

    //在此构造函数中声明属性    public MyTopBar(Context context, AttributeSet attrs) {        //super中会将原生的属性从布局中获取,然后进行赋值        super(context, attrs);        setBackgroundColor(0xFFF59563);//设置topbar的属性        /*有个问题不太明白,如何将布局中赋的值映射到attrs.xml上自定义的属性上的*/        //将attrs中的自定义属性由布局中存储到TypedArray对象中,然后从该对象中获取值        TypedArray ta=context.obtainStyledAttributes(attrs,R.styleable.MyTopBar);//获取attrs.xml中的MyTopBar的自定义属性        mLeftTextColor=ta.getColor(R.styleable.MyTopBar_leftTextColor, 0);//第二个参数为缺省值        mLeftBackground=ta.getDrawable(R.styleable.MyTopBar_leftBackground);        mLeftText=ta.getString(R.styleable.MyTopBar_leftText);        mRightTextColor=ta.getColor(R.styleable.MyTopBar_rightTextColor, 0);        mRightBackground=ta.getDrawable(R.styleable.MyTopBar_rightBackground);        mRightText=ta.getString(R.styleable.MyTopBar_rightText);        mTitleTextColor=ta.getColor(R.styleable.MyTopBar_mtitleTextColor, 0);        mTitleTextSize=ta.getDimension(R.styleable.MyTopBar_mtitleTextSize, 10);        mTitle=ta.getString(R.styleable.MyTopBar_mtitle);        ta.recycle();//获取完TypedArray的值后,要调用recycle方法,回收        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(mTitle);        mTitleView.setTextColor(mTitleTextColor);        mTitleView.setTextSize(mTitleTextSize);        mTitleView.setGravity(Gravity.CENTER);组合控件是由两个button和一个textview组成的,上面的过程对于已有的属性,是已经封装过的了。

接着是对button,textview的位置信息实现,并将其添加打GroupView中

//为组件元素设置相应的布局元素        /*ViewGroup.LayoutParams和LayoutParams的区别是,后者是前者的子类*/        mLeftParams=new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);        mLeftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT,TRUE);//设置在相对布局左边        addView(mLeftButton, mLeftParams);//将Button以mLeftParams的方式添加到RelativeLayout中        mRightParams=new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);        mRightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,TRUE);//设置在相对布局右边        addView(mRightButton, mRightParams);        mTitleParams=new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);        mTitleParams.addRule(RelativeLayout.CENTER_IN_PARENT,TRUE);        addView(mTitleView, mTitleParams);

上面的过程具体如下

1.在attrs.xml声明属性

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="MyTopBar">        <attr name="mtitle" format="string"/>        <attr name="mtitleTextSize" format="dimension"/>        <attr name="mtitleTextColor" 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>2.自定义GroupView类,RelativeLayout类继承GroupView

public class MyTopBar extends RelativeLayout {    PRivate Button mLeftButton,mRightButton;//topbar的左按钮和右按钮    private TextView mTitleView;//topbar的标题    private LayoutParams mLeftParams,mTitleParams,mRightParams;//布局属性    //在attrs.xml中的各属性定义    private int mLeftTextColor;    private Drawable mLeftBackground;//背景图片    private String mLeftText;    private int mRightTextColor;    private Drawable mRightBackground;    private String mRightText;    private float mTitleTextSize;    private int mTitleTextColor;    private String mTitle;    public MyTopBar(Context context) {        super(context);    }    //在此构造函数中声明属性    public MyTopBar(Context context, AttributeSet attrs) {        //super中会将原生的属性从布局中获取,然后进行赋值        super(context, attrs);        setBackgroundColor(0xFFF59563);//设置topbar的属性        /*有个问题不太明白,如何将布局中赋的值映射到attrs.xml上自定义的属性上的*/        //将attrs中的自定义属性由布局中存储到TypedArray对象中,然后从该对象中获取值        TypedArray ta=context.obtainStyledAttributes(attrs,R.styleable.MyTopBar);//获取attrs.xml中的MyTopBar的自定义属性        mLeftTextColor=ta.getColor(R.styleable.MyTopBar_leftTextColor, 0);//第二个参数为缺省值        mLeftBackground=ta.getDrawable(R.styleable.MyTopBar_leftBackground);        mLeftText=ta.getString(R.styleable.MyTopBar_leftText);        mRightTextColor=ta.getColor(R.styleable.MyTopBar_rightTextColor, 0);        mRightBackground=ta.getDrawable(R.styleable.MyTopBar_rightBackground);        mRightText=ta.getString(R.styleable.MyTopBar_rightText);        mTitleTextColor=ta.getColor(R.styleable.MyTopBar_mtitleTextColor, 0);        mTitleTextSize=ta.getDimension(R.styleable.MyTopBar_mtitleTextSize, 10);        mTitle=ta.getString(R.styleable.MyTopBar_mtitle);        ta.recycle();//获取完TypedArray的值后,要调用recycle方法,回收        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(mTitle);        mTitleView.setTextColor(mTitleTextColor);        mTitleView.setTextSize(mTitleTextSize);        mTitleView.setGravity(Gravity.CENTER);        //为组件元素设置相应的布局元素        /*ViewGroup.LayoutParams和LayoutParams的区别是,后者是前者的子类*/        mLeftParams=new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);        mLeftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT,TRUE);//设置在相对布局左边        addView(mLeftButton, mLeftParams);//将Button以mLeftParams的方式添加到RelativeLayout中        mRightParams=new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);        mRightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,TRUE);//设置在相对布局右边        addView(mRightButton, mRightParams);        mTitleParams=new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);        mTitleParams.addRule(RelativeLayout.CENTER_IN_PARENT,TRUE);        addView(mTitleView, mTitleParams);        mRightButton.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                //此处调用一个接口函数,调用者自己实现其方法            }        });        mLeftButton.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                //同上            }        });    }}3.布局中添加控件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    xmlns:topbar="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:layout_height="match_parent"    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="com.example.administrator.test301.MainActivity">    <com.example.administrator.test301.MyTopBar        android:layout_below="@+id/mytextview"        android:layout_width="match_parent"        android:layout_height="60dp"        topbar:leftBackground="#903234"        topbar:leftText="Back"        topbar:leftTextColor="#FFFFFF"        topbar:rightBackground="#903234"        topbar:rightText="MORE"        topbar:rightTextColor="#FFFFFF"        topbar:mtitle="自定义amazing"        topbar:mtitleTextColor="#f40fff"        topbar:mtitleTextSize="10sp"/></RelativeLayout>


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表