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

版权声明:个人学习记录,由于能力和时间有限,如果有错误望读者纠正,谢谢! 转载请注明出处 谢谢合作 https://blog.csdn.net/qq_43377749/article/details/88946928

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

首先定义 attrs 文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="TopBar">
        <attr name="title" format="string"></attr>
        <attr name="titleTextSize" format="dimension"></attr>
        <attr name="titleTextColor" format="color"></attr>
        <attr name="leftTextColor" format="color"></attr>
        <attr name="leftBackground" format="reference|color"></attr>
        <attr name="leftText" format="string"></attr>
        <attr name="rightTextColor" format="color"></attr>
        <attr name="rightBackground" format="reference|color"></attr>
        <attr name="rightText" format="string"></attr>
    </declare-styleable>
</resources>

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

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

}

实现其监听事件接口:

public interface TopBarOnClickListener {
    // 左按钮点击事件
    void LeftClick();
    // 右按钮点击事件
    void RightClick();
}

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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".activies.MainActivity">
    
    <com.example.desighviewtext.views.TopBar
        android:layout_width="match_parent"
        android:layout_height="50dp"
        custom:leftText = "BACK"
        custom:leftBackground = "@android:color/holo_blue_bright"
        custom:leftTextColor = "#FFFFFF"

        custom:title = "自定义标题"
        custom:titleTextSize = "10sp"
        custom:titleTextColor = "#000000"

        custom:rightText = "MORE"
        custom:rightBackground = "@android:color/holo_blue_bright"
        custom:rightTextColor = "#FFFFFF">

    </com.example.desighviewtext.views.TopBar>

</LinearLayout>

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

预计效果:

实际效果:

解决:

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

修改结果如下:

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

}

猜你喜欢

转载自blog.csdn.net/qq_43377749/article/details/88946928