文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android实现淘宝选中商品尺寸的按钮组实例

2022-06-06 07:43

关注

话不多说,先上个效果图:

现在我们就来说说里面的一些原理把!

一、原理:

1.其实这里我们用到的是一个

ViewGroup
控件组,把这些按钮加进去就有这种效果了!不过这里要继承
ViewGroup
(命名为:
GoodsViewGroup
)重写里面的一些方法。

2.主要的方法有:

GoodsViewGroup按钮组的控件大小


protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)

里面的按钮每个的位置坐标


protected void onLayout(boolean changed, int l, int t, int r, int b) 

这两个方法的具体使用大家可以网上查阅资料,这里就不多说了!

二、代码:



public class GoodsViewGroup<X extends TextView> extends ViewGroup {
 public static final String BTN_MODE = "BTNMODE"; //按钮模式
 public static final String TEV_MODE = "TEVMODE"; //文本模式
 private static final String TAG = "IViewGroup";
 private final int HorInterval = 10; //水平间隔
 private final int VerInterval = 10; //垂直间隔
 private int viewWidth; //控件的宽度
 private int viewHeight; //控件的高度
 private ArrayList<String> mTexts = new ArrayList<>();
 private Context mContext;
 private int textModePadding = 15;
 //正常样式
 private float itemTextSize = 18;
 private int itemBGResNor = R.drawable.goods_item_btn_normal;
 private int itemTextColorNor = Color.parseColor("#000000");
 //选中的样式
 private int itemBGResPre = R.drawable.goods_item_btn_selected;
 private int itemTextColorPre = Color.parseColor("#ffffff");
 public GoodsViewGroup(Context context) {
  this(context, null);
 }
 public GoodsViewGroup(Context context, AttributeSet attrs) {
  super(context, attrs);
  mContext = context;
 }
 
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  viewWidth = measureWidth(widthMeasureSpec);
  viewHeight = measureHeight(heightMeasureSpec);
  Log.e(TAG, "onMeasure:" + viewWidth + ":" + viewHeight);
  // 计算自定义的ViewGroup中所有子控件的大小
  measureChildren(widthMeasureSpec, heightMeasureSpec);
  // 设置自定义的控件MyViewGroup的大小
  setMeasuredDimension(viewWidth, getViewHeight());
 }
 private int measureWidth(int pWidthMeasureSpec) {
  int result = 0;
  int widthMode = MeasureSpec.getMode(pWidthMeasureSpec);
  int widthSize = MeasureSpec.getSize(pWidthMeasureSpec);
  switch (widthMode) {
   
   case MeasureSpec.AT_MOST:
   case MeasureSpec.EXACTLY:
    result = widthSize;
    break;
  }
  return result;
 }
 private int measureHeight(int pHeightMeasureSpec) {
  int result = 0;
  int heightMode = MeasureSpec.getMode(pHeightMeasureSpec);
  int heightSize = MeasureSpec.getSize(pHeightMeasureSpec);
  switch (heightMode) {
   case MeasureSpec.UNSPECIFIED:
    result = getSuggestedMinimumHeight();
    break;
   case MeasureSpec.AT_MOST:
   case MeasureSpec.EXACTLY:
    result = heightSize;
    break;
  }
  return result;
 }
 
 @Override
 protected void onLayout(boolean changed, int l, int t, int r, int b) {
  // 遍历所有子视图
  int posLeft = HorInterval;
  int posTop = VerInterval;
  int posRight;
  int posBottom;
  for (int i = 0; i < getChildCount(); i++) {
   View childView = getChildAt(i);
   // 获取在onMeasure中计算的视图尺寸
   int measureHeight = childView.getMeasuredHeight();
   int measuredWidth = childView.getMeasuredWidth();
   if (posLeft + getNextHorLastPos(i) > viewWidth) {
    posLeft = HorInterval;
    posTop += (measureHeight + VerInterval);
   }
   posRight = posLeft + measuredWidth;
   posBottom = posTop + measureHeight;
   childView.layout(posLeft, posTop, posRight, posBottom);
   posLeft += (measuredWidth + HorInterval);
  }
 }
 //获取控件的自适应高度
 private int getViewHeight() {
  int viewwidth = HorInterval;
  int viewheight = VerInterval;
  if (getChildCount() > 0) {
   viewheight = getChildAt(0).getMeasuredHeight() + VerInterval;
  }
  for (int i = 0; i < getChildCount(); i++) {
   View childView = getChildAt(i);
   // 获取在onMeasure中计算的视图尺寸
   int measureHeight = childView.getMeasuredHeight();
   int measuredWidth = childView.getMeasuredWidth();
   if (viewwidth + getNextHorLastPos(i) > viewWidth) {
    viewwidth = HorInterval;
    viewheight += (measureHeight + VerInterval);
   } else {
    viewwidth += (measuredWidth + HorInterval);
   }
  }
  return viewheight;
 }
 private int getNextHorLastPos(int i) {
  return getChildAt(i).getMeasuredWidth() + HorInterval;
 }
 private OnGroupItemClickListener onGroupItemClickListener;
 public void setGroupClickListener(OnGroupItemClickListener listener) {
  onGroupItemClickListener = listener;
  for (int i = 0; i < getChildCount(); i++) {
   final X childView = (X) getChildAt(i);
   final int itemPos = i;
   childView.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
     onGroupItemClickListener.onGroupItemClick(itemPos);
     chooseItemStyle(itemPos);
    }
   });
  }
 }
 //选中那个的样式
 public void chooseItemStyle(int pos) {
  clearItemsStyle();
  if (pos < getChildCount()) {
   X childView = (X) getChildAt(pos);
   childView.setBackgroundResource(itemBGResPre);
   childView.setTextColor(itemTextColorPre);
   setItemPadding(childView);
  }
 }
 private void setItemPadding(X view) {
  if (view instanceof Button) {
   view.setPadding(textModePadding, 0, textModePadding, 0);
  } else {
   view.setPadding(textModePadding, textModePadding, textModePadding, textModePadding);
  }
 }
 //清除Group所有的样式
 private void clearItemsStyle() {
  for (int i = 0; i < getChildCount(); i++) {
   X childView = (X) getChildAt(i);
   childView.setBackgroundResource(itemBGResNor);
   childView.setTextColor(itemTextColorNor);
   setItemPadding(childView);
  }
 }
 public void addItemViews(ArrayList<String> texts, String mode) {
  mTexts = texts;
  removeAllViews();
  for (String text : texts) {
   addItemView(text, mode);
  }
 }
 private void addItemView(String text, String mode) {
  X childView = null;
  switch (mode) {
   case BTN_MODE:
    childView = (X) new Button(mContext);
    break;
   case TEV_MODE:
    childView = (X) new TextView(mContext);
    break;
  }
  childView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
    LayoutParams.WRAP_CONTENT));
  childView.setTextSize(itemTextSize);
  childView.setBackgroundResource(itemBGResNor);
  setItemPadding(childView);
  childView.setTextColor(itemTextColorNor);
  childView.setText(text);
  this.addView(childView);
 }
 public String getChooseText(int itemID) {
  if (itemID >= 0) {
   return mTexts.get(itemID);
  }
  return null;
 }
 public void setItemTextSize(float itemTextSize) {
  this.itemTextSize = itemTextSize;
 }
 public void setItemBGResNor(int itemBGResNor) {
  this.itemBGResNor = itemBGResNor;
 }
 public void setItemTextColorNor(int itemTextColorNor) {
  this.itemTextColorNor = itemTextColorNor;
 }
 public void setItemBGResPre(int itemBGResPre) {
  this.itemBGResPre = itemBGResPre;
 }
 public void setItemTextColorPre(int itemTextColorPre) {
  this.itemTextColorPre = itemTextColorPre;
 }
 public interface OnGroupItemClickListener {
  void onGroupItemClick(int item);
 }
}

上面提供了可以设置按钮组的item的一些样式,还有这个

GoodsViewGroup
为什么要写成
GoodsViewGroup<X extends TextView>
这样呢?其实这里我是想做一个泛型,可以使用与
Button
TextView
,而这里的
Button
本生就是继承
TextView
所以在代码中还要进行一个判断,可以看上面方法
setItemPadding(X view) 
。那到了这里,有些好友可能就会问,为什么要搞两个呢?

其实这里因为

TextView
的不会自动有设置
padding
的,而
button
是有自动设置
padding
。这个时候你就要看看你是先要那种效果!不过通过我的代码中如果是选择
TextView
的话,这里也设置了一个
padding
给他,不然会很难看!

两种模式的写法:

1.Button :


GoodsViewGroup<Button> mGroup;
mGroup.addItemViews(viewtexts, GoodsViewGroup.BTN_MODE);

2.TextView


GoodsViewGroup<TextView> mGroup;
mGroup.addItemViews(viewtexts, GoodsViewGroup.TEV_MODE);

三、Drawable文件:上面涉及到的按钮选中与正常的两个Drawable

1.goods_item_btn_normal.xml


<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
 <item>
  <shape>
   <solid android:color="#F5F5F5" />
   <corners android:radius="15.0dip" />
  </shape>
 </item>
</layer-list>

2.goods_item_btn_selected.xml


<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
 <item>
  <shape>
   <solid android:color="#FE4F00" />
   <corners android:radius="15.0dip" />
  </shape>
 </item>
</layer-list>

四、例子:

ButtonGroupActivity



public class ButtonGroupActivity extends Activity implements GoodsViewGroup.OnGroupItemClickListener, View.OnClickListener {
 private GoodsViewGroup<TextView> mGroup;
 private Button mSubmitBtn;
 private ArrayList<String> viewtexts = new ArrayList<>();
 private int chooseID = -1;
 private String chooseText;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  setContentView(R.layout.activity_buttongroup);
  mGroup = (GoodsViewGroup) findViewById(R.id.viewGroup);
  mSubmitBtn = (Button) findViewById(R.id.submitBtn);
  String text;
  for (int i = 0; i < 10; i++) {
   text = "L" + i;
   viewtexts.add(text);
  }
  mGroup.addItemViews(viewtexts, GoodsViewGroup.TEV_MODE);
  mGroup.setGroupClickListener(this);
  mSubmitBtn.setOnClickListener(this);
  super.onCreate(savedInstanceState);
 }
 @Override
 public void onGroupItemClick(int item) {
  chooseID = item;
  chooseText = mGroup.getChooseText(item);
 }
 @Override
 public void onClick(View view) {
  if (chooseID >= 0) {
   showToast("ID:" + chooseID + ";text:" + chooseText);
  } else {
   showToast("请选择");
  }
 }
 private void showToast(String text) {
  Toast.makeText(ButtonGroupActivity.this, text, Toast.LENGTH_SHORT).show();
 }
}

activity_buttongroup.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/linear_ayout"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical">
 <com.example.jisuanqi.GoodsViewGroup
  android:id="@+id/viewGroup"
  android:layout_width="match_parent"
  android:layout_height="wrap_content">
 </com.example.jisuanqi.GoodsViewGroup>
 <Button
  android:id="@+id/submitBtn"
  android:text="确定"
  android:layout_width="match_parent"
  android:layout_height="wrap_content" />
</LinearLayout>

总结

以上就是关于Android实现淘宝选中商品不同尺寸的按钮组的全部内容了,如果本文有什么问题欢迎大家指出,大家共同进步!希望本文对大家的学习和工作能有所帮助哦~

您可能感兴趣的文章:Android仿美团下拉菜单(商品选购)实例代码Android实现仿淘宝购物车增加和减少商品数量功能demo示例Android仿淘宝商品浏览界面图片滚动效果Android 仿淘宝、京东商品详情页向上拖动查看图文详情控件DEMO详解Android把商品添加到购物车的动画效果(贝塞尔曲线)Android自定义商品购买数量加减控件安卓(android)仿电商app商品详情页按钮浮动效果Android 仿京东、拼多多商品分类页的示例代码Android 仿淘宝商品属性标签页android仿京东商品属性筛选功能


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯