做过TV上使用GridView,对item进行放大的时候,会被后面或者其他item遮挡的问题,那么这个问题一般怎么解决呢?
其实当我们遇到这样子的情况,使用bringToFront是无法解决问题的。
其实我们要做的就是,要改变GridView对子view的绘制顺序,要将选中的item项绘制显示在顶层,所以要改变GridView的子View绘制顺序;
/**
*
* @author zhanghuagang 2017.7.6
*
*/
public class CommonGridView extends GridView {
private View mLastView = null;
private int mSelectedPosition;
/**
*
* @author zhanghuagang 2017.7.6
*
*/
public CommonGridView(Context context) {
this(context, null);
}
public CommonGridView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setChildrenDrawingOrderEnabled(true);
setSmoothScrollbarEnabled(true);
}
public CommonGridView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
@Override
protected void setChildrenDrawingOrderEnabled(boolean enabled) {
super.setChildrenDrawingOrderEnabled(enabled);
}
public int getSelectedPosition() {
return mSelectedPosition;
}
public void setSelectedPosition(int mSelectedPosition) {
this.mSelectedPosition = mSelectedPosition;
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
}
private void zoomInView(View v){
AnimatorSet animSet = new AnimatorSet();
float[] values = new float[] { 1.0f ,1.18f };
animSet.playTogether(ObjectAnimator.ofFloat(v, "scaleX", values),
ObjectAnimator.ofFloat(v, "scaleY", values));
animSet.setDuration(100).start();
}
private void zoomOutView(View v){
AnimatorSet animSet = new AnimatorSet();
float[] values = new float[] { 1.18f ,1.0f };
animSet.playTogether(ObjectAnimator.ofFloat(v, "scaleX", values),
ObjectAnimator.ofFloat(v, "scaleY", values));
animSet.setDuration(100).start();
}
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if(view!=null)
zoomInView(view);
if (view != mLastView && mLastView!=null) {
zoomOutView(mLastView);
}
mLastView=view;
}
/**
* 此方法用来完美觉得item放大 ,绘制顺序出现问题的
*/
@Override
protected int getChildDrawingOrder(int childCount, int i) {
if (this.getSelectedItemPosition() != -1) {
if (i + this.getFirstVisiblePosition() == this.getSelectedItemPosition()) {// 这是原本要在最后一个刷新的item
return childCount - 1;
}
if (i == childCount - 1) {// 这是最后一个需要刷新的item
return this.getSelectedItemPosition() - this.getFirstVisiblePosition();
}
}
return i;
}
}
首先我们是自定义view,在构造方法中将是否可以改变绘制顺序设置为true,改为可以。
setChildrenDrawingOrderEnabled(true);
然后,覆盖一下关键方法。
getChildDrawingOrder方法,在这个中实现改变绘制顺序的逻辑,那么我们既然要在放大的时候,不被其他item遮挡,那么就必须在他选中的时候,将他绘制顺序放在最后,大改这个方法的实现逻辑如下。
/**
* 此方法用来完美觉得item放大 ,绘制顺序出现问题的
*/
@Override
protected int getChildDrawingOrder(int childCount, int i) {
if (this.getSelectedItemPosition() != -1) {
if (i + this.getFirstVisiblePosition() == this.getSelectedItemPosition()) {// 这是原本要在最后一个刷新的item
return childCount - 1;
}
if (i == childCount - 1) {// 这是最后一个需要刷新的item
return this.getSelectedItemPosition() - this.getFirstVisiblePosition();
}
}
return i;
}
第一行代码是判断,当前选中的item的position是否有效。
代码逻辑很好理解,如果当前选中的子view是可见的,那么就将其设置为最后一个子view,来绘制,如果选中的是最后一个view,就返回他的真是有效的position,这样即可。