做过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,这样即可。
