Android 购物选择颜色、尺码实现(二)

    Android 购物选择颜色(尺码)实现(一)这篇文章只是简单的介绍以及实现了点击效果,还没有实现颜色、尺码、库存等联动,所以,在闲暇时间,就写了这篇文章实现这样的效果。首先还是上几张淘宝的效果图:

在选择尺码或者颜色分类的时候,颜色分类、尺码、库存以及图片都会有相应变化。接下来,我们 就看看如何实现这样的效果。先看看我实现的效果图

一.分析

    要实现这样的效果,商品属性就得有,尺码、颜色、库存等,我们简称为sku,当你选择某一个尺码的时候,先查找该颜色对应的尺码列表是什么,接着用这个尺码列表和总的尺码列表进行对比,要是有尺码不在总尺码列表中,那么就标记改尺码是不可选的;颜色也同理。只要你明白这道理,那么就很好理解了。下来我们看看具体的代码实现。

二.实现

1.新建项目;

2.打开布局文件activity_main.xml,该布局文件是主界面布局;

代码就不罗列了,具体代码见代码下载。

 3.在layou文件夹中新建布局gridview_item.xml文件,该布局文件主要是设置GridView的item布局,主要是一个TextView显示商品属性;

PS: 这一块要是不了解的话,可以先看看这篇文章Android 购物选择颜色(尺码)实现(一)

4.新建MyGridView类,继承GridView,解决滑动冲突;

 

/**
 * 滑动冲突
 */
public class MyGridView extends GridView {

	public MyGridView(Context context) {
		super(context);
	}

	public MyGridView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public MyGridView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	@Override
	public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
				MeasureSpec.AT_MOST);
		super.onMeasure(widthMeasureSpec, expandSpec);
	}

	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		if (ev.getAction() == MotionEvent.ACTION_MOVE) {
			return true;
		}
		return super.dispatchTouchEvent(ev);
	}

}

5.新建SkuAdapter ,继承BaseAdapter,其中用到的接口回调;

 

 

public class SkuAdapter extends BaseAdapter {
	private List<Bean> list;//数据源
	private LayoutInflater mInflater;// 得到一个LayoutInfalter对象用来导入布局
	public onItemClickListener itemClickListener;// 接口回调

	public void setItemClickListener(onItemClickListener itemClickListener) {
		this.itemClickListener = itemClickListener;
	}

	public SkuAdapter(List<Bean> list, Context context) {
		super();
		this.mInflater = LayoutInflater.from(context);
		this.list = list;
	}

	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return list.size();
	}

	@Override
	public Object getItem(int position) {
		// TODO Auto-generated method stub
		return list.get(position);
	}

	@Override
	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return position;
	}

	@Override
	public View getView(final int position, View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		ViewHolder holder;
		if (convertView == null) {
			holder = new ViewHolder();
			convertView = mInflater.inflate(R.layout.gridview_item, null);
			/** 得到各个控件的对象 */
			holder.title = (TextView) convertView.findViewById(R.id.ItemText);
			holder.layout = (LinearLayout) convertView.findViewById(R.id.layout);
			convertView.setTag(holder);// 绑定ViewHolder对象
		} else {
			holder = (ViewHolder) convertView.getTag();// 取出ViewHolder对象
		}
		final Bean bean = list.get(position);
	
		switch (bean.getStates()) {
		// 选中
		case "0":
			holder.layout.setBackgroundResource(R.xml.shape2);
			holder.title.setTextColor(Color.WHITE);
			break;
		// 未选中
		case "1":
			holder.layout.setBackgroundResource(R.xml.shape1);
			holder.title.setTextColor(Color.BLACK);
			break;
		// 不可选
		case "2":
			holder.layout.setBackgroundResource(R.xml.shape1);
			holder.title.setTextColor(Color.parseColor("#999999"));
			break;
		default:
			break;
		}
		/** 设置TextView显示的内容,即我们存放在动态数组中的数据 */
		holder.title.setText(bean.getName());
		holder.layout.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				if (itemClickListener != null) {
					if(!bean.getStates().equals("2")){
						itemClickListener.onItemClick(bean, position);
					}
				}
			}
		});
		return convertView;
	}

	public final class ViewHolder {
		public TextView title;
		public LinearLayout layout;
	}

	public interface onItemClickListener {
		public void onItemClick(Bean bean, int position);
	}
}

 

6.新建Constants 类(当然你也可以自己在Activity中定义常量);

 

public class Constants {
	//颜色数组
	public static final String[] colorArr={"铁蓝灰","孔雀蓝","深蓝","中国红","艳紫"};
	//尺码数组
	public static final String[] sizeArr={"S","M","L","XL","XXL","XXXL"};
}

7.新建DataUtil,用来数据处理,代码太长,就不讲解了,具体的代码,请下载代码后,查看;
8.最主要的类,MainActivity,该类包含了所有的实现,代码如下;

 

 

public class MainActivity extends Activity {

	List<SkuItme> mList;// sku数据

	List<Bean> mColorList;// 颜色列表
	List<Bean> mSizeList;// 尺码列表
	GridView gvColor;// 颜色
	GridView gvSize;// 尺码
	SkuAdapter skuColorAdapter;// 颜色适配器
	SkuAdapter skuSizeAdapter;// 尺码适配器
	String color;//
	String size;//
	TextView tvSkuName;// 显示sku
	TextView tvSkuStock;// 显示库存
	int stock = 0;// 库存

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		gvSize = (GridView) findViewById(R.id.gv_size);
		gvColor = (GridView) findViewById(R.id.gv_color);
		tvSkuName = (TextView) findViewById(R.id.tv_sku);
		tvSkuStock = (TextView) findViewById(R.id.tv_sku_stock);
		addData();
		stock = DataUtil.getAllStock(mList);
		if (stock > 0) {
			tvSkuStock.setText("库存:" + stock + "");
		}
		skuColorAdapter = new SkuAdapter(mColorList, this);
		gvColor.setAdapter(skuColorAdapter);
		skuColorAdapter.setItemClickListener(new onItemClickListener() {

			@Override
			public void onItemClick(Bean bean, int position) {
				// TODO Auto-generated method stub
				color = bean.getName();
				switch (bean.getStates()) {
				case "0":
					// 清空尺码
					mSizeList=DataUtil.clearAdapterStates(mSizeList);
					skuSizeAdapter.notifyDataSetChanged();
					// 清空颜色
					mColorList=DataUtil.clearAdapterStates(mColorList);
					skuColorAdapter.notifyDataSetChanged();
					color = "";
					// 判断使用选中了尺码
					if (!TextUtils.isEmpty(size)) {
						// 选中尺码,计算库存
						stock =DataUtil.getSizeAllStock(mList,size);
						if (stock > 0) {
							tvSkuStock.setText("库存:" + stock + "");
						}
						tvSkuName.setText("请选择尺码");
						// 获取该尺码对应的颜色列表
						List<String> list = DataUtil.getColorListBySize(mList,size);
						if (list != null && list.size() > 0) {
							// 更新颜色列表
							mColorList = DataUtil.setSizeOrColorListStates(mColorList,list, color);
							skuColorAdapter.notifyDataSetChanged();
						}
						mSizeList=DataUtil.setAdapterStates(mSizeList,size);
						skuSizeAdapter.notifyDataSetChanged();
					} else {
						// 所有库存
						stock = DataUtil.getAllStock(mList);
						if (stock > 0) {
							tvSkuStock.setText("库存:" + stock + "");
						}
						tvSkuName.setText("请选择尺码,颜色分类");
					}
					break;
				case "1":
					// 选中颜色
					mColorList=DataUtil.updateAdapterStates(mColorList,"0", position);
					skuColorAdapter.notifyDataSetChanged();
					// 计算改颜色对应的尺码列表
					List<String> list = DataUtil.getSizeListByColor(mList,color);
					if (!TextUtils.isEmpty(size)) {
						// 计算改颜色与尺码对应的库存
						stock = DataUtil.getStockByColorAndSize(mList,color, size);
						tvSkuName.setText("规格:" + color + " " + size);
						if (stock > 0) {
							tvSkuStock.setText("库存:" + stock + "");
						}
						if (list != null && list.size() > 0) {
							// 更新尺码列表
							mSizeList = DataUtil.setSizeOrColorListStates(mSizeList,list, size);
							skuSizeAdapter.notifyDataSetChanged();
						}
					} else {
						// 根据颜色计算库存
						stock = DataUtil.getColorAllStock(mList,color);
						if (stock > 0) {
							tvSkuStock.setText("库存:" + stock + "");
						}
						tvSkuName.setText("请选择尺码");
						if (list != null && list.size() > 0) {
							// 更新尺码列表
							mSizeList = DataUtil.setSizeOrColorListStates(mSizeList,list, "");
							skuSizeAdapter.notifyDataSetChanged();
						}
					}
					break;
				default:
					break;
				}
			}
		});

		skuSizeAdapter = new SkuAdapter(mSizeList, this);
		gvSize.setAdapter(skuSizeAdapter);
		skuSizeAdapter.setItemClickListener(new onItemClickListener() {

			@Override
			public void onItemClick(Bean bean, int position) {
				// TODO Auto-generated method stub
				size = bean.getName();
				switch (bean.getStates()) {
				case "0":
					// 清空尺码
					mSizeList=DataUtil.clearAdapterStates(mSizeList);
					skuSizeAdapter.notifyDataSetChanged();
					// 清空颜色
					mColorList=DataUtil.clearAdapterStates(mColorList);
					skuColorAdapter.notifyDataSetChanged();
					size = "";
					if (!TextUtils.isEmpty(color)) {
						// 计算改颜色对应的所有库存
						stock = DataUtil.getColorAllStock(mList,color);
						if (stock > 0) {
							tvSkuStock.setText("库存:" + stock + "");
						}
						tvSkuName.setText("请选择尺码");
						// 计算改颜色对应的尺码列表
						List<String> list = DataUtil.getSizeListByColor(mList,color);
						if (list != null && list.size() > 0) {
							// 更新尺码列表
							mSizeList = DataUtil.setSizeOrColorListStates(mSizeList,list, size);
							skuSizeAdapter.notifyDataSetChanged();
						}
						mColorList=DataUtil.setAdapterStates(mColorList,color);
						skuColorAdapter.notifyDataSetChanged();
					} else {
						// 获取所有库存
						stock = DataUtil.getAllStock(mList);
						if (stock > 0) {
							tvSkuStock.setText("库存:" + stock + "");
						}
						tvSkuName.setText("请选择尺码,颜色分类");
					}
					break;
				case "1":
					// 选中尺码
					mSizeList=DataUtil.updateAdapterStates(mSizeList, "0", position);
					skuSizeAdapter.notifyDataSetChanged();
					// 获取该尺码对应的颜色列表
					List<String> list = DataUtil.getColorListBySize(mList,size);
					if (!TextUtils.isEmpty(color)) {
						// 计算改颜色与尺码对应的库存
						stock = DataUtil.getStockByColorAndSize(mList,color, size);
						tvSkuName.setText("规格:" + color + " " + size);
						if (stock > 0) {
							tvSkuStock.setText("库存:" + stock + "");
						}
						if (list != null && list.size() > 0) {
							// 更新颜色列表
							mColorList = DataUtil.setSizeOrColorListStates(mColorList,list, color);
							skuColorAdapter.notifyDataSetChanged();
						}
					} else {
						// 计算改尺码的所有库存
						stock = DataUtil.getSizeAllStock(mList,size);
						if (stock > 0) {
							tvSkuStock.setText("库存:" + stock + "");
						}
						tvSkuName.setText("请选择颜色分类");
						if (list != null && list.size() > 0) {
							mColorList =  DataUtil.setSizeOrColorListStates(mColorList,list, "");
							skuColorAdapter.notifyDataSetChanged();
						}
					}
					break;
				default:
					break;
				}
			}
		});
	}



	
	/**
	 * 模拟数据
	 */
	private void addData() {
		mList = new ArrayList<SkuItme>();
		mColorList = new ArrayList<Bean>();
		mSizeList = new ArrayList<Bean>();
		String[] colorArr = Constants.colorArr;
		String[] sizeArr = Constants.sizeArr;
		int color = colorArr.length;
		int size = sizeArr.length;

		for (int i = 0; i < color; i++) {
			Bean bean = new Bean();
			bean.setName(colorArr[i]);
			bean.setStates("1");
			mColorList.add(bean);
		}
		for (int i = 0; i < size; i++) {
			Bean bean = new Bean();
			bean.setName(sizeArr[i]);
			bean.setStates("1");
			mSizeList.add(bean);
		}

		String color0 = colorArr[0];
		String size0 = sizeArr[0];
		String color1 = colorArr[1];
		String size1 = sizeArr[1];
		String color2 = colorArr[2];
		String size2 = sizeArr[2];
		String color3 = colorArr[3];
		String size3 = sizeArr[3];
		String color4 = colorArr[4];
		String size4 = sizeArr[4];
		String size5 = sizeArr[5];
		SkuItme item0 = new SkuItme();
		item0.setId("1");
		item0.setSkuColor(color0);
		item0.setSkuSize(size0);
		item0.setSkuStock(10);
		mList.add(item0);
		SkuItme item1 = new SkuItme();
		item1.setId("2");
		item1.setSkuColor(color0);
		item1.setSkuSize(size1);
		item1.setSkuStock(1);
		mList.add(item1);
		SkuItme item2 = new SkuItme();
		item2.setId("3");
		item2.setSkuColor(color1);
		item2.setSkuSize(size0);
		item2.setSkuStock(12);
		mList.add(item2);
		SkuItme item3 = new SkuItme();
		item3.setId("4");
		item3.setSkuColor(color1);
		item3.setSkuSize(size2);
		item3.setSkuStock(123);
		mList.add(item3);
		SkuItme item4 = new SkuItme();
		item4.setId("5");
		item4.setSkuColor(color1);
		item4.setSkuSize(size1);
		item4.setSkuStock(53);
		mList.add(item4);
		SkuItme item5 = new SkuItme();
		item5.setId("6");
		item5.setSkuColor(color2);
		item5.setSkuSize(size1);
		item5.setSkuStock(13);
		mList.add(item5);
		SkuItme item6 = new SkuItme();
		item6.setId("7");
		item6.setSkuColor(color0);
		item6.setSkuSize(size3);
		item6.setSkuStock(18);
		mList.add(item6);
		SkuItme item7 = new SkuItme();
		item7.setId("8");
		item7.setSkuColor(color2);
		item7.setSkuSize(size3);
		item7.setSkuStock(14);
		mList.add(item7);
		SkuItme item8 = new SkuItme();
		item8.setId("9");
		item8.setSkuColor(color1);
		item8.setSkuSize(size3);
		item8.setSkuStock(22);
		mList.add(item8);
		SkuItme item9 = new SkuItme();
		item9.setId("10");
		item9.setSkuColor(color0);
		item9.setSkuSize(size4);
		item9.setSkuStock(29);
		mList.add(item9);
		SkuItme item10 = new SkuItme();
		item10.setId("11");
		item10.setSkuColor(color2);
		item10.setSkuSize(size5);
		item10.setSkuStock(64);
		mList.add(item10);
		SkuItme item11 = new SkuItme();
		item11.setId("12");
		item11.setSkuColor(color3);
		item11.setSkuSize(size2);
		item11.setSkuStock(70);
		mList.add(item11);
		SkuItme item12 = new SkuItme();
		item12.setId("13");
		item12.setSkuColor(color4);
		item12.setSkuSize(size0);
		item12.setSkuStock(80);
		mList.add(item12);
		SkuItme item13 = new SkuItme();
		item13.setId("14");
		item13.setSkuColor(color3);
		item13.setSkuSize(size4);
		item13.setSkuStock(35);
		mList.add(item13);
		SkuItme item14 = new SkuItme();
		item14.setId("15");
		item14.setSkuColor(color4);
		item14.setSkuSize(size1);
		item14.setSkuStock(62);
		mList.add(item14);
		SkuItme item15 = new SkuItme();
		item15.setId("16");
		item15.setSkuColor(color3);
		item15.setSkuSize(size5);
		item15.setSkuStock(41);
		mList.add(item15);
		SkuItme item16 = new SkuItme();
		item16.setId("17");
		item16.setSkuColor(color1);
		item16.setSkuSize(size5);
		item16.setSkuStock(39);
		mList.add(item16);
		SkuItme item17 = new SkuItme();
		item17.setId("18");
		item17.setSkuColor(color4);
		item17.setSkuSize(size5);
		item17.setSkuStock(37);
		mList.add(item17);
		SkuItme item18 = new SkuItme();
		item18.setId("19");
		item18.setSkuColor(color4);
		item18.setSkuSize(size2);
		item18.setSkuStock(44);
		mList.add(item18);
		SkuItme item19 = new SkuItme();
		item19.setId("20");
		item19.setSkuColor(color4);
		item19.setSkuSize(size3);
		item19.setSkuStock(61);
		mList.add(item19);
	}
}
这样,我们就基本可以实现类似淘宝选择颜色尺码的效果了。效果看着还不错!O(∩_∩)O~!

 

三.我的项目分析说明

   1. 首先来张项目结构图

(1).Bean类是适配器的数据实体,它的属性有

 

private String name;//名称
private String states;//状态 3种  1 选中  2 未选中 3不可选

name即具体的尺码或者颜色,states是用来标识目前状态是什么。

 

(2).Constants 常量类,保存了数据源

 

//颜色数组
public static final String[] colorArr={"铁蓝灰","孔雀蓝","深蓝","中国红","艳紫"};
//尺码数组
public static final String[] sizeArr={"S","M","L","XL","XXL","XXXL"};

 

(3).SkuItme sku的数据实体类

 

private String id;//id
private String skuSize;//尺码
private String skuColor;//颜色
private int skuStock;//库存
private String skuIamgeUrl;//图片路径

(4).MyGridView  解决GridView和ScrollView滑动冲突

 

(5).SkuAdapter 适配器,显示尺码或者颜色分类

(6).DataUtil 数据处理类

     相信大家看完这篇文章,就或许有思路,实现类似淘宝的选择颜色、尺码效果了!

   (本人水平有限,有错误的地方,欢迎大家指出)

    PS:代码下载
 

欢迎大家关注我的公众号


 

 
  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
实现一个自定义控件来实现Android网格选择颜色,可以按照以下步骤进行: 1. 创建一个继承自View或其子类的自定义控件类,例如ColorGridView。 2. 在该类中添加必要的属性,例如颜色数组、列数等。 3. 重写onMeasure方法,计算控件的大小。 4. 重写onDraw方法,在控件内绘制颜色格子。 5. 处理触摸事件,当用户点击某个颜色格子时,将该格子的颜色作为选择结果返回。 6. (可选)添加其他交互功能,例如滑动、长按等。 以下是一个简单的实现示例: ``` public class ColorGridView extends View { private int[] colors; private int columnCount; private int selectedColor; public ColorGridView(Context context) { super(context); init(null, 0); } public ColorGridView(Context context, AttributeSet attrs) { super(context, attrs); init(attrs, 0); } public ColorGridView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(attrs, defStyle); } private void init(AttributeSet attrs, int defStyle) { // 初始化属性 TypedArray a = getContext().obtainStyledAttributes( attrs, R.styleable.ColorGridView, defStyle, 0); // 读取颜色数组 int colorsId = a.getResourceId(R.styleable.ColorGridView_colors, 0); if (colorsId != 0) { TypedArray colorsArray = getResources().obtainTypedArray(colorsId); colors = new int[colorsArray.length()]; for (int i = 0; i < colorsArray.length(); i++) { colors[i] = colorsArray.getColor(i, 0); } colorsArray.recycle(); } // 读取列数 columnCount = a.getInt(R.styleable.ColorGridView_columnCount, 4); a.recycle(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // 计算控件大小 int width = MeasureSpec.getSize(widthMeasureSpec); int height = (colors.length / columnCount + 1) * width / columnCount; setMeasuredDimension(width, height); } @Override protected void onDraw(Canvas canvas) { // 绘制颜色格子 int width = getWidth() / columnCount; int height = width; Paint paint = new Paint(); for (int i = 0; i < colors.length; i++) { int x = (i % columnCount) * width; int y = (i / columnCount) * height; paint.setColor(colors[i]); canvas.drawRect(x, y, x + width, y + height, paint); } } @Override public boolean onTouchEvent(MotionEvent event) { // 处理触摸事件 if (event.getAction() == MotionEvent.ACTION_DOWN) { int x = (int) event.getX(); int y = (int) event.getY(); int index = (y / (getWidth() / columnCount)) * columnCount + x / (getWidth() / columnCount); if (index < colors.length) { selectedColor = colors[index]; invalidate(); return true; } } return super.onTouchEvent(event); } public int getSelectedColor() { return selectedColor; } } ``` 在布局文件中可以这样使用: ``` <com.example.ColorGridView android:id="@+id/color_grid_view" android:layout_width="match_parent" android:layout_height="wrap_content" app:colors="@array/colors" app:columnCount="4" /> ``` 其中,colors和columnCount是自定义属性,可以在res/values/attrs.xml文件中定义: ``` <declare-styleable name="ColorGridView"> <attr name="colors" format="reference" /> <attr name="columnCount" format="integer" /> </declare-styleable> ``` 这样,就可以通过ColorGridView控件来实现Android网格选择颜色了。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值