自定義控制元件屬性以及程式碼設定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>