編輯:關於Android編程
需求
1.動態加載屬性,如尺碼,顏色,款式等
由於每件商品的屬性是不確定的,有的商品的屬性是顏色和尺碼,有的是口味,有的是大小,所以這些屬性不能直接寫死到頁面上。
2.動態加載屬性下的標簽
每個屬性下的標簽個數也不是一定的,比如有的商品的尺碼是是S,M,XL,有的是均碼,也就是每種屬性的具體的內容是不一定的。
技術點
自定義ViewGroup,使其中的TextView可以依據內容長短自動換行,如下圖所示
實現
布局
通過ListView來顯示商品所有屬性,每種屬性作為ListView的Item。
<span >自定義ViewGroup</span>
普通的LinearLayout只能橫向和縱向顯示控件,但是當一行顯示不夠時,無法自動換行,需要我們自定義布局容器。
<code class="hljs java">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();" height="child.getMeasuredHeight();" if(i="=" 0){="" lengthx+="width+VIEW_MARGIN;//第一個的時候不需要加" }else{="" +jiange;="" 按鈕之間的間隔="" }="" lengthy="row*(height+VIEW_MARGIN)+VIEW_MARGIN+height+arg2;" if="" it="" can't="" drawing="" on="" a="" same="" line="" ,="" skip="" to="" next="" 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); } } } </code>
ListView的Adapter
<code class="hljs java">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,>(); 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++){ string="" void="" viewholder="" view="" v="(TextView)" tv="(TextView)v;" this.type="type;" textviews="(TextView[])v.getTag();" textview="" tablelayout="" return="" public="" private="" override="" new="" myviewgroup="" linearlayout="" lableclicklistener="" int="" implements="" i="0;i<textViews.length;i++){" h="0;h<holder.vgPropContents.getChildCount();h++){" code=""></textviews.length;j++){></string></string></string,></string,textview[]></hashmap<string,textview[]></hashmap<string,object></string,></string,></string,></string,string></hashmap<string,textview[]></hashmap<string,object></code>
總結
這裡關鍵就是實現自定義的ViewGroup,重寫onMeasure和onLayout方法,判斷新添加的控件有沒有超出屏幕的寬度來決定是否要換行。
以上所述是小編給大家介紹的Android 仿淘寶商品屬性標簽頁,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復大家的,在此也非常感謝大家對本站網站的支持!
SwipeRefreshLayout是Android官方的下拉刷新控件,使用簡單,界面美觀,不熟悉的朋友可以隨便搜索了解一下,這裡就不廢話了,直接進入正題。 首
在學習Android開發的過程你,你往往會去借鑒別人的應用是怎麼開發的,那些漂亮的動畫和精致的布局可能會讓你愛不釋手,作為一個開發者,你可能會很想知道這些效果界面是怎麼去
上一篇簡單介紹了廣播的發送,這篇主要介紹下,有序廣播的發送。 設置完相關屬性的時候,廣播就會按照有序的方式進行發送: 發送順序: 第一條廣播; 再發送第二條廣播; 最後發
應用實現密碼登陸,記事本內容可增刪改除等操作,用listview顯示每次保存的記事內容,實現了記事本的基本功能。代碼都有詳細注解。1、代碼的目錄密碼登陸使用的是share