目的:设计一个自定义的UI控件,类似Button一样的Android控件。如本案例要设计一个如下的控件:
左边蓝色和右边蓝色部分为两个Button,中间是一个TextView,我们的目的就是要设计出一个这样的控件
第一步:设计控件的各种属性
在values目录下新建一个xml文件,名为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 = "rightText" format="string"/>
<attr name = "rightBackground" format="reference|color"/>
<attr name = "rightTextColor" format="color"/>
</declare-styleable>
</resources>
第二步:编写自定义View:
public class TopBar extends RelativeLayout{
private Button leftButton,rightButton;
private TextView tvTitle;
private String titleText;
private int titleTextColor;
private float titleTextSize;
private String leftText;
private int leftTextColor;
private Drawable leftBackground;
private String rightText;
private int rightTextColor;
private Drawable rightBackground;
private LayoutParams leftParams,rightParams,titleParams;
private TopBarClickListener listener;
// 自定义TopBar控件的接口
public interface TopBarClickListener{
public void leftClick();
public void rightClick();
}
// 暴露一个方法给调用者
public void setOnTopBarClickListener(TopBarClickListener listener){
this.listener = listener;
}
public TopBar(final Context context, AttributeSet attrs) {
super(context, attrs);
setBackgroundColor(0xFFF59563);
TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.topBar);
titleText = ta.getString(R.styleable.topBar_titleText);
titleTextColor = ta.getColor(R.styleable.topBar_titleTextColor,0);
titleTextSize = ta.getDimension(R.styleable.topBar_titleTextSize,0);
leftText = ta.getString(R.styleable.topBar_leftText);
leftTextColor = ta.getColor(R.styleable.topBar_leftTextColor,0);
leftBackground = ta.getDrawable(R.styleable.topBar_leftBackground);
rightText = ta.getString(R.styleable.topBar_rightText);
rightTextColor = ta.getColor(R.styleable.topBar_rightTextColor,0);
rightBackground = ta.getDrawable(R.styleable.topBar_rightBackground);
// 类型数组资源的回收
ta.recycle();
leftButton = new Button(context);
rightButton = new Button(context);
tvTitle = new TextView(context);
tvTitle.setText(titleText);
tvTitle.setTextColor(titleTextColor);
tvTitle.setTextSize(titleTextSize);
tvTitle.setGravity(Gravity.CENTER);
leftButton.setText(leftText);
leftButton.setTextColor(leftTextColor);
leftButton.setBackground(leftBackground);
rightButton.setText(rightText);
rightButton.setTextColor(rightTextColor);
rightButton.setBackground(rightBackground);
// 设置标题的布局参数之宽和高
titleParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
// 设置标题布局参数之对齐方式
titleParams.addRule(RelativeLayout.CENTER_IN_PARENT,TRUE);
// 将TextView tvTitle以布局参数titleParams加入到View中
addView(tvTitle,titleParams);
leftParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
addView(leftButton,leftParams);
rightParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
rightParams.addRule(ALIGN_PARENT_RIGHT);
addView(rightButton,rightParams);
leftButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
listener.leftClick();
}
});
rightButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
listener.rightClick();
}
});
}
}
编写自定义View的时候自定义了控件的一个接口,并将此接口暴露给了调用者使用
第三步:编写Activity代码,显示该控件并实现接口中的方法:
public class MainActivity extends AppCompatActivity{
private TopBar topBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
topBar = (TopBar) findViewById(R.id.topBar);
topBar.setOnTopBarClickListener(new TopBar.TopBarClickListener() {
// 实现接口TopBarClickListener中的方法
@Override
public void leftClick() {
Toast.makeText(MainActivity.this, "点击了Back", Toast.LENGTH_SHORT).show();
}
@Override
public void rightClick() {
Toast.makeText(MainActivity.this, "点击了More", Toast.LENGTH_SHORT).show();
}
});
}
}
其中activity_main.xml为:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.mytopbar.MainActivity">
<com.example.mytopbar.TopBar
android:layout_width="match_parent"
android:layout_height="40dp"
android:id="@+id/topBar"
custom:leftText="Back"
custom:leftTextColor="@color/white"
custom:leftBackground="@drawable/blue_button"
custom:titleText="来玩玩吧"
custom:titleTextSize="15sp"
custom:titleTextColor="@color/white"
custom:rightText="More"
custom:rightTextColor="@color/white"
custom:rightBackground="@drawable/blue_button"
/>
</RelativeLayout>
注意:自定义的控件使用时候要声明它的命名空间,如上面的:
xmlns:custom="http://schemas.android.com/apk/res-auto"
运行效果: