自定义控件之创建复合控件

方式:继承一个合适的ViewGroup,再添加指定功能的控件,需要拓展一些可以配置的属性,以达到更好的重用功能。

以一个自定义标题栏为例。
具体功能:标题栏分为三个部分,左按钮、右按钮、标题,按钮可以设置文字、文字颜色、背景,并且可以隐藏;标题可以设置文字、文字颜色、文字大小、背景。

步骤:

1.定义标题栏的属性,如标题颜色、大小等等,需要在res/values目录下创建一个attrs.xml文件,并通过如下代码定义相应的属性。


    
        
        
        
        
        
        
        
        
        
        
    

2.创建标题栏类TopBar,并继承一个ViewGroup,这里选择RelativeLayout。我们需要在其构造方法中获取自定义属性集,即attrs.xml里面定义的属性,这里用到了TypedArray,通过它的getString()、getColor()等方法获取属性值。

public class TopBar extends RelativeLayout{

    private String mLeftText;
    private int mLeftTextColor;
    private Drawable mLeftBackground;

    private String mRightText;
    private int mRightTextColor;
    private Drawable mRightBackground;

    private String mTitleText;
    private int mTitleTextColor;
    private float mTitleTextSize;
    private Drawable mTitleBackground;

    private Button mLeftButton;
    private Button mRightButton;
    private TextView mTitleView;

    private LayoutParams mLeftParams;
    private LayoutParams mRightParams;
    private LayoutParams mTitleParams;

    private TopBarClickListener mListener;


    public TopBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        //存储自定义的属性集
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.topBar);

        //取出TypedArray中的值
        mLeftText = ta.getString(R.styleable.topBar_leftText);
        mLeftTextColor = ta.getColor(R.styleable.topBar_leftTextColor, 0);
        mLeftBackground = ta.getDrawable(R.styleable.topBar_leftBackground);

        mRightText = ta.getString(R.styleable.topBar_rightText);
        mRightTextColor = ta.getColor(R.styleable.topBar_rightTextColor, 0);
        mRightBackground = ta.getDrawable(R.styleable.topBar_rightBackground);

        mTitleText = ta.getString(R.styleable.topBar_titleText);
        mTitleTextColor = ta.getColor(R.styleable.topBar_titleTextColor, 0);
        mTitleTextSize = ta.getDimension(R.styleable.topBar_titleTextSize, 10);
        mTitleBackground = ta.getDrawable(R.styleable.topBar_titleBackground);

        //回收资源
        ta.recycle();

        //为控件的属性赋值
        init(context);
    }

    private void init(Context context){

        mLeftButton = new Button(context);
        mRightButton = new Button(context);
        mTitleView = new TextView(context);

        mLeftButton.setText(mLeftText);
        mLeftButton.setTextColor(mLeftTextColor);
        mLeftButton.setBackground(mLeftBackground);

        mRightButton.setText(mRightText);
        mRightButton.setTextColor(mRightTextColor);
        mRightButton.setBackground(mRightBackground);

        mTitleView.setText(mTitleText);
        mTitleView.setTextColor(mTitleTextColor);
        mTitleView.setTextSize(mTitleTextSize);
        mTitleView.setBackground(mTitleBackground);
        mTitleView.setGravity(Gravity.CENTER);

        mLeftParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
        mLeftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE);
        addView(mLeftButton, mLeftParams);

        mRightParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
        mRightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, TRUE);
        addView(mRightButton, mRightParams);

        mTitleParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        mTitleParams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE);
        addView(mTitleView, mTitleParams);

        mLeftButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mListener.leftClick();
            }
        });
        mRightButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mListener.rightClick();
            }
        });
    }

    /**
    * 注册接口回调
    * @param listener 
    */
    public void setOnTopBarClickListener(TopBarClickListener listener){
        mListener = listener;
    }

    /**
    * 左右按钮点击事件的接口,发生点击事件时回调方法
    */
    public interface TopBarClickListener{
        void leftClick();
        void rightClick();
    }

    /**
    * 控制按钮是否显示
    * @param id 0:左,1:右
    * @param flag true:显示 false:隐藏
    */
    public void setButtonDisplay(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);
            }
        }
    }
}

3.引用自定义标题栏:需要指定第三方也就是我们自定义的命名空间,我定义的是 xmlns:topBar="http://schemas.android.com/apk/res-auto" ,当然,这里的topBar你可以替换成任意你想定义的名字,比如one、two、three都应该没什么问题。


注:左右按钮点击接口回调

mTopBar = (TopBar) findViewById(R.id.topBar);
mTopBar.setOnTopBarClickListener(new TopBar.TopBarClickListener() {
    @Override
    public void leftClick() {
            
    }

    @Override
    public void rightClick() {
            
    }
});
自定义控件之创建复合控件_第1张图片
效果

你可能感兴趣的:(自定义控件之创建复合控件)