android+tv+自动切换,Android TV 重写GridView,实现焦点放大效果
关于缩放,使用了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,实现焦点放大效果相关推荐
- android 导航自动切换,Android导航抽屉切换图标向右
吃鸡游戏 我为EndDrawerToggle该类编写了一个与您的设置非常相似的设置- DrawerLayout带末端对齐的抽屉View,AppCompatActivity带有自定义Toolbar的支持 ...
- android 静态图片自动切换,Android静态图片人脸识别的完整demo(附完整源码)
Android静态图片人脸识别的完整demo(附完整源码) 来源:互联网 作者:佚名 时间:2015-03-24 20:07 本文介绍了android静态识别人脸并进行标记人眼位置及人脸框的完整dem ...
- android设置自动亮度,Android亮度调节的几种实现方法
最近在做一个App的设置项,亮度调节.真正做时,发现Android亮度调节比预想要复杂一些.其实目前网上已有不少这方面的资料,但有些博文具有一定误导性.在此将这块内容按照自己理解整理一下. 整体上看, ...
- android 横竖屏幕切换,Android 横竖屏切换总结
一.Android切换横竖屏 应用的横竖屏设置 应用的横竖屏设置主要是通过Activity的screenOrientation属性控制,属性值如下: 主要有以下两种方式设置screenOrientat ...
- android开发自动拍照,Android:Camera2开发详解(上):实现预览、拍照、保存照片等功能...
android.jpg 前言 在前几篇文章中介绍了如何调用系统相机拍照和使用Camera1的实现自定义相机拍照.人脸检测等功能 文章传送门: 接下来的几篇文章中,我将给大家介绍如何使用Camera2实 ...
- android 实现自动拍照,android实现定时拍照功能
在手机上面实现,设置一段时间(以秒计时)之后,自动拍照,适用于摄影师建立一个场景,之后设置时间,再进入场景. 界面主要就是一个设置时间的EditText和启动倒计时的Button,设置完时间之后,点击 ...
- android 键盘 自动消失,android 键盘状态,获取键盘显示和隐藏
要设置弹出键盘是否覆盖Activity的view,或者软键盘的显示隐藏状态,需要用到Activity的一个属性: android:windowSoftInputMode 该属性在AndroidMani ...
- android edittext自动获取焦点,Android取消EditText自动获取默认焦点
Android取消EditText自动获取默认焦点 发布时间:2020-10-02 14:08:30 来源:脚本之家 阅读:142 作者:ganchuanpu 最近在通讯录新建联系人=中,一进入一个页 ...
- android 表情键盘切换,Android仿微信键盘切换效果
Android 仿微信的键盘切换(录音,表情,文字,其他),IM通讯,类似朋友圈只要涉及到文字等相关的app都会要涉及到键盘的处理,今天就给大家分享一下Android 仿微信的键盘切换. 效果图如下: ...
最新文章
- css学习笔记2--多重边框
- 001_Spring Data JPA
- 平果手机桌面计算机,苹果手机便签记事本怎么在Windows电脑桌面上使用?
- 信息学奥赛一本通 1045:收集瓶盖赢大奖 | OpenJudge NOI 1.4 07
- 在docker上和ubuntu上运行InfoGAN
- keras系列︱Sequential与Model模型、keras基本结构功能(一)
- 通达信自编的选股公式如何使用?
- GitHub 上有哪些一般人也可以用的项目?
- Java订单接入支付宝二 支付回调
- CPU寻址能力的理解
- 深圳大学计算机研究生调剂,深圳大学2020年硕士研究生招生调剂办法
- wd ex2 ultra mysql_西部数据My Cloud EX2网络存储器驱动
- python实现最小二乘拟合函数(选择三种不同基函数,基函数可改变)
- 一百馒头一百僧升级版
- 剑灵在该服务器上未获取到角色信息,白青FAQ!常见问题一网打尽
- 期权Greeks(Delta、Gamma、Vega、Theta) 介绍与Python实现
- ROS学习总结十二:给自己的机器人添加传感器
- 企业微信如何退出之前的公司
- Autofill 实践
- (二)什么是Reactor模式
热门文章
- 验证曲线( validation curve)是什么?如何绘制验证曲线( validation curve)?验证曲线( validation curve)详解及实践
- laravel php跨域请求,Laravel 5.x设置跨域访问
- 组合数函数-快速提取所有可能的组合数
- 中国知网PCNI号码
- python3环境搭建(利用Anaconda+pycharm+pytorch)
- Proovread安装与试用
- PHP 表单文件上传的原理,php上传文件的原理
- flask 创建基本模板
- 计算机 微课 论文,探析毕业论文怎么写 关于微课和电脑论文范例30000字
- 【NIO】异步模型之Callback -- 封装NIO