最近做项目的时候,需要自定义一个视图,需要点击有水波纹效果,这个在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>