Android gridview keep item selected

1.ImageView在GridView,listView中设置selector,但是在Adapter的getView设置setSelected(true),imageView显示不是对应的图片(下面仅以GridView为例子):

原因分析:

        因为ImageView作为getView的返回值给GridView,GridView源码对imageView做了setSelecte(false)处理,导致我们的操作无效,这个可以验证:

			imageView.setSelected(mSelectColor == Color.parseColor(data));
			imageView.setScaleType(ScaleType.CENTER_INSIDE);
			imageView.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					mSelectColor = Color.parseColor(data);
					notifyDataSetChanged();
					imageView.postDelayed(new Runnable() {
						@Override
						public void run() {
							Log.d(TAG, "imageView.isSelected_onClick:" +imageView.isSelected()+" "
									+imageView.isActivated()
									);
						}
					}, 5000);
					
				}
			});


以上代码在GridView的Adapter的getView方法中,其点击时记录选定的颜色,在通知adapter刷新,在后面延时5秒检测imgeView的select状态,打印却是false;getView已经置selected为true了,只有可能gridview或者gridview的adapter对imageview又置为false了。

解决方法:

法1:用setActivated代替setSelected实现效果:

			StateListDrawable stateListDrawable = new StateListDrawable();
			stateListDrawable.addState(new int[] { android.R.attr.state_pressed }, layerDrawableSel);
			stateListDrawable.addState(new int[] { android.R.attr.state_selected }, layerDrawableSel);
			stateListDrawable.addState(new int[] { android.R.attr.state_activated }, layerDrawableSel);
			stateListDrawable.addState(new int[] {}, layerDrawableUnsel);
			imageView.setImageDrawable(stateListDrawable);
			imageView.setActivated(mSelectColor == Color.parseColor(data));
			imageView.setScaleType(ScaleType.CENTER_INSIDE);
			imageView.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					mSelectColor = Color.parseColor(data);
					notifyDataSetChanged();
					imageView.postDelayed(new Runnable() {
						@Override
						public void run() {
							Log.d(TAG, "imageView.isSelected_onClick:" +imageView.isSelected()+" "
									+imageView.isActivated()
									);
						}
					}, 5000);
					
				}

法2:在imageView外面套一层Relativelayout之类的container,gridview设置selected针对于relativelayout而不是imageview了,充当挡箭牌的角色。

public View getView(int position, View convertView, ViewGroup parent) {
			RelativeLayout relativeLayout;
			
			final ImageView imageView;
			final String data = getItem(position);
			int width = 132;
			int height = 281;
			int col = pop_gv.getNumColumns();
			int row = getCount() % pop_gv.getNumColumns() == 0 ? getCount() / pop_gv.getNumColumns() : getCount()
					/ pop_gv.getNumColumns() + 1;
			int width_item = (width - (col - 1) * pop_gv.getHorizontalSpacing()) / col;
			int height_item = (height - (row - 1) * pop_gv.getVerticalSpacing()) / row;
			Log.d(TAG, "width_item:" + width_item + " height_item:" + height_item);
			if (convertView == null) {
				relativeLayout = new RelativeLayout(parent.getContext()); 
				imageView = new ImageView(parent.getContext());
				RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(width_item, height_item);
				relativeLayout.addView(imageView, lp);
			} else {
				relativeLayout = (RelativeLayout) convertView;
				imageView = (ImageView) relativeLayout.getChildAt(0);
			}
			Log.d(TAG, "imageView.getDrawable() == null:" + (imageView.getDrawable() == null)+" position:"+position);
			if (imageView.getDrawable() == null) {
				int out_radius = 8;
				int strokeWidth = 3;
				int out_radius_2 = 5;
				ShapeDrawable backGroundDrawable = null;
				float[] outerR = new float[] { out_radius, out_radius, out_radius, out_radius, out_radius, out_radius,
						out_radius, out_radius };
				RoundRectShape s = new RoundRectShape(outerR, null, null);
				backGroundDrawable = new ShapeDrawable(s);
				backGroundDrawable.setIntrinsicWidth(width_item);
				backGroundDrawable.setIntrinsicHeight(height_item);
				backGroundDrawable.getPaint().setStrokeWidth(strokeWidth);
				backGroundDrawable.getPaint().setColor(Color.parseColor(data));
				backGroundDrawable.getPaint().setStyle(Paint.Style.STROKE);
				float[] outerR_2 = new float[] { out_radius_2, out_radius_2, out_radius_2, out_radius_2, out_radius_2,
						out_radius_2, out_radius_2, out_radius_2 };
				RoundRectShape s2 = new RoundRectShape(outerR_2, null, null);
				ShapeDrawable shapeDrawable = new ShapeDrawable(s2);
				shapeDrawable.setIntrinsicWidth(width_item - 16);
				shapeDrawable.setIntrinsicHeight(height_item - 16);
				shapeDrawable.getPaint().setColor(Color.parseColor(data));
				shapeDrawable.getPaint().setStyle(Paint.Style.FILL);
				LayerDrawable layerDrawableSel = new LayerDrawable(new Drawable[] { backGroundDrawable, shapeDrawable });
				layerDrawableSel.setLayerInset(1, 8, 8, 8, 8);
				LayerDrawable layerDrawableUnsel = new LayerDrawable(new Drawable[] { shapeDrawable });
				layerDrawableUnsel.setLayerInset(0, 8, 8, 8, 8);
				StateListDrawable stateListDrawable = new StateListDrawable();
				stateListDrawable.addState(new int[] { android.R.attr.state_pressed }, layerDrawableSel);
				stateListDrawable.addState(new int[] { android.R.attr.state_selected }, layerDrawableSel);
				stateListDrawable.addState(new int[] {}, layerDrawableUnsel);
				imageView.setImageDrawable(stateListDrawable);
			}
			imageView.setSelected(mSelectColor == Color.parseColor(data));
			Log.d(TAG, "imageView.isSelected:" + imageView.isSelected()+" position:"+position);
			imageView.setScaleType(ScaleType.CENTER_INSIDE);
			imageView.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					mSelectColor = Color.parseColor(data);
					notifyDataSetChanged();
				}
			});
			return relativeLayout;
}

更多GridView,ListView导致View设置chekced,pressed异常可能也是这种原因,待验证。。。

2.代码实现Selector

		int width_item = 200;
		int height_item = 200;
		final ImageView imageView = new ImageView(this);
		FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(width_item, height_item);
		lp.gravity = Gravity.CENTER;
		int out_radius = 8;
		int strokeWidth = 3;
		int out_radius_2 = 5;
		//		GradientDrawable bgGradientDrawable = new GradientDrawable();
		//		bgGradientDrawable.setSize(width_item, height_item);
		//		bgGradientDrawable.setStroke(strokeWidth, Color.parseColor("#ff0000"));
		//		float[] outerR = new float[] { out_radius, out_radius, out_radius, out_radius, out_radius, out_radius,
		//				out_radius, out_radius };
		//		bgGradientDrawable.setCornerRadii(outerR);
		//		bgGradientDrawable.setShape(GradientDrawable.RECTANGLE);
		//		GradientDrawable shapeDrawable = new GradientDrawable();
		//		shapeDrawable.setSize(width_item - 16, height_item - 16);
		//		shapeDrawable.setStroke(0, 0);
		//		float[] outerR_2 = new float[] { out_radius_2, out_radius_2, out_radius_2, out_radius_2, out_radius_2,
		//				out_radius_2, out_radius_2, out_radius_2 };
		//		shapeDrawable.setCornerRadii(outerR_2);
		//		shapeDrawable.setShape(GradientDrawable.RECTANGLE);
		//		shapeDrawable.setColor(Color.parseColor("#fff000"));
		//		LayerDrawable layerDrawableSel = new LayerDrawable(new Drawable[] { bgGradientDrawable, shapeDrawable });
		//		layerDrawableSel.setLayerInset(1, 8, 8, 8, 8);
		//		LayerDrawable layerDrawableUnsel = new LayerDrawable(new Drawable[] { shapeDrawable });
		//		layerDrawableUnsel.setLayerInset(0, 8, 8, 8, 8);
		//		StateListDrawable stateListDrawable = new StateListDrawable();
		//		
		//		stateListDrawable.addState(new int[] {android.R.attr.state_pressed }, layerDrawableSel);
		//		stateListDrawable.addState(new int[] {android.R.attr.state_selected }, layerDrawableSel);
		//		stateListDrawable.addState(new int[] {}, layerDrawableUnsel);
		ShapeDrawable backGroundDrawable = null;
		float[] outerR = new float[] { out_radius, out_radius, out_radius, out_radius, out_radius, out_radius,
				out_radius, out_radius };
		RoundRectShape s = new RoundRectShape(outerR, null, null);
		backGroundDrawable = new ShapeDrawable(s);
		backGroundDrawable.setIntrinsicWidth(width_item);
		backGroundDrawable.setIntrinsicHeight(height_item);
		backGroundDrawable.getPaint().setStrokeWidth(strokeWidth);
		backGroundDrawable.getPaint().setColor(Color.parseColor("#ff0000"));
		backGroundDrawable.getPaint().setStyle(Paint.Style.STROKE);
		float[] outerR_2 = new float[] { out_radius_2, out_radius_2, out_radius_2, out_radius_2, out_radius_2,
				out_radius_2, out_radius_2, out_radius_2 };
		RoundRectShape s2 = new RoundRectShape(outerR_2, null, null);
		ShapeDrawable shapeDrawable = new ShapeDrawable(s2);
		shapeDrawable.setIntrinsicWidth(width_item - 16);
		shapeDrawable.setIntrinsicHeight(height_item - 16);
		shapeDrawable.getPaint().setColor(Color.parseColor("#ff0000"));
		shapeDrawable.getPaint().setStyle(Paint.Style.FILL);
		LayerDrawable layerDrawableSel = new LayerDrawable(new Drawable[] { backGroundDrawable, shapeDrawable });
		layerDrawableSel.setLayerInset(1, 8, 8, 8, 8);
		LayerDrawable layerDrawableUnsel = new LayerDrawable(new Drawable[] { shapeDrawable });
		layerDrawableUnsel.setLayerInset(0, 8, 8, 8, 8);
		StateListDrawable stateListDrawable = new StateListDrawable();
		stateListDrawable.addState(new int[] { android.R.attr.state_selected }, layerDrawableSel);
		stateListDrawable.addState(new int[] { android.R.attr.state_pressed }, layerDrawableSel);
		stateListDrawable.addState(new int[] {}, layerDrawableUnsel);
		imageView.setImageDrawable(stateListDrawable);
		imageView.setSelected(true);
		imageView.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				StringBuffer sb = new StringBuffer();
				int[] states = imageView.getDrawable() != null ? imageView.getDrawableState() : imageView
						.getBackground().getState();
				for (int stateOne : states) {
					sb.append(String.valueOf(stateOne)).append(",");
				}
				Log.d("MainActivity", "sb.toString:" + sb.toString());
				imageView.setSelected(!imageView.isSelected());
			}
		});
		pop_gv = new GridView(this);
		pop_gv.setHorizontalSpacing(10);
		pop_gv.setVerticalSpacing(17);
		colorsList = Arrays.asList(getResources().getStringArray(R.array.officeui_pop_colors));
		pop_gv.setNumColumns(2);
		pop_gv.setAdapter(new GVAdapter());
		lp.gravity = Gravity.CENTER;
		lp.width = FrameLayout.LayoutParams.WRAP_CONTENT;
		lp.height = FrameLayout.LayoutParams.WRAP_CONTENT;


这种方式设置pressed有效,selected为true无效时:

StateListDrawable stateListDrawable = new StateListDrawable();
stateListDrawable.addState(new int[] { android.R.attr.state_pressed }, layerDrawableSel);
stateListDrawable.addState(new int[] { -android.R.attr.state_pressed }, layerDrawableUnsel);
stateListDrawable.addState(new int[] { android.R.attr.state_selected }, layerDrawableSel);
stateListDrawable.addState(new int[] { -android.R.attr.state_selected }, layerDrawableUnsel);

原因:是-android.R.attr.state_pressed在android.R.attr.state_selected前面,导致逻辑判断走不到android.R.attr.state_selected;


解决方法:将正状态如android.R.attr.state_selected放在-android.R.attr.state_selected等这些负状态前面;

StateListDrawable stateListDrawable = new StateListDrawable();
stateListDrawable.addState(new int[] { android.R.attr.state_pressed }, layerDrawableSel);
stateListDrawable.addState(new int[] { android.R.attr.state_selected }, layerDrawableSel);
stateListDrawable.addState(new int[] { -android.R.attr.state_selected }, layerDrawableUnsel);
stateListDrawable.addState(new int[] { -android.R.attr.state_pressed }, layerDrawableUnsel); 

或者这种可以:

StateListDrawable stateListDrawable = new StateListDrawable();
stateListDrawable.addState(new int[] { android.R.attr.state_selected }, layerDrawableSel);
stateListDrawable.addState(new int[] { android.R.attr.state_pressed }, layerDrawableSel);
stateListDrawable.addState(new int[] {}, layerDrawableUnsel);
imageView.setImageDrawable(stateListDrawable);

参考:

stackoverflow的问题


你可能感兴趣的:(Android基础)