版权声明:本文为博主原创文章,欢迎转载,转载请注明出处。 https://blog.csdn.net/qq_18945757/article/details/86547269
GitHub代码地址:GitHub
- 第一步,为这个View提供可自定义的属性:在res目录下的values目录下创建attrs.xml,并通过代码定义属性。以下是attrs.xml:
<?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="titleBackground" 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="TopBar"表示此自定义属性的名字
- 第二步,创建一个自定义控件,并让它继承ViewGroup,然后添加设置子View。例如,创建TopBar继承RelativeLayout。方法如下的注释中。以下是TopBar.java:
public class TopBar extends RelativeLayout {
private int mLeftTextColor;
private int mRightTextColor;
private int mTitleTextColor;
private int mTitleBackground;
private float mTitleTextSize;
private Button mLeftButton;
private Button mRightButton;
private TextView mTitleView;
private RelativeLayout.LayoutParams mLeftParams,mRightParams,mTitleParams;
topbarClickListener mListener;
private Drawable mLeftBackground;
private Drawable mRightBackground;
private String mLeftText;
private String mRightText;
private String mTitle;
public TopBar(Context context) { super(context);}
public TopBar(Context context, AttributeSet attrs,int defStyle) { super(context,attrs,defStyle);}
public TopBar(Context context, AttributeSet attrs) {
super(context,attrs);
//将在attrs.xml中定义的declare-styleable的所有属性的值存储到TypedArray中,“值”在引用本布局的xml文件中会定义
TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.TopBar);
//从TypedArray中取出对应的值
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);
mTitle = ta.getString(R.styleable.TopBar_title);
mTitleBackground = ta.getColor(R.styleable.TopBar_titleBackground,0);
ta.recycle();//获取完数据要调用recyle方法完成资源的回收
mLeftButton = new Button(context);
mRightButton = new Button(context);
mTitleView = new TextView(context);
mLeftButton.setTextColor(mLeftTextColor);
mLeftButton.setBackground(mLeftBackground);
mLeftButton.setText(mLeftText);
mLeftButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mListener.leftClick();//回调的接口在这里实现
}
});
mRightButton.setTextColor(mRightTextColor);
mRightButton.setBackground(mRightBackground);
mRightButton.setText(mRightText);
mRightButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mListener.rightClick();//回调的接口字这里实现
}
});
mTitleView.setText(mTitle);
mTitleView.setTextColor(mTitleTextColor);
mTitleView.setTextSize(mTitleTextSize);
mTitleView.setGravity(Gravity.CENTER);
mTitleView.setBackgroundColor(mTitleBackground);
//设置相应的布局元素
mLeftParams = new LayoutParams(200,LayoutParams.MATCH_PARENT);
mLeftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT,TRUE);
//添加到RelativeLayout中
addView(mLeftButton,mLeftParams);
mRightParams = new LayoutParams(200,LayoutParams.MATCH_PARENT);
mRightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,TRUE);
addView(mRightButton,mRightParams);
mTitleParams = new LayoutParams(600,LayoutParams.MATCH_PARENT);
mTitleParams.addRule(RelativeLayout.CENTER_IN_PARENT,TRUE);
addView(mTitleView,mTitleParams);
}
//暴露接口给调用者
public interface topbarClickListener{
void leftClick();
void rightClick();
}
//暴露一个方法给调用者来注册接口回调
public void setOnTopbarClickListener(topbarClickListener mListener){
this.mListener = mListener;//实现接口回调
}
/*设置按钮的显示与否,通过id区分按钮,flag区分是否显示
@param id id
@param flag 是否显示
*/
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);
}
}
}
}
- 第三步,创建布局文件,并引用UI模版。在布局文件中,要定义attrs.xml中自定义属性的值。
例如,创建topbar.xml:
<?xml version="1.0" encoding="utf-8"?>
<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="60dp"
custom:leftBackground="@drawable/button_back"
custom:leftText=""
custom:leftTextColor="#FFFFFF"
custom:title="自定义标题"
custom:titleTextColor="#123412"
custom:titleTextSize="12sp"
custom:titleBackground="@color/colorTitle_background"
custom:rightBackground="@drawable/button_more"
custom:rightText=""
custom:rightTextColor="#FFFFFF">
</com.example.topbar.TopBar>
- 第四步,在Activity布局文件中引用topbar布局:例如,activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<include layout="@layout/topbar"/>
</android.support.constraint.ConstraintLayout>
直接放入<include layout="@layout/topbar"/>
即可。
- 第五步,在MainActivity.java中获取布局中组件的id,获得实例后进行相关的设置。比如,传入回调接口。代码如下:
public class MainActivity extends AppCompatActivity {
TopBar mTopbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null){
actionBar.hide();//隐藏标题栏
}
mTopbar = (TopBar) findViewById(R.id.topBar);//获取TopBar实例
//使用匿名内部类的形式来实现接口中的方法
mTopbar.setOnTopbarClickListener(new TopBar.topbarClickListener() {
@Override
public void leftClick() {
Toast.makeText(MainActivity.this,"left",Toast.LENGTH_SHORT).show();
}
@Override
public void rightClick() {
Toast.makeText(MainActivity.this,"right",Toast.LENGTH_SHORT).show();
}
});
mTopbar.setButtonVisable(0,true);//设置左右按钮是否可见
mTopbar.setButtonVisable(0,true);
}
}
- 效果如图: