博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何更好的通过Inflate layout的方式来实现自定义view
阅读量:6821 次
发布时间:2019-06-26

本文共 3395 字,大约阅读时间需要 11 分钟。

本篇文章讲的是如何用现有控件产生一个组合控件的方法,十分简单实用。现在开始!

一、需求

我们要实现一个有红点和文字的按钮控件,就像下面这样:

二、实现

我的思路是让一个button和一个textview进行组合。

可以看到最外层我用了merge标签,这是因为我需要把这个xml加载到一个自定义的RelativeLayout中。merge标签主要是用来避免重复嵌套的。

接着我在java代码中加载这个xml文件

public class BottomTab extends RelativeLayout implements BottomTabImpl {    public BottomTab(Context context) {        this(context, null);    }    public BottomTab(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public BottomTab(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        initViews();    }private void initViews() {        inflate(getContext(), R.layout.test_xml, this);

这样就完成了一个初步的自定义view,但我们要知道merge标签是有弊端的。<merge>标签可以融合其内容,但是不包括自身,因此顶层的属性都丢失了。而且用了merge,在布局中因为不知道最外层是什么控件,所以就不能很好的进行预览。预览的问题无法解决,但是我们有方法让控件最外层的属性加回来。

三、解决merge属性丢失的问题

有三种办法可以将它们添加回来:

1)在代码中添加

private void initViews() {        inflate(getContext(), R.layout.card, this);        // add bg to root view        setBackgroundColor(getResources().getColor(R.color.card_background));         //Add missing top level attributes            int padding = (int)getResources().getDimension(R.dimen.card_padding);        setPadding(padding, padding, padding, padding);        ……    }

2)在控件被使用的时候添加丢失的属性

3)定义一个stylable 属性将这些值通过style提供给控件
attr.xml
style.xml
Card.java
public class Card extends RelativeLayout {     public Card(Context context) {        super(context, null, R.attr.cardStyle);        init();    }     public Card(Context context, AttributeSet attrs) {        super(context, attrs, R.attr.cardStyle);        init();    }    .....
需要注意的是要在view的构造方法中要传入R.attr.xxx的文件,让控件去调用。为了更加说明这点,我举个toolbar的例子来说明。
首先,toolbar在系统中定义了这样一个attr:

然后在代码中进行了如下的设置:

public Toolbar(Context context) {        this(context, null);    }    public Toolbar(Context context, @Nullable AttributeSet attrs) {        this(context, attrs, R.attr.toolbarStyle);    }    public Toolbar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        // Need to use getContext() here so that we use the themed context        final TintTypedArray a = TintTypedArray.obtainStyledAttributes(getContext(), attrs,                R.styleable.Toolbar, defStyleAttr, 0);        mTitleTextAppearance = a.getResourceId(R.styleable.Toolbar_titleTextAppearance, 0);        mSubtitleTextAppearance = a.getResourceId(R.styleable.Toolbar_subtitleTextAppearance, 0);        mGravity = a.getInteger(R.styleable.Toolbar_android_gravity, mGravity);        mButtonGravity = Gravity.TOP;        mTitleMarginStart = mTitleMarginEnd = mTitleMarginTop = mTitleMarginBottom =                a.getDimensionPixelOffset(R.styleable.Toolbar_titleMargins, 0);

这样我们就知道这个view用到了R.attr.toolbarStyle的属性,所以如果我们想要设置一个全局的属性,那么可以在theme中进行设置即可。

设置具体的值:

 

参考自:

 

转载地址:http://pkozl.baihongyu.com/

你可能感兴趣的文章