关于缩放,使用了view.setScaleX/Y 方法,api11以上即可。

重写dispatchDraw(),绘制选中项的焦点效果。(注意带阴影的焦点图需要微调偏移量)

要将选中项绘制显示在顶层,所以要改变GridView的子View绘制顺序;

所以要重写bringChildToFront、getChildDrawingOrder,同时要打开setChildrenDrawingOrderEnabled(true)。

在缩放代码中添加了监听器,用于调用端,设置回调。

注意: 如果GridView的最后一行的个数少于列数,在较少的列上向下,会报异常。 还有就是当快速切换时,可能会看到默认的listSelector,可以将其设置为透明的。

package com.stone.tvapplication.widget;

import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Rect;

import android.graphics.drawable.Drawable;

import android.util.AttributeSet;

import android.view.View;

import android.view.ViewGroup;

import android.widget.AbsListView;

import android.widget.GridView;

import android.widget.ImageView;

import android.widget.RelativeLayout;

import android.widget.TextView;

import com.stone.tvapplication.R;

import com.stone.tvapplication.util.AdaptionAlgo;

/**

* 重写dispatchDraw,在选中项上绘制一个focus-drawable

*

* author : stone

* email : aa86799@163.com

* time : 16/5/11 10 20

*/

public class TvFocusGridView extends GridView {

private Drawable mFocusBackDrawable;

private Rect mFocusBackRect;

private int mSelectedPosition;

private View mSelectedView;

private float mScaleX;

private float mScaleY;

private onItemFocusSelectedListener mOnItemFocusSelectedListener;

public TvFocusGridView(Context context) {

this(context, null);

}

public TvFocusGridView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public TvFocusGridView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

setClipChildren(false);

setClipToPadding(false);

setChildrenDrawingOrderEnabled(true);//设置绘制顺序可重定义,需要重写getChildDrawingOrder来变化绘制顺序

TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.TvFocusGridView);

mFocusBackDrawable = array.getDrawable(R.styleable.TvFocusGridView_focus_background);

array.recycle();

mFocusBackRect = new Rect();

mFocusBackDrawable.getPadding(mFocusBackRect); //Drawable中实际填充图像的Rect

// System.out.println("mFocusBackRect-->" + mFocusBackRect);

}

public interface onItemFocusSelectedListener {

void onFocused(View child, int position);

void unfocused(View child, int position);

}

public void setOnItemFocusSelectedListener(onItemFocusSelectedListener onItemFocusSelectedListener) {

this.mOnItemFocusSelectedListener = onItemFocusSelectedListener;

}

@Override

protected void dispatchDraw(Canvas canvas) {

super.dispatchDraw(canvas);

if (mFocusBackDrawable == null) {

return;

}

drawSelector(canvas);

}

private void drawSelector(Canvas canvas) {

View view = getSelectedView();

if (view == null) return;

bringChildToFront(view);

if (isFocused()) {

scaleSelectedView(view);

Rect gvVisibleRect = new Rect();

this.getGlobalVisibleRect(gvVisibleRect); //GridView可见区 在屏幕中的绝对坐标 rect

Rect selectedViewRect = new Rect();

if (mSelectedView instanceof ViewGroup) {

mSelectedView.getGlobalVisibleRect(selectedViewRect); //选中View可见区 在屏幕中的绝对坐标 rect

selectedViewRect.offset(-gvVisibleRect.left, - gvVisibleRect.top); //偏移

selectedViewRect.left -= mFocusBackRect.left + 40;//+阴影偏移

selectedViewRect.top -= mFocusBackRect.top + 20;

selectedViewRect.right += mFocusBackRect.right + 40;

selectedViewRect.bottom += mFocusBackRect.bottom + 20;

mFocusBackDrawable.setBounds(selectedViewRect);

mFocusBackDrawable.draw(canvas);

}

}

}

/**

* 使子view位置在上层

* @param child

*/

@Override

public void bringChildToFront(View child) { //重写,不调用父类方法;获取child的实际position

// super.bringChildToFront(child);

mSelectedPosition = indexOfChild(child);

invalidate();

}

@Override

protected int getChildDrawingOrder(int childCount, int i) {//交换 选中项与最后一项 绘制的顺序

if (mSelectedPosition != AbsListView.INVALID_POSITION) {

if (i == mSelectedPosition) {

return childCount - 1;

}

if (i == childCount - 1) {

return mSelectedPosition;

}

}

return super.getChildDrawingOrder(childCount, i);

}

private void scaleSelectedView(View view) {//缩放

unScalePreView();

mSelectedView = view;

mSelectedView.setScaleX(mScaleX); //api11

mSelectedView.setScaleY(mScaleY);

if (mOnItemFocusSelectedListener != null) {

mOnItemFocusSelectedListener.onFocused(mSelectedView, indexOfChild(mSelectedView));

}

}

private void unScalePreView() {//还原

if (mSelectedView != null) {

mSelectedView.setScaleX(1);

mSelectedView.setScaleY(1);

if (mOnItemFocusSelectedListener != null) {

mOnItemFocusSelectedListener.unfocused(mSelectedView, indexOfChild(mSelectedView));

}

mSelectedView = null;

}

}

@Override

protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {//整个GridView焦点状态

if (!gainFocus) {

unScalePreView();

requestLayout();

}

super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);

}

public void setScale(float scaleX, float scaleY) {

this.mScaleX = scaleX;

this.mScaleY = scaleY;

}

}

调用端设置与监听:

mGridView.setAdapter(mAdapter);

mGridView.setScale(1.2f, 1.2f);

mGridView.setHorizontalSpacing(AdaptionAlgo.scaleX(30));

mGridView.setVerticalSpacing(AdaptionAlgo.scaleY(30));

mGridView.setPadding(60, 40, 60, 40);

mGridView.setOnItemFocusSelectedListener(new TvFocusGridView.onItemFocusSelectedListener() {

@Override

public void onFocused(View child, int position) {

TextView tv = getViewById(child, R.id.tv_text);

tv.setTextColor(Color.RED);

}

@Override

public void unfocused(View child, int position) {

TextView tv = getViewById(child, R.id.tv_text);

tv.setTextColor(Color.MAGENTA);

}

});

android+tv+自动切换,Android TV 重写GridView,实现焦点放大效果相关推荐

  1. android 导航自动切换,Android导航抽屉切换图标向右

    吃鸡游戏 我为EndDrawerToggle该类编写了一个与您的设置非常相似的设置- DrawerLayout带末端对齐的抽屉View,AppCompatActivity带有自定义Toolbar的支持 ...

  2. android 静态图片自动切换,Android静态图片人脸识别的完整demo(附完整源码)

    Android静态图片人脸识别的完整demo(附完整源码) 来源:互联网 作者:佚名 时间:2015-03-24 20:07 本文介绍了android静态识别人脸并进行标记人眼位置及人脸框的完整dem ...

  3. android设置自动亮度,Android亮度调节的几种实现方法

    最近在做一个App的设置项,亮度调节.真正做时,发现Android亮度调节比预想要复杂一些.其实目前网上已有不少这方面的资料,但有些博文具有一定误导性.在此将这块内容按照自己理解整理一下. 整体上看, ...

  4. android 横竖屏幕切换,Android 横竖屏切换总结

    一.Android切换横竖屏 应用的横竖屏设置 应用的横竖屏设置主要是通过Activity的screenOrientation属性控制,属性值如下: 主要有以下两种方式设置screenOrientat ...

  5. android开发自动拍照,Android:Camera2开发详解(上):实现预览、拍照、保存照片等功能...

    android.jpg 前言 在前几篇文章中介绍了如何调用系统相机拍照和使用Camera1的实现自定义相机拍照.人脸检测等功能 文章传送门: 接下来的几篇文章中,我将给大家介绍如何使用Camera2实 ...

  6. android 实现自动拍照,android实现定时拍照功能

    在手机上面实现,设置一段时间(以秒计时)之后,自动拍照,适用于摄影师建立一个场景,之后设置时间,再进入场景. 界面主要就是一个设置时间的EditText和启动倒计时的Button,设置完时间之后,点击 ...

  7. android 键盘 自动消失,android 键盘状态,获取键盘显示和隐藏

    要设置弹出键盘是否覆盖Activity的view,或者软键盘的显示隐藏状态,需要用到Activity的一个属性: android:windowSoftInputMode 该属性在AndroidMani ...

  8. android edittext自动获取焦点,Android取消EditText自动获取默认焦点

    Android取消EditText自动获取默认焦点 发布时间:2020-10-02 14:08:30 来源:脚本之家 阅读:142 作者:ganchuanpu 最近在通讯录新建联系人=中,一进入一个页 ...

  9. android 表情键盘切换,Android仿微信键盘切换效果

    Android 仿微信的键盘切换(录音,表情,文字,其他),IM通讯,类似朋友圈只要涉及到文字等相关的app都会要涉及到键盘的处理,今天就给大家分享一下Android 仿微信的键盘切换. 效果图如下: ...

最新文章

  1. css学习笔记2--多重边框
  2. 001_Spring Data JPA
  3. 平果手机桌面计算机,苹果手机便签记事本怎么在Windows电脑桌面上使用?
  4. 信息学奥赛一本通 1045:收集瓶盖赢大奖 | OpenJudge NOI 1.4 07
  5. 在docker上和ubuntu上运行InfoGAN
  6. keras系列︱Sequential与Model模型、keras基本结构功能(一)
  7. 通达信自编的选股公式如何使用?
  8. GitHub 上有哪些一般人也可以用的项目?
  9. Java订单接入支付宝二 支付回调
  10. CPU寻址能力的理解
  11. 深圳大学计算机研究生调剂,深圳大学2020年硕士研究生招生调剂办法
  12. wd ex2 ultra mysql_西部数据My Cloud EX2网络存储器驱动
  13. python实现最小二乘拟合函数(选择三种不同基函数,基函数可改变)
  14. 一百馒头一百僧升级版
  15. 剑灵在该服务器上未获取到角色信息,白青FAQ!常见问题一网打尽
  16. 期权Greeks(Delta、Gamma、Vega、Theta) 介绍与Python实现
  17. ROS学习总结十二:给自己的机器人添加传感器
  18. 企业微信如何退出之前的公司
  19. Autofill 实践
  20. (二)什么是Reactor模式

热门文章

  1. 验证曲线( validation curve)是什么?如何绘制验证曲线( validation curve)?验证曲线( validation curve)详解及实践
  2. laravel php跨域请求,Laravel 5.x设置跨域访问
  3. 组合数函数-快速提取所有可能的组合数
  4. 中国知网PCNI号码
  5. python3环境搭建(利用Anaconda+pycharm+pytorch)
  6. Proovread安装与试用
  7. PHP 表单文件上传的原理,php上传文件的原理
  8. flask 创建基本模板
  9. 计算机 微课 论文,探析毕业论文怎么写 关于微课和电脑论文范例30000字
  10. 【NIO】异步模型之Callback -- 封装NIO