亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > Android > 正文

Android實現多維商品屬性SKU選擇

2019-10-21 21:37:05
字體:
來源:轉載
供稿:網友

前言:

最近又做到這一塊的需求,以前也做過類似仿淘寶的屬性選擇,當時在網上下載的demo參考,最多也支持兩組商品屬性,用的兩個gridview結合,擴展性很差,這次不打算用之前的代碼,所以重新自己寫了一個demo**(文末附上項目地址)**

Android,商品屬性,SKU

如圖所示,界面UI這一塊肯定不用gridview,那樣太過繁瑣,所以采用recyclerview,item里面渲染ViewGroup,根據數據源的數量,往ViewGroup里面添加Textview。這樣就可以解決它的每個屬性按鈕寬高自適應。 
這里重點是重寫ViewGroup里面的onMeasure和onLayout方法:

/**   * 測量子view大小 根據子控件設置寬和高   */  @Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  {    super.onMeasure(widthMeasureSpec, heightMeasureSpec);    // 獲得它的父容器為它設置的測量模式和大小    int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);    int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);    int modeWidth = MeasureSpec.getMode(widthMeasureSpec);    int modeHeight = MeasureSpec.getMode(heightMeasureSpec);    // 如果是warp_content情況下,記錄寬和高    int width = 0;    int height = 0;    /**     * 記錄每一行的寬度,width不斷取最大寬度     */    int lineWidth = 0;    /**     * 每一行的高度,累加至height     */    int lineHeight = 0;    int cCount = getChildCount();    // 遍歷每個子元素    for (int i = 0; i < cCount; i++)    {      View child = getChildAt(i);      // 測量每一個child的寬和高      measureChild(child, widthMeasureSpec, heightMeasureSpec);      // 得到child的布局管理器      MarginLayoutParams lp = (MarginLayoutParams) child          .getLayoutParams();      // 當前子空間實際占據的寬度      int childWidth = child.getMeasuredWidth() + lp.leftMargin          + lp.rightMargin;      // 當前子空間實際占據的高度      int childHeight = child.getMeasuredHeight() + lp.topMargin          + lp.bottomMargin;      /**       * 如果加入當前child,則超出最大寬度,則的到目前最大寬度給width,類加height 然后開啟新行       */      if (lineWidth + childWidth > sizeWidth)      {        width = Math.max(lineWidth, childWidth);// 取最大的        lineWidth = childWidth; // 重新開啟新行,開始記錄        // 疊加當前高度,        height += lineHeight;        // 開啟記錄下一行的高度        lineHeight = childHeight;      } else      // 否則累加值lineWidth,lineHeight取最大高度      {        lineWidth += childWidth;        lineHeight = Math.max(lineHeight, childHeight);      }      // 如果是最后一個,則將當前記錄的最大寬度和當前lineWidth做比較      if (i == cCount - 1)      {        width = Math.max(width, lineWidth);        height += lineHeight;      }    }    setMeasuredDimension((modeWidth == MeasureSpec.EXACTLY) ? sizeWidth        : width, (modeHeight == MeasureSpec.EXACTLY) ? sizeHeight        : height);  }
@Override  protected void onLayout(boolean changed, int l, int t, int r, int b)  {    mAllViews.clear();    mLineHeight.clear();    int width = getWidth();    int lineWidth = 0;    int lineHeight = 0;    // 存儲每一行所有的childView    List<View> lineViews = new ArrayList<>();    int cCount = getChildCount();    // 遍歷所有的孩子    for (int i = 0; i < cCount; i++)    {      View child = getChildAt(i);      MarginLayoutParams lp = (MarginLayoutParams) child          .getLayoutParams();      int childWidth = child.getMeasuredWidth();      int childHeight = child.getMeasuredHeight();      // 如果已經需要換行      if (childWidth + lp.leftMargin + lp.rightMargin + lineWidth > width)      {        // 記錄這一行所有的View以及最大高度        mLineHeight.add(lineHeight);        // 將當前行的childView保存,然后開啟新的ArrayList保存下一行的childView        mAllViews.add(lineViews);        lineWidth = 0;// 重置行寬        lineViews = new ArrayList<>();      }      /**       * 如果不需要換行,則累加       */      lineWidth += childWidth + lp.leftMargin + lp.rightMargin;      lineHeight = Math.max(lineHeight, childHeight + lp.topMargin          + lp.bottomMargin);      lineViews.add(child);    }    // 記錄最后一行    mLineHeight.add(lineHeight);    mAllViews.add(lineViews);    int left = 0;    int top = 0;    // 得到總行數    int lineNums = mAllViews.size();    for (int i = 0; i < lineNums; i++)    {      // 每一行的所有的views      lineViews = mAllViews.get(i);      // 當前行的最大高度      lineHeight = mLineHeight.get(i);      // 遍歷當前行所有的View      for (int j = 0; j < lineViews.size(); j++)      {        View child = lineViews.get(j);        if (child.getVisibility() == View.GONE)        {          continue;        }        MarginLayoutParams lp = (MarginLayoutParams) child            .getLayoutParams();        //計算childView的Marginleft,top,right,bottom        int lc = left + lp.leftMargin;        int tc = top + lp.topMargin;        int rc =lc + child.getMeasuredWidth();        int bc = tc + child.getMeasuredHeight();        child.layout(lc, tc, rc, bc);        left += child.getMeasuredWidth() + lp.rightMargin            + lp.leftMargin;      }      left = 0;      top += lineHeight;    }  }

接下來是SKU的算法,因為本人的學生時期數學沒有好好學習,冪集什么的,都不是很懂。所以在這里用了另外一種方法,把選項狀態(三種:不能選擇,可以選擇,已選中)依次對屬性按鈕做出修改,這里雖然做了一些不必要的循環判斷,但勝在功能的實現,如果大家有更好的想法,望不吝賜教。

貼上adapter代碼(重點initOptions、canClickOptions和getSelected三個方法)

/** * Created by 胡逸楓 on 2017/1/16. */public class GoodsAttrsAdapter extends BaseRecyclerAdapter<GoodsAttrsBean.AttributesBean> {  private SKUInterface myInterface;  private SimpleArrayMap<Integer, String> saveClick;  private List<GoodsAttrsBean.StockGoodsBean> stockGoodsList;//商品數據集合  private String[] selectedValue;  //選中的屬性  private TextView[][] childrenViews;  //二維 裝所有屬性  private final int SELECTED = 0x100;  private final int CANCEL = 0x101;  public GoodsAttrsAdapter(Context ctx, List<GoodsAttrsBean.AttributesBean> list, List<GoodsAttrsBean.StockGoodsBean> stockGoodsList) {    super(ctx, list);    this.stockGoodsList = stockGoodsList;    saveClick = new SimpleArrayMap<>();    childrenViews = new TextView[list.size()][0];    selectedValue = new String[list.size()];    for (int i = 0; i < list.size(); i++) {      selectedValue[i] = "";    }  }  public void setSKUInterface(SKUInterface myInterface) {    this.myInterface = myInterface;  }  @Override  public int getItemLayoutId(int viewType) {    return R.layout.item_skuattrs;  }  @Override  public void bindData(RecyclerViewHolder holder, int position, GoodsAttrsBean.AttributesBean item) {    TextView tv_ItemName = holder.getTextView(R.id.tv_ItemName);    SKUViewGroup vg_skuItem = (SKUViewGroup) holder.getView(R.id.vg_skuItem);    tv_ItemName.setText(item.getTabName());    List<String> childrens = item.getAttributesItem();    int childrenSize = childrens.size();    TextView[] textViews = new TextView[childrenSize];    for (int i = 0; i < childrenSize; i++) {      LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);      params.setMargins(5, 5, 5, 0);      TextView textView = new TextView(mContext);      textView.setGravity(Gravity.CENTER);      textView.setPadding(15, 5, 15, 5);      textView.setLayoutParams(params);      textView.setBackgroundColor(ContextCompat.getColor(mContext, R.color.saddlebrown));      textView.setText(childrens.get(i));      textView.setTextColor(ContextCompat.getColor(mContext, R.color.white));      textViews[i] = textView;      vg_skuItem.addView(textViews[i]);    }    childrenViews[position] = textViews;    initOptions();    canClickOptions();    getSelected();  }  private int focusPositionG, focusPositionC;  private class MyOnClickListener implements View.OnClickListener {    //點擊操作 選中SELECTED  取消CANCEL    private int operation;    private int positionG;    private int positionC;    public MyOnClickListener(int operation, int positionG, int positionC) {      this.operation = operation;      this.positionG = positionG;      this.positionC = positionC;    }    @Override    public void onClick(View v) {      focusPositionG = positionG;      focusPositionC = positionC;      String value = childrenViews[positionG][positionC].getText().toString();      switch (operation) {        case SELECTED:          saveClick.put(positionG, positionC + "");          selectedValue[positionG] = value;          myInterface.selectedAttribute(selectedValue);          break;        case CANCEL:          saveClick.put(positionG, "");          for (int l = 0; l < selectedValue.length; l++) {            if (selectedValue[l].equals(value)) {              selectedValue[l] = "";              break;            }          }          myInterface.uncheckAttribute(selectedValue);          break;      }      initOptions();      canClickOptions();      getSelected();    }  }  class MyOnFocusChangeListener implements View.OnFocusChangeListener {    private int positionG;    private int positionC;    public MyOnFocusChangeListener(int positionG, int positionC) {      this.positionG = positionG;      this.positionC = positionC;    }    @Override    public void onFocusChange(View v, boolean hasFocus) {      String clickpositionC = saveClick.get(positionG);      if (hasFocus) {        v.setBackgroundColor(ContextCompat.getColor(mContext, R.color.pink));        if (TextUtils.isEmpty(clickpositionC)) {          ((TextView) v).setTextColor(ContextCompat.getColor(mContext, R.color.dodgerblue));        } else if (clickpositionC.equals(positionC + "")) {        } else {          ((TextView) v).setTextColor(ContextCompat.getColor(mContext, R.color.dodgerblue));        }      } else {        v.setBackgroundColor(ContextCompat.getColor(mContext, R.color.saddlebrown));        if (TextUtils.isEmpty(clickpositionC)) {          ((TextView) v).setTextColor(ContextCompat.getColor(mContext, R.color.white));        } else if (clickpositionC.equals(positionC + "")) {        } else {          ((TextView) v).setTextColor(ContextCompat.getColor(mContext, R.color.white));        }      }    }  }  /**   * 初始化選項(不可點擊,焦點消失)   */  private void initOptions() {    for (int y = 0; y < childrenViews.length; y++) {      for (int z = 0; z < childrenViews[y].length; z++) {//循環所有屬性        TextView textView = childrenViews[y][z];        textView.setEnabled(false);        textView.setFocusable(false);        textView.setTextColor(ContextCompat.getColor(mContext, R.color.gray));//變灰      }    }  }  /**   * 找到符合條件的選項變為可選   */  private void canClickOptions() {    for (int i = 0; i < childrenViews.length; i++) {      for (int j = 0; j < stockGoodsList.size(); j++) {        boolean filter = false;        List<GoodsAttrsBean.StockGoodsBean.GoodsInfoBean> goodsInfo = stockGoodsList.get(j).getGoodsInfo();        for (int k = 0; k < selectedValue.length; k++) {          if (i == k || TextUtils.isEmpty(selectedValue[k])) {            continue;          }          if (!selectedValue[k].equals(goodsInfo              .get(k).getTabValue())) {            filter = true;            break;          }        }        if (!filter) {          for (int n = 0; n < childrenViews[i].length; n++) {            TextView textView = childrenViews[i][n];//拿到所有屬性TextView            String name = textView.getText().toString();            //拿到屬性名稱            if (goodsInfo.get(i).getTabValue().equals(name)) {              textView.setEnabled(true);//符合就變成可點擊              textView.setFocusable(true); //設置可以獲取焦點              //不要讓焦點亂跑              if (focusPositionG == i && focusPositionC == n) {                textView.setTextColor(ContextCompat.getColor(mContext, R.color.dodgerblue));                textView.requestFocus();              } else {                textView.setTextColor(ContextCompat.getColor(mContext, R.color.white));              }              textView.setOnClickListener(new MyOnClickListener(SELECTED, i, n) {              });              textView.setOnFocusChangeListener(new MyOnFocusChangeListener(i, n) {              });            }          }        }      }    }  }  /**   * 找到已經選中的選項,讓其變紅   */  private void getSelected() {    for (int i = 0; i < childrenViews.length; i++) {      for (int j = 0; j < childrenViews[i].length; j++) {//拿到每行屬性Item        TextView textView = childrenViews[i][j];//拿到所有屬性TextView        String value = textView.getText().toString();        for (int m = 0; m < selectedValue.length; m++) {          if (selectedValue[m].equals(value)) {            textView.setTextColor(ContextCompat.getColor(mContext, R.color.red));            textView.setOnClickListener(new MyOnClickListener(CANCEL, i, j) {            });          }        }      }    }  }}

下載鏈接:

GitHub:地址

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久久久久影院| 成人免费网站在线观看| 国产亚洲欧美aaaa| 亚洲国产精品久久久久秋霞不卡| 欧美激情中文网| 懂色aⅴ精品一区二区三区蜜月| 国产精品福利网| 精品五月天久久| 亚洲国产美女精品久久久久∴| 91色p视频在线| 亚洲性生活视频在线观看| 成人欧美一区二区三区在线| 欧美韩国理论所午夜片917电影| 日韩久久午夜影院| 欧美日韩视频在线| 亚洲国产精品成人精品| 日韩免费高清在线观看| 国产mv久久久| 日韩精品免费综合视频在线播放| 国产成+人+综合+亚洲欧美丁香花| 国产亚洲视频中文字幕视频| 懂色av中文一区二区三区天美| 这里只有精品视频在线| www.xxxx欧美| 26uuu另类亚洲欧美日本一| 国产69精品久久久久久| 81精品国产乱码久久久久久| 国产在线观看一区二区三区| 情事1991在线| 91亚洲国产精品| 国产欧美精品xxxx另类| 久久亚洲成人精品| 欧美另类极品videosbestfree| 欧美丰满片xxx777| 北条麻妃一区二区在线观看| 日韩暖暖在线视频| 久久九九精品99国产精品| 91精品国产综合久久久久久久久| 一区二区三区精品99久久| 国产在线播放不卡| 国产福利精品视频| 欧美日韩性视频在线| 色综合视频网站| 亚洲精品国产综合久久| 在线亚洲午夜片av大片| 国产视频一区在线| 亚洲夜晚福利在线观看| 日韩在线视频观看| 成人在线视频网站| 亚洲综合最新在线| 91九色国产社区在线观看| 91精品国产高清久久久久久91| 国产一区二区丝袜高跟鞋图片| 91国偷自产一区二区三区的观看方式| 日韩在线观看视频免费| 亚洲天堂av在线免费| 日韩av影片在线观看| 久久天天躁狠狠躁夜夜av| 日韩电影中文字幕| 欧美性生交xxxxxdddd| 亚洲欧洲中文天堂| 亚洲一区二区三区四区在线播放| 亚洲在线第一页| 中文字幕亚洲激情| 欧美资源在线观看| 福利视频第一区| 久久免费视频这里只有精品| 黄色成人av在线| 亚洲色在线视频| 一区二区成人精品| 国产精品日韩在线| 日韩av在线影视| 91日本在线视频| 国产日韩视频在线观看| 国产一区二区日韩| 亚洲国模精品私拍| 国产免费观看久久黄| 国产精品视频区1| 欧美日韩国产在线| 国产精品久久99久久| 国产精品亚洲精品| 亚洲国产另类 国产精品国产免费| 91精品国产色综合久久不卡98| 国产精品一区二区三区成人| 日韩高清电影好看的电视剧电影| 国产成人精品最新| 亚洲偷熟乱区亚洲香蕉av| 91久久精品国产91性色| 97精品国产aⅴ7777| 91美女福利视频高清| 亚洲国产成人久久| 色av中文字幕一区| 国产精品视频久久| 亚洲欧美日韩国产中文| 91香蕉国产在线观看| 国产精品久久久久久久天堂| 精品中文字幕在线观看| 日本亚洲欧洲色α| 国产精品激情av在线播放| 最好看的2019的中文字幕视频| 精品久久久免费| 亚洲成人aaa| 日韩69视频在线观看| 亚洲欧美制服中文字幕| 亚洲va码欧洲m码| 2020欧美日韩在线视频| 久久久久国产精品一区| 91免费观看网站| 国产精品福利在线观看网址| 色琪琪综合男人的天堂aⅴ视频| 懂色av一区二区三区| 欧美视频一二三| 久久精品国产2020观看福利| 91成人免费观看网站| 亚洲春色另类小说| 国产日韩综合一区二区性色av| 国产精选久久久久久| 国产精品久久久久久久天堂| 欧美午夜无遮挡| 欧美不卡视频一区发布| 国产精品美女999| 国产亚洲人成a一在线v站| 中文字幕视频在线免费欧美日韩综合在线看| 亚洲一区第一页| 亚洲欧美日韩国产中文专区| 亚洲天堂网站在线观看视频| 亚洲精品久久久久久久久| 欧美成人精品在线视频| 亚洲毛片在线免费观看| 人妖精品videosex性欧美| 热久久美女精品天天吊色| 一区国产精品视频| 亚洲成年人影院在线| 欧美日韩国产一中文字不卡| 亚洲国产精久久久久久久| 中文字幕在线视频日韩| 国产区精品视频| 北条麻妃一区二区三区中文字幕| 亚洲精品久久久久中文字幕欢迎你| 久久久久久有精品国产| 久久久免费精品| 国产一区二区三区久久精品| 九九九热精品免费视频观看网站| 久久久精品2019中文字幕神马| 91网在线免费观看| 欧美精品videossex性护士| 亚洲欧洲国产伦综合| 在线视频日本亚洲性| 亚洲在线观看视频| 日韩在线观看你懂的| xvideos国产精品| 国产精品444| 国产日韩精品综合网站| 美女福利视频一区| 中文字幕久久亚洲| 日韩有码视频在线| 亚洲跨种族黑人xxx| 国外成人在线直播| 亚洲一区中文字幕| 欧美激情区在线播放| 久久成人精品一区二区三区| 久久精品中文字幕电影| 亚洲黄色免费三级| 91中文精品字幕在线视频|