需要实现的效果:
思路:
1:LinearLayout里包含LinearLayout里包含LinearLayout里包含LinearLayout 2:RecycleView里包含一层RecycleView 3:自定义ViewGroup
1太小学生,2太麻烦,所以来用3,且代码极其简单,优雅,复用性极高 xml里什么也不用谢,仅需在activity中这么写
private ArrayList
<MyChooseBtnView
> allChoose
=new ArrayList<MyChooseBtnView
>();
private void addData(){
allChoose
.add(new MyChooseBtnView(getActivity(),new String[]{"新车","二手车","库存车"}));
allChoose
.add(new MyChooseBtnView(getActivity(),new String[]{"白色","黑色","绿色","蓝色","粉色","白色","灰色"}));
allChoose
.add(new MyChooseBtnView(getActivity(),new String[]{"1.0L","1.5L","2.0L","2.5L"}));
allChoose
.add(new MyChooseBtnView(getActivity(),new String[]{"营运","非营运","私家车","公车"}));
allChoose
.add(new MyChooseBtnView(getActivity(),new String[]{"1万","2万","3万","4万","5万","6万","7万"}));
allChoose
.add(new MyChooseBtnView(getActivity(),new String[]{"电动","汽油","混合","柴油"}));
for(MyChooseBtnView oneChoose
:allChoose
){
needAdd
.addView(oneChoose
);
}
}
private ArrayList
<String
> getAllRes(){
ArrayList
<String
> res
=new ArrayList<String
>();
for(MyChooseBtnView oneChoose
:allChoose
){
res
.add(oneChoose
.getRes());
}
return res
;
}
addData也可以根据实际情况去动态add, getAllRes()就得出了[“二手车”,“黑色”,“2.5L”,“营运”,“3万”,“电动”], 把这个结果发给服务器,是不是很优雅?
下面是组件的代码,就一个自定义的ViewGroup:
MyChooseBtnView.java:
public class MyChooseBtnView extends ViewGroup {
private int allW
=0,allH
=0;
private int oneW
=0,oneH
=0;
private int shu
=3;
private int heng
=0;
private int pading
=0;
private int nowChoose
=-1;
private String
[] datas
={};
public MyChooseBtnView(Context context
,String
[] data
) {
super(context
);
oneH
= BaseObserver
.getInstance().getPXformDP(40);
pading
=BaseObserver
.getInstance().getPXformDP(8);
datas
=data
;
for(int i
=0;i
<datas
.length
;i
++){
addView(getText(context
,datas
[i
],i
));
}
}
public MyChooseBtnView(Context context
, AttributeSet attrs
) {
this(context
, attrs
, 0);
}
public MyChooseBtnView(Context context
, AttributeSet attrs
, int defStyle
) {
super(context
, attrs
, defStyle
);
}
@Override
protected void onMeasure(int widthMeasureSpec
, int heightMeasureSpec
) {
super.onMeasure(widthMeasureSpec
, heightMeasureSpec
);
heng
=datas
.length
/shu
+(datas
.length
%shu
==0?0:1);
allW
=MeasureSpec
.getSize(widthMeasureSpec
);
allH
= oneH
* heng
+pading
+pading
* heng
;
oneW
=(allW
-pading
* shu
-pading
)/ shu
;
measureChildren(View
.MeasureSpec
.makeMeasureSpec(oneW
, EXACTLY
),View
.MeasureSpec
.makeMeasureSpec(oneH
, EXACTLY
));
setMeasuredDimension(allW
,allH
);
}
@Override
protected void onLayout(boolean changed
, int l
, int t
, int r
, int b
) {
for (int i
= 0; i
< getChildCount(); i
++) {
View textView
=getChildAt(i
);
int var1
= i
/ shu
;
int var2
= i
% shu
;
int left
= oneW
*var2
+pading
+pading
*var2
;
int top
= oneH
*var1
+pading
+pading
*var1
;
int right
= left
+ oneW
;
int bottom
= top
+ oneH
;
textView
.layout(left
, top
, right
, bottom
);
}
}
private TextView
getText(Context context
,String s
,int po
){
TextView textView
=new TextView(context
);
textView
.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams
.MATCH_PARENT
,LayoutParams
.MATCH_PARENT
));
textView
.setTextSize(TypedValue
.COMPLEX_UNIT_DIP
,15);
textView
.setBackgroundResource(R
.drawable
.shape63
);
textView
.setTextColor(0xff8a8a8a);
textView
.setGravity(Gravity
.CENTER
);
textView
.setText(s
);
textView
.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v
) {
setNowChoose(po
);
}
});
return textView
;
}
private void setNowChoose(int po
){
if(nowChoose
!=-1){
TextView textView
=(TextView
)getChildAt(nowChoose
);
textView
.setBackgroundResource(R
.drawable
.shape63
);
textView
.setTextColor(0xff8a8a8a);
}
nowChoose
=po
;
TextView textView
=(TextView
)getChildAt(nowChoose
);
textView
.setBackgroundResource(R
.drawable
.shape64
);
textView
.setTextColor(0xffffffff);
}
public String
getRes(){
if(nowChoose
!=-1){
return datas
[nowChoose
];
}else {
return null
;
}
}
}
重点就是要理解ViewGroup里的onMeasure,onLayout方法
在前者里算出viewGroup的宽高,以及里面所有子view的宽高 在后者里算出所有子view的位置 明白安卓多层级UI的绘制流程,思路清晰,算这东西就不会晕,不会错