自定义控件属性以及代码设置selectableItemBackground

最近做项目的时候,需要自定义一个视图,需要点击有水波纹效果,这个在xml中简单:

android:background="?attr/selectableItemBackground"

可是写自定义控件的时候,就需要用代码来获取这个属性了,在这之前我们需要了解一些关于自定义控件的知识,知道的同学可以跳过前面,直接到3

1.

首先,我们要知道怎么获取AttributeSet中相关的属性,比如我定义了一个视图RippleButton,若想在xml中有我自定义属性的联想,那么就需要添加 declare-styleable,

<resources>
    <declare-styleable name="RippleButton">
        <attr name="text" format="string"/>
        <attr name="textColor" format="color"/>
        <attr name="textSize" format="dimension"/>
    </declare-styleable>
</resources>

如上,在style中添加了这些东西,那么在我引用我的控件的时候,就会出现提示了:

       <com.xunyou.xunyouapp.view.customview.RippleButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:text="立即组队"
            app:textColor ="@color/colorFontMainWhite"
            app:textSize = "@dimen/general_font_x2"/>

2.

接下来进入正题,
设置了自定义属性,那我们就会在代码中的构造方法中收到传过来的AttributeSet,比如我们此时需要获取我们定义的text属性的值:

TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.RippleButton);
typedArray.getString(R.styleable.RippleButton_text);

重点就在于 typedArray.getString(attrid)这一步,当我们是自定义属性的时候,系统会生成对应的attrId,格式为: R.styleable. + declare-styleable名 + _ + attr名

3.

设置selectableItemBackground
知道了原理,那么现在问题来了,怎么获取selectableItemBackground中对应的attrId,这就需要使用TypeValue这个东西,它是用来解析attr属性相关内容的

TypedValue typedValue = new TypedValue();
getContext().getTheme()
.resolveAttribute(android.R.attr.selectableItemBackground, typedValue, true);

下面重头戏来了,我们可以用typedValue.resourceId获取到attr对应的id:

int[] attribute = new int[]{android.R.attr.selectableItemBackground};
        TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(typedValue.resourceId, attribute);

之后就可以从里面获取对应的Drawable了:

        setBackground(typedArray.getDrawable(0));

以上就是怎么用代码设置selectableItemBackground的内容了,有错误请指出,下面附上我写的带水波纹的控件
(DensityUtil就是个dp,sp转px的工具,网上很多)

RippleButton.java

package com.xunyou.xunyouapp.view.customview;

import android.content.Context;
import android.content.res.TypedArray;
import android.support.design.internal.ForegroundLinearLayout;
import android.support.v7.widget.AppCompatTextView;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;

import com.xunyou.xunyouapp.R;
import com.xunyou.xunyouapp.util.DensityUtil;

/**
 * Created by phc on 2016/11/10 0010.
 * 水波纹按钮 就是在里面加个 AppTextView
 */

public class RippleButton extends ForegroundLinearLayout {
    private AppCompatTextView mTextView;
    private final int DEFULT_TXT_COL = 0xffffffff;
    private final int DEFULT_TXT_SIZE = 16;

    public RippleButton(Context context) {
//        super(context);
        this(context, null, 0);
    }

    public RippleButton(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RippleButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs);
    }

    private void init(AttributeSet attrs) {
        mTextView = new AppCompatTextView(getContext());
        mTextView.setTextColor(DEFULT_TXT_COL);
        mTextView.setTextSize(DEFULT_TXT_SIZE);
        if (attrs != null) {
            TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.RippleButton);
            String texContent = typedArray.getString(R.styleable.RippleButton_text);
            float textSize = typedArray.getDimension(R.styleable.RippleButton_textSize, DensityUtil.sp2Px(getContext(), DEFULT_TXT_SIZE));
            int textColor = typedArray.getColor(R.styleable.RippleButton_textColor, DEFULT_TXT_COL);
            mTextView.setText(texContent);
            mTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
            mTextView.setTextColor(textColor);
            typedArray.recycle();
        } else {
            mTextView.setTextColor(DEFULT_TXT_COL);
            mTextView.setTextSize(DEFULT_TXT_SIZE);
        }
        addView(mTextView);
        setGravity(Gravity.CENTER);
        setClickable(true);
        TypedValue typedValue = new TypedValue();
        getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, typedValue, true);
        int[] attribute = new int[]{android.R.attr.selectableItemBackground};
        TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(typedValue.resourceId, attribute);
        setForeground(typedArray.getDrawable(0));
        typedArray.recycle();
    }

    private void setTxtColor(int color) {
        if (mTextView != null) {
            mTextView.setTextColor(color);
        }
    }
}

style.xml

<resources>

    <declare-styleable name="RippleButton">
        <attr name="text" format="string"/>
        <attr name="textColor" format="color"/>
        <attr name="textSize" format="dimension"/>
    </declare-styleable>
    </resources>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值