《Android群英传》-组合控件View案例-TopBar

版权声明:本文为博主原创文章,欢迎转载,转载请注明出处。 https://blog.csdn.net/qq_18945757/article/details/86547269

GitHub代码地址:GitHub

  1. 第一步,为这个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"表示此自定义属性的名字

  1. 第二步,创建一个自定义控件,并让它继承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);
            }
        }
    }
}
  1. 第三步,创建布局文件,并引用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>
  1. 第四步,在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"/>即可。

  1. 第五步,在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);
    }
}
  1. 效果如图在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_18945757/article/details/86547269