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;
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的问题