Android gridview keep item selected

1. ImageView는 GridView,listView에서 selector를 설정하지만 Adapter의 GetView에서 setSelected(true)를 설정하면 이미지View는 대응하는 그림이 아닙니다. (다음은 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의 어댑터의 GetView 방법에서 클릭할 때 선택한 색을 기록하고 어댑터에게 리셋을 알립니다. 뒤에서 5초 지연하여imgeView의 select 상태를 검사하지만 인쇄는false입니다.getView는 selected를true로 설정했습니다. gridview나gridview의adapter만 이미지view를false로 설정할 수 있습니다.
해결 방법:
방법 1: setSelected 대신 setActivated를 사용하여 효과를 구현합니다.
			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를 설정하여 imageview가 아닌relativelayout에 맞추어 방패 역할을 한다.
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);

참조:
질문

좋은 웹페이지 즐겨찾기