国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > 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開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 惠东县| 柏乡县| 偏关县| 天镇县| 景宁| 金阳县| 荆门市| 广西| 普定县| 长宁县| 伊金霍洛旗| 怀安县| 天长市| 伊金霍洛旗| 乌鲁木齐县| 东丰县| 甘泉县| 龙山县| 上高县| 左云县| 孝感市| 句容市| 江川县| 雷波县| 彭山县| 蒲江县| 商南县| 华宁县| 信丰县| 徐汇区| 萨迦县| 五原县| 桂平市| 平舆县| 涿州市| 白玉县| 凤翔县| 马公市| 星座| 屯留县| 隆化县|