前段时间在看属性动画,恰巧这个按钮的效果可以用属性动画实现,所以就来实践实践。效果基本出来了,大家可以自己去完善。
首先看一下效果图:
我们看到点击FloatingActionButton后会展开一些item,然后会有一个蒙板效果,这都是这个View的功能。那么这整个View肯定是个ViewGroup,我们一部分一部分来看。
首先是这个最小的Tag:
这个Tag带文字,可以是一个TextView,但为了美观,我们使用CardView,CardView是一个FrameLayout,我们要让它具有显示文字的功能,就继承CardView自定义一个ViewGroup。
public class TagView extends CardView
内部维护一个TextView,在其构造函数中我们实例化一个TextView用来显示文字,并在外部调用setTagText的时候把TextView添加到这个CardView中。
public class TagView extends CardView {
private TextView mTextView;
public TagView(Context context) {
this(context, null);
}
public TagView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TagView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mTextView = new TextView(context);
mTextView.setSingleLine(true);
}
protected void setTextSize(float size){
mTextView.setTextSize(size);
}
protected void setTextColor(int color){
mTextView.setTextColor(color);
}
//给内部的TextView添加文字
protected void setTagText(String text){
mTextView.setText(text);
addTag();
}
//添加进这个layout中
private void addTag(){
LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT
, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER);
int l = dp2px(8);
int t = dp2px(8);
int r = dp2px(8);
int b = dp2px(8);
layoutParams.setMargins(l, t, r, b);
//addView会引起所有View的layout
addView(mTextView, layoutParams);
}
private int dp2px(int value){
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP
, value, getResources().getDisplayMetrics());
}
}
接下来我们看这个item,它是一个tag和一个fab的组合:
tag使用刚才我们自定义的TagView,fab就用系统的FloatingActionButton,这里显然需要一个ViewGroup来组合这两个子View,可以使用LinearLayout,这里我们就直接使用ViewGroup。
public class TagFabLayout extends ViewGroup
我们为这个ViewGroup设置自定义属性,是为了给tag设置text:
<declare-styleable name="FabTagLayout">
<attr name="tagText" format="string" />
</declare-styleable>
在构造器中获取自定义属性,初始化TagView并添加到该ViewGroup中:
public TagFabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
getAttributes(context, attrs);
settingTagView(context);
}
private void getAttributes(Context context, AttributeSet attributeSet){
TypedArray typedArray = context.obtainStyledAttributes(attributeSet
, R.styleable.FabTagLayout);
mTagText = typedArray.getString(R.styleable.FabTagLayout_tagText);
typedArray.recycle();
}
private void settingTagView(Context context){
mTagView = new TagView(context);
mTagView.setTagText(mTagText);
addView(mTagView);
}
在onMeasure对该ViewGroup进行测量,这里我直接把宽高设置成wrap_content的了,match_parent和精确值感觉没有必要。Tag