当前位置: 代码迷 >> Android >> 【Android开发—电商系列】(2):仿淘宝商品属性标签页
  详细解决方案

【Android开发—电商系列】(2):仿淘宝商品属性标签页

热度:104   发布时间:2016-04-24 12:01:40.0
【Android开发—电商系列】(二):仿淘宝商品属性标签页

一睹为快

      这里写图片描述

需求

1.动态加载属性,如尺码,颜色,款式等

  由于每件商品的属性是不确定的,有的商品的属性是颜色和尺码,有的是口味,有的是大小,所以这些属性不能直接写死到页面上。

2.动态加载属性下的标签

  每个属性下的标签个数也不是一定的,比如有的商品的尺码是是S,M,XL,有的是均码,也就是每种属性的具体的内容是不一定的。

技术点

自定义ViewGroup,使其中的TextView可以依据内容长短自动换行,如下图所示

     这里写图片描述

实现

布局

通过ListView来显示商品所有属性,每种属性作为ListView的Item。

 <!-- 商品规格列表 -->    <LinearLayout         android:layout_width="match_parent"        android:layout_height="match_parent"                android:background="#FFFFFFFF"        >         <ListView              android:id="@+id/lv_property"                        android:layout_width="fill_parent"             android:layout_height="match_parent"             android:layout_marginLeft="5dp"              android:layout_marginRight="5dp"             android:divider="#C0C0C0"             android:dividerHeight="0.5px"             android:listSelector="#00000000">        </ListView>     </LinearLayout>

自定义ViewGroup

普通的LinearLayout只能横向和纵向显示控件,但是当一行显示不够时,无法自动换行,需要我们自定义布局容器。

package jczb.shoping.common;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.View;import android.view.ViewGroup;public class MyViewGroup extends ViewGroup {     private final static int VIEW_MARGIN=15;     public MyViewGroup(Context context, AttributeSet attrs){         super(context, attrs);     }     public MyViewGroup(Context context) {         super(context);     }     @Override     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int stages = 1;        int stageHeight = 0;        int stageWidth = 0;        int wholeWidth = MeasureSpec.getSize(widthMeasureSpec);        for (int i = 0; i < getChildCount(); i++) {            final View child = getChildAt(i);            // measure            measureChild(child, widthMeasureSpec, heightMeasureSpec);            stageWidth += (child.getMeasuredWidth() + VIEW_MARGIN);            stageHeight = child.getMeasuredHeight();            if (stageWidth >= wholeWidth) {                stages++;                //reset stageWidth                stageWidth = child.getMeasuredWidth();            }        }        int wholeHeight = (stageHeight + VIEW_MARGIN) * stages;        // report this final dimension        setMeasuredDimension(resolveSize(wholeWidth, widthMeasureSpec),                resolveSize(wholeHeight, heightMeasureSpec));     }     private int jiange = 10;//按钮之间的间隔     @Override     protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) {         final int count = getChildCount();         int row=0;// which row lay you view relative to parent         int lengthX=arg1 ;    // right position of child relative to parent         int lengthY=arg2;    // bottom position of child relative to parent         for(int i=0;i<count;i++){             final View child = this.getChildAt(i);             int width = child.getMeasuredWidth();             int height = child.getMeasuredHeight();             if(i == 0){                 lengthX+=width+VIEW_MARGIN;//第一个的时候不需要加             }else{                 lengthX+=width+VIEW_MARGIN +jiange;//按钮之间的间隔             }             lengthY=row*(height+VIEW_MARGIN)+VIEW_MARGIN+height+arg2;             //if it can't drawing on a same line , skip to next line             if(lengthX>arg3){                 lengthX=width+VIEW_MARGIN+arg1;                 row++;                 lengthY=row*(height+VIEW_MARGIN)+VIEW_MARGIN+height+arg2;             }             child.layout(lengthX-width, lengthY-height, lengthX, lengthY);         }     }}

ListView的Adapter

package jczb.shoping.adapter;import java.util.ArrayList;import java.util.HashMap;import jczb.shoping.common.MyViewGroup;import jczb.shoping.ui.R;import android.content.Context;import android.graphics.Color;import android.graphics.drawable.Drawable;import android.os.Handler;import android.view.LayoutInflater;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.Button;import android.widget.LinearLayout;import android.widget.LinearLayout.LayoutParams;import android.widget.TableLayout;import android.widget.TextView;public class PropertyAdapter extends BaseAdapter {    private Context mContext;    private ArrayList<HashMap<String,Object>> mList;    private ArrayList<HashMap<String,TextView[]>> mViewList;    private Drawable drawableNormal ;    private Drawable drawablePressed;    private Handler mHandler;    //用于保存用户的属性集合    private HashMap<String,String> selectProMap=new HashMap<String, String>();    /**     * 返回选中的属性     * @return     */    public HashMap<String, String> getSelectProMap() {        return selectProMap;    }    public void setSelectProMap(HashMap<String, String> selectProMap) {        this.selectProMap = selectProMap;    }    public PropertyAdapter(Handler handler,Context context,ArrayList<HashMap<String,Object>> list){        super();        this.mHandler=handler;        this.mContext=context;        this.mList=list;        mViewList=new ArrayList<HashMap<String,TextView[]>>();        drawableNormal=mContext.getResources().getDrawable(R.drawable.tv_property_label);    }    @Override    public int getCount() {        // TODO Auto-generated method stub        return mList.size();    }    @Override    public Object getItem(int position) {        // TODO Auto-generated method stub        return mList.get(position);    }    @Override    public long getItemId(int position) {        // TODO Auto-generated method stub        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        ViewHolder holder = null;         if (convertView == null) {            // 获取list_item布局文件的视图            convertView = LayoutInflater.from(this.mContext).inflate(R.layout.lv_property_item, null,true);            holder = new ViewHolder();             // 获取控件对象            holder.tvPropName= (TextView) convertView                    .findViewById(R.id.tv_property_name);            //holder.llPropContents=(LinearLayout)convertView.findViewById(R.id.ll_property_content);            //holder.tlPropContents=(TableLayout)convertView.findViewById(R.id.ll_property_content);            // 设置控件集到convertView            holder.vgPropContents= (MyViewGroup) convertView.findViewById(R.id.myviewgroup);            convertView.setTag(holder);        } else {            holder = (ViewHolder) convertView.getTag();         }        if (this.mList != null) {            //HashMap<String,TextView[]> mapView=new HashMap<String, TextView[]>();            ArrayList<String> lables = (ArrayList<String>) this.mList.get(position).get("lable");            String type = (String) this.mList.get(position).get(                    "type");            holder.tvPropName.setText(type);//规格名称            //动态加载标签            //判断布局中的子控件是否为0,如果不为0,就不添加了,防止ListView滚动时重复添加            if(holder.vgPropContents.getChildCount()==0){                TextView[]  textViews = new TextView[lables.size()];                //设置每个标签的文本和布局                //TableRow tr=new TableRow(mContext);                 for (int i = 0; i < lables.size(); i++) {                     TextView textView = new TextView(mContext);                     textView.setGravity(17);                     textView.setPadding(25,15,25,15);                                    textViews[i] = textView;                     textViews[i].setBackgroundResource(R.drawable.tv_property_label);                     textViews[i].setText(lables.get(i));                     textViews[i].setTag(i);                     //textViews[i].setBackgroundColor(Color.parseColor("#EE5500"));                     //tr.addView(textViews[i]);                    // holder.llPropContents.addView(textViews[i]);                     holder.vgPropContents.addView(textViews[i]);                 }                 //holder.tlPropContents.addView(tr);                 //绑定标签的Click事件                 for(int j=0;j<textViews.length;j++){                     textViews[j].setTag(textViews);                     textViews[j].setOnClickListener(new LableClickListener(type));                 }                 //把控件存起来//               mapView.put(type, textViews);//               mViewList.add(mapView);            }            /**判断之前是否已选中标签*/            if(selectProMap.get(type)!=null){                for(int h=0;h<holder.vgPropContents.getChildCount();h++){                    TextView v=(TextView) holder.vgPropContents.getChildAt(h);                    if(selectProMap.get(type).equals(v.getText().toString())){                        v.setBackgroundColor(Color.parseColor("#EE5500"));                        v.setTextColor(Color.parseColor("#FFFFFF"));                        selectProMap.put(type, v.getText().toString());                    }                }            }        }        return convertView;    }    /*定义item对象*/    public class ViewHolder {        TextView tvPropName;            LinearLayout llPropContents;        MyViewGroup vgPropContents;        TableLayout tlPropContents;   }     class LableClickListener implements OnClickListener{        private String type;         public LableClickListener(String type){            this.type=type;        }        @Override        public void onClick(View v) {            TextView[] textViews=(TextView[])v.getTag();            TextView tv=(TextView)v;            for(int i=0;i<textViews.length;i++){                //让点击的标签背景变成橙色,字体颜色变为白色                if(tv.equals(textViews[i])){                    textViews[i].setBackgroundColor(Color.parseColor("#EE5500"));                    textViews[i].setTextColor(Color.parseColor("#FFFFFF"));                    selectProMap.put(type, textViews[i].getText().toString());                }else{                    //其他标签背景变成白色,字体颜色为黑色                    //textViews[i].setBackgroundDrawable(drawableNormal);                    textViews[i].setBackgroundResource(R.drawable.tv_property_label);                    textViews[i].setTextColor(Color.parseColor("#000000"));                }            }        }     } }

总结

  这里关键就是实现自定义的ViewGroup,重写onMeasure和onLayout方法,判断新添加的控件有没有超出屏幕的宽度来决定是否要换行。

1楼u010508826前天 09:57
当时这块我就没有搞出来,还是败在了自定义Viewgroup上啊!@不错
  相关解决方案