首先,先回顾一下简单的自定义控件的实现流程
1
在res文件夹下的values目录下创建attrs文件,并在其中定义你自定义控件想要具备的属性
自定义属性类似如下
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TopBar">
<attr name="title" 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>
前面name表示自定义属性名,后面表示赋值的类型
2
在自定义控件中获取自已在xml中给该控件设置的属性,并重新在子控件中对其进行赋值
public class TopBar extends RelativeLayout {
private String mTitle;
private int mTitleTextColor;
private float mTitleTextSize;
private String mRightText;
private Drawable mRightBackground;
private int mRightTextColor;
private String mLeftText;
private Drawable mLeftBackground;
private int mLeftTextColor;
private Button mLeftBtn;
private Button mRightBtn;
private TextView mTitleView;
private LayoutParams mLeftParams;
private LayoutParams mRightParams;
private LayoutParams mTitleParams;
private topbarClickListener mListener;
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public TopBar(Context context) {
this(context, null);
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public TopBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public TopBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
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, 0);
mTitleTextColor = ta.getColor(R.styleable.TopBar_titleTextColor, 0);
mTitle = ta.getString(R.styleable.TopBar_title);
ta.recycle();
initView(context);
mRightBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mListener.rightClick();
}
});
mLeftBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mListener.leftClick();
}
});
}
public void setOnTopbarClickListener(topbarClickListener mListener) {
this.mListener = mListener;
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public TopBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
private void initView(Context context) {
mLeftBtn = new Button(context);
mRightBtn = new Button(context);
mTitleView = new TextView(context);
mLeftBtn.setTextColor(mLeftTextColor);
mLeftBtn.setBackground(mLeftBackground);
mLeftBtn.setText(mLeftText);
mRightBtn.setText(mRightText);
mRightBtn.setBackground(mRightBackground);
mRightBtn.setTextColor(mRightTextColor);
mTitleView.setText(mTitle);
mTitleView.setTextColor(mTitleTextColor);
mTitleView.setTextSize(mTitleTextSize);
mTitleView.setGravity(Gravity.CENTER);
mLeftParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
mLeftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE);
addView(mLeftBtn, mLeftParams);
mRightParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
mRightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
addView(mRightBtn, mRightParams);
mTitleParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
mTitleParams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE);
addView(mTitleView, mTitleParams);
}
public interface topbarClickListener {
void leftClick();
void rightClick();
}
}
在这其中,为自定义控件的左右两个控制设置 了点击事件.核心是先自定义一个自已的topbarClickListener的接口,在这个接口当中给左右两个控件定义点击事件.
然后在代码中给子控件设置点击事件,点用自定义接口中的方法.最后暴露一个方法给使用者来注册并实现接口回调
使用地方的代码如下
public class MainActivity extends AppCompatActivity {
TopBar mTopBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTopBar= (TopBar) findViewById(R.id.tb);
mTopBar.setOnTopbarClickListener(new TopBar.topbarClickListener(){
@Override
public void leftClick() {
Toast.makeText(MainActivity.this,"左边",Toast.LENGTH_SHORT).show();
}
@Override
public void rightClick() {
Toast.makeText(MainActivity.this,"右边",Toast.LENGTH_SHORT).show();
}
});
}
}
参考自安卓群英传
具体实现代码在上传的资源中