需要实现的效果:
思路:
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;//viewgroup宽高
private int oneW=0,oneH=0;//子view宽高
private int shu=3;//竖着有几排
private int heng=0;//横着有几排
private int pading=0;//子view间距
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);
}
//确定viewgroup,以及所有子view的大小
//在这个确定的过程中,就实现了每个子view等分
@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;
//一定要注意这里的EXACTLY,EXACTLY 一定要与子view对上,比如我这写EXACTLY,子view动态layoutparm就写MATCH_PARENT或XXDP
//如果我这写ALMOST,ALMOST 子view动态layoutparm就写WARP_PARENT
//不然子view执行measure方法时,就用不到你传过去的宽高
measureChildren(View.MeasureSpec.makeMeasureSpec(oneW, EXACTLY),View.MeasureSpec.makeMeasureSpec(oneH, EXACTLY));
setMeasuredDimension(allW,allH);
}
//确定viewgroup,以及所有子view的位置
//在这个确定的过程中,就实现了每个子view的位置排列
@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的绘制流程,思路清晰,算这东西就不会晕,不会错