前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >android-自定义组合控件和 自定义组合控件不显示问题

android-自定义组合控件和 自定义组合控件不显示问题

作者头像
圆号本昊
发布2021-09-24 12:03:25
1.4K0
发布2021-09-24 12:03:25
举报
文章被收录于专栏:github@hornhuang

代码实现参考自-Android群英传

首先定义 attrs 文件:

代码语言:javascript
复制

在定义 TopBar 类,使其继承自 ViewGroup ( 此处用RelatiLayout )

代码语言:javascript
复制
public class TopBar extends RelativeLayout {
    // 组件
    private Button mLeftButton, mRightButton;
    private TextView mTitleView;
    // 布局元素
    private LayoutParams mLeftParams, mRightParams, mTitlepParams;
    // 属性
    private int mLeftTextColor, mRightTextColor, mTitleTextColor;
    private Drawable mLeftBackground, mRightBackground;
    private String mLeftText, mRightText, mTitle;
    private float mTitleTextSize;
    private TopBarOnClickListener mListner;


    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    public TopBar(Context context) {
        super(context);
//        ConfigurationAttributes(context, attrs);
        mLeftButton = new Button(context);
        mRightButton = new Button(context);
        mTitleView = new TextView(context);

        // 为创建的组件元素赋值
        // 值来源于我们引用的 xml 为减重给对应属性的赋值
        mLeftButton.setTextColor(mLeftTextColor);
        mLeftButton.setBackground(mLeftBackground);
        mLeftButton.setText(mLeftText);

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

        mRightButton.setText(mRightText);

        mTitleView.setText(mTitle);
        mTitleView.setTextColor(mTitleTextColor);
        mTitleView.setTextSize(mTitleTextSize);
        mTitleView.setGravity(Gravity.CENTER);

        // 为组件元素设置对应布局
        mLeftParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT,
                LayoutParams.MATCH_PARENT);
        mLeftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE);
        // 添加到 ViewGroup
        addView(mLeftButton, mLeftParams);

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

        mTitlepParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT,
                LayoutParams.MATCH_PARENT);
        mTitlepParams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE);
        addView(mTitleView, mTitlepParams);
//        ConfigurationIngredient(context);
        ConfigurationListner();
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    public TopBar(Context context, AttributeSet attrs) {
        super(context, attrs);
//        ConfigurationAttributes(context, attrs);
        mLeftButton = new Button(context);
        mRightButton = new Button(context);
        mTitleView = new TextView(context);

        // 为创建的组件元素赋值
        // 值来源于我们引用的 xml 为减重给对应属性的赋值
        mLeftButton.setTextColor(mLeftTextColor);
        mLeftButton.setBackground(mLeftBackground);
        mLeftButton.setText(mLeftText);

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

        mRightButton.setText(mRightText);

        mTitleView.setText(mTitle);
        mTitleView.setTextColor(mTitleTextColor);
        mTitleView.setTextSize(mTitleTextSize);
        mTitleView.setGravity(Gravity.CENTER);

        // 为组件元素设置对应布局
        mLeftParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT,
                LayoutParams.MATCH_PARENT);
        mLeftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE);
        // 添加到 ViewGroup
        addView(mLeftButton, mLeftParams);

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

        mTitlepParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT,
                LayoutParams.MATCH_PARENT);
        mTitlepParams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE);
        addView(mTitleView, mTitlepParams);
//        ConfigurationIngredient(context);
        ConfigurationListner();
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    public TopBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
//        ConfigurationAttributes(context, attrs);
        mLeftButton = new Button(context);
        mRightButton = new Button(context);
        mTitleView = new TextView(context);

        // 为创建的组件元素赋值
        // 值来源于我们引用的 xml 为减重给对应属性的赋值
        mLeftButton.setTextColor(mLeftTextColor);
        mLeftButton.setBackground(mLeftBackground);
        mLeftButton.setText(mLeftText);

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

        mRightButton.setText(mRightText);

        mTitleView.setText(mTitle);
        mTitleView.setTextColor(mTitleTextColor);
        mTitleView.setTextSize(mTitleTextSize);
        mTitleView.setGravity(Gravity.CENTER);

        // 为组件元素设置对应布局
        mLeftParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT,
                LayoutParams.MATCH_PARENT);
        mLeftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE);
        // 添加到 ViewGroup
        addView(mLeftButton, mLeftParams);

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

        mTitlepParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT,
                LayoutParams.MATCH_PARENT);
        mTitlepParams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE);
        addView(mTitleView, mTitlepParams);
//        ConfigurationIngredient(context);
        ConfigurationListner();
    }

    private void ConfigurationAttributes(Context context, AttributeSet attrs){
//        通过这个方法将你在 atts.xml 中定义的 declare-styleable
//        的所有属性的值存储到 TypeArray 中
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TopBar );
//        从 TypeArray 中取出对应的值来为要设置的属性赋值
        mLeftTextColor = typedArray.getColor(
                R.styleable.TopBar_leftTextColor, 0);
        mLeftBackground = typedArray.getDrawable(
                R.styleable.TopBar_leftBackground);
        mLeftText = typedArray.getString(
                R.styleable.TopBar_leftText);

        mRightTextColor = typedArray.getColor(
                R.styleable.TopBar_rightTextColor, 0);
        mRightBackground = typedArray.getDrawable(
                R.styleable.TopBar_rightBackground);

        mRightText = typedArray.getString(
                R.styleable.TopBar_rightText);

        mTitleTextSize = typedArray.getDimension(
                R.styleable.TopBar_titleTextSize, 10);
        mTitleTextColor = typedArray.getColor(
                R.styleable.TopBar_titleTextColor, 0);
        mTitle = typedArray.getString(
                R.styleable.TopBar_title);

        // 获取完 TypeArray 的值后,一般要调用
        // recyle 方法避免新创建时候的错误
        typedArray.recycle();

    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    private void ConfigurationIngredient(Context context){
    }

    private void ConfigurationListner(){
        mRightButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mListner.RightClick();
            }
        });

        mLeftButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mListner.LeftClick();
            }
        });
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }

    public void setOnTopBarClickListner(TopBarOnClickListener topBarClickListner){
        this.mListner = topBarClickListner;
    }

    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);
            }
        }
    }

}

实现其监听事件接口:

代码语言:javascript
复制
public interface TopBarOnClickListener {
    // 左按钮点击事件
    void LeftClick();
    // 右按钮点击事件
    void RightClick();
}

在活动的布局文件中调用:

代码语言:javascript
复制

在学习自定义控件的过程中,遇到了控件无法显示的问题:

预计效果:

实际效果:

解决:

  • 原因:控件实例化石调用了错误的构造方法
  • 方法:删去无用的构造方法

修改结果如下:

代码语言:javascript
复制
public class TopBar extends RelativeLayout {
    // 组件
    private Button mLeftButton, mRightButton;
    private TextView mTitleView;
    // 布局元素
    private LayoutParams mLeftParams, mRightParams, mTitlepParams;
    // 属性
    private int mLeftTextColor, mRightTextColor, mTitleTextColor;
    private Drawable mLeftBackground, mRightBackground;
    private String mLeftText, mRightText, mTitle;
    private float mTitleTextSize;
    private TopBarOnClickListener mListner;

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    public TopBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        ConfigurationAttributes(context, attrs);
        mLeftButton = new Button(context);
        mRightButton = new Button(context);
        mTitleView = new TextView(context);

        // 为创建的组件元素赋值
        // 值来源于我们引用的 xml 为减重给对应属性的赋值
        mLeftButton.setTextColor(mLeftTextColor);
        mLeftButton.setBackground(mLeftBackground);
        mLeftButton.setText(mLeftText);

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

        mRightButton.setText(mRightText);

        mTitleView.setText(mTitle);
        mTitleView.setTextColor(mTitleTextColor);
        mTitleView.setTextSize(mTitleTextSize);
        mTitleView.setGravity(Gravity.CENTER);

        // 为组件元素设置对应布局
        mLeftParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT,
                LayoutParams.MATCH_PARENT);
        mLeftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE);
        // 添加到 ViewGroup
        addView(mLeftButton, mLeftParams);

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

        mTitlepParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT,
                LayoutParams.MATCH_PARENT);
        mTitlepParams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE);
        addView(mTitleView, mTitlepParams);
        ConfigurationListner();
    }

    private void ConfigurationAttributes(Context context, AttributeSet attrs){
        // 通过这个方法将你在 atts.xml 中定义的 declare-styleable
        // 的所有属性的值存储到 TypeArray 中
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TopBar );
//        从 TypeArray 中取出对应的值来为要设置的属性赋值
        mLeftTextColor = typedArray.getColor(
                R.styleable.TopBar_leftTextColor, 0);
        mLeftBackground = typedArray.getDrawable(
                R.styleable.TopBar_leftBackground);
        mLeftText = typedArray.getString(
                R.styleable.TopBar_leftText);

        mRightTextColor = typedArray.getColor(
                R.styleable.TopBar_rightTextColor, 0);
        mRightBackground = typedArray.getDrawable(
                R.styleable.TopBar_rightBackground);

        mRightText = typedArray.getString(
                R.styleable.TopBar_rightText);

        mTitleTextSize = typedArray.getDimension(
                R.styleable.TopBar_titleTextSize, 10);
        mTitleTextColor = typedArray.getColor(
                R.styleable.TopBar_titleTextColor, 0);
        mTitle = typedArray.getString(
                R.styleable.TopBar_title);

        // 获取完 TypeArray 的值后,一般要调用
        // recyle 方法避免新创建时候的错误
        typedArray.recycle();

    }

    private void ConfigurationListner(){
        mRightButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mListner.RightClick();
            }
        });

        mLeftButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mListner.LeftClick();
            }
        });
    }

    /*
    监听事件接口实现
     */
    public void setOnTopBarClickListner(TopBarOnClickListener topBarClickListner){
        this.mListner = topBarClickListner;
    }

    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);
            }
        }
    }

}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/04/01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 首先定义 attrs 文件:
  • 在定义 TopBar 类,使其继承自 ViewGroup ( 此处用RelatiLayout )
  • 实现其监听事件接口:
  • 在活动的布局文件中调用:
  • 预计效果:
  • 实际效果:
  • 解决:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档