首页 > 代码库 > ZoneGridVIew 自定义放大GridView

ZoneGridVIew 自定义放大GridView

电视浏览交互设计和手机很大不同。不是触屏一般要有当前焦点框,而且观看距离较远,屏幕大内容多。为了突出选中焦点,电视UI常采用选中放大的策略。

而最常用的一种UI布局方式就是,带选中放大框的GridView。下面对这种ZoneGridView介绍

 

 

 选中放大是采用默认API支持的 View.setScaleValue(); 对于每一个选中的View,计算出放大尺寸,放大。

void scaleCurrentView(){        View v = getSelectedView();        unScalePrevView();        if(v != null){            //Log.i(TAG,"scaleView");            mMySelectedView = v;            mMySelectedView.setScaleX(mMyScaleX);            mMySelectedView.setScaleY(mMyScaleY);        }    }

 

计算ScaleX ScaleX 的尺寸,通过参数传入ZoneGridView。

        try {            float scaleX = (1.0f * (gridItemWidth + horizontalSpacing) / gridItemWidth);            float scaleY = (1.0f * (gridItemHeight + verticalSpacing) / gridItemHeight);            mGridView.setMyScaleValues(scaleX, scaleY);        } catch (Exception e) {            e.printStackTrace();        }

 

绘制选中焦点框方法,焦点框通常比正常背景大一点。这里采用的.9可拉伸的中间透明的矩形框。通过GridView的dispatchDraw方法绘制背景。
    protected void drawSelector(Canvas canvas) {        View v = getSelectedView();        if (isFocused() && v != null) {            scaleCurrentView();                        Rect r = mTmpSelectedRect;//            getFocusedRect(r);                        v.getGlobalVisibleRect(r);            getGlobalVisibleRect(mTmpGridViewRect);                        r.offset(-mTmpGridViewRect.left, -mTmpGridViewRect.top);                        r.top -= mMySelectedPaddingRect.top;            r.left -= mMySelectedPaddingRect.left;            r.right += mMySelectedPaddingRect.right;            r.bottom += mMySelectedPaddingRect.bottom;                        //int restoreCount = canvas.save();            //canvas.scale(v.getScaleX(), v.getScaleY(), r.exactCenterX(), r.exactCenterY());            mMySelectedDrawable.setBounds(r);            mMySelectedDrawable.draw(canvas);            //canvas.restoreToCount(restoreCount);        }    }

 完整的ZoneGridView代码

public class ZoneGridView extends GridView {    float mMyScaleX = 1.0f;    float mMyScaleY = 1.0f;    protected Rect mMySelectedPaddingRect = new Rect();    Drawable mPlayIcon;    protected boolean mShowPlayIcon = false;        int mPlayIconMargin;        public void setShowPlayIcon(Boolean show) {        mShowPlayIcon = show;        this.invalidate();    }        public ZoneGridView(Context contxt) {        super(contxt);        mPlayIcon = this.getResources().getDrawable(R.drawable.tv_ic_cloud_video);        mPlayIconMargin = getResources().getDimensionPixelSize(R.dimen.aui_margin_2);    }    public ZoneGridView(Context contxt, AttributeSet attrs) {        super(contxt, attrs);        mPlayIcon = this.getResources().getDrawable(R.drawable.tv_ic_cloud_video);        mPlayIconMargin = getResources().getDimensionPixelSize(R.dimen.aui_margin_2);    }    public ZoneGridView(Context contxt, AttributeSet attrs, int defStyle) {        super(contxt, attrs, defStyle);        mPlayIcon = this.getResources().getDrawable(R.drawable.tv_ic_cloud_video);        mPlayIconMargin = getResources().getDimensionPixelSize(R.dimen.aui_margin_2);    }        @Override    public void dispatchDraw(Canvas canvas) {        super.dispatchDraw(canvas);        if (mMySelectedDrawable == null)            return;        drawSelector(canvas);        drawPlayIcon(canvas);    }        protected void drawPlayIcon(Canvas canvas) {                if (isFocused() && this.mMySelectedDrawable != null && mShowPlayIcon) {            Rect r = this.mMySelectedDrawable.getBounds();            r.bottom -= (mPlayIconMargin+this.mMySelectedPaddingRect.bottom);            r.right -= (mPlayIconMargin+this.mMySelectedPaddingRect.right);            r.top = r.bottom - mPlayIcon.getIntrinsicHeight();            r.left = r.right - mPlayIcon.getIntrinsicWidth();            mPlayIcon.setBounds(r);            mPlayIcon.draw(canvas);        }    }        public void setMySelector(int resId) {        mMySelectedDrawable = getResources().getDrawable(resId);        mMySelectedPaddingRect = new Rect();        mMySelectedDrawable.getPadding(mMySelectedPaddingRect);    }    protected Drawable mMySelectedDrawable = null;    protected View mMySelectedView = null;        protected Rect mTmpSelectedRect = new Rect();    protected Rect mTmpGridViewRect = new Rect();        protected void drawSelector(Canvas canvas) {        View v = getSelectedView();        if (isFocused() && v != null) {            scaleCurrentView();                        Rect r = mTmpSelectedRect;//            getFocusedRect(r);                        v.getGlobalVisibleRect(r);            getGlobalVisibleRect(mTmpGridViewRect);                        r.offset(-mTmpGridViewRect.left, -mTmpGridViewRect.top);                        r.top -= mMySelectedPaddingRect.top;            r.left -= mMySelectedPaddingRect.left;            r.right += mMySelectedPaddingRect.right;            r.bottom += mMySelectedPaddingRect.bottom;                        //int restoreCount = canvas.save();            //canvas.scale(v.getScaleX(), v.getScaleY(), r.exactCenterX(), r.exactCenterY());            mMySelectedDrawable.setBounds(r);            mMySelectedDrawable.draw(canvas);            //canvas.restoreToCount(restoreCount);        }    }        public void setMyScaleValues(float scaleX, float scaleY) {        mMyScaleX = scaleX;        mMyScaleY = scaleY;    }        void scaleCurrentView(){        View v = getSelectedView();        unScalePrevView();        if(v != null){            //Log.i(TAG,"scaleView");            mMySelectedView = v;            mMySelectedView.setScaleX(mMyScaleX);            mMySelectedView.setScaleY(mMyScaleY);        }    }        void unScalePrevView(){        if(mMySelectedView != null){            mMySelectedView.setScaleX(1);            mMySelectedView.setScaleY(1);            mMySelectedView = null;        }            }                protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {        if(!gainFocus){            unScalePrevView();            requestLayout();        }        super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);    }    protected int mMyVerticalSpacing = 0;        public void setMyVerticalSpacing(int verticalSpacing) {        mMyVerticalSpacing = verticalSpacing;    }        public int getMyVerticalSpacing() {        return mMyVerticalSpacing;    }}

 

Activity中调用ZoneGridView 

// adapter.notifyDataSetChanged();        mGridView = (ZoneGridView) findViewById(R.id.gridView);        adapter = new ThumbMixAdapter(this, _files);        mGridView.setAdapter(adapter);        mGridView.setClipToPadding(false);        mGridView.setSelected(true);        mGridView.setSelection(0);        mGridView.setSelector(android.R.color.transparent);        mGridView.setMySelector(R.drawable.tui_bg_focus);

 

layout的布局文件

    <com.commons.ZoneGridView        android:id="@+id/gridView"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:numColumns="4"        android:layout_marginTop="@dimen/tui_margin_5_d20dp"        android:paddingTop="@dimen/tui_padding_hacked_i20dp"        android:paddingBottom="@dimen/tui_margin_3"        android:horizontalSpacing="@dimen/tui_margin_4_28"        android:verticalSpacing="@dimen/tui_margin_3"         android:gravity="center_horizontal"        android:drawSelectorOnTop="false"        android:scrollbars="none"/>

 

ZoneGridVIew 自定义放大GridView