android tv焦点特效实现浅析

Android TV上的焦点凸显特效相信大家都看到过,那么我们就来实现它吧,首先上张效果图。

先说一下实现原理,主要通过重写RelativeLayout实现item,之后在其中加入scalanimation动画效果。刚开始处理时,还是发现了一些问题,比如item放大后会被其他item遮挡,如何添加选中边框等等,以及动画的实现等等。下面放上实现细节。

首先是item的代码:

<view xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item"
    android:layout_width="@dimen/home_channel_item_width"
    android:layout_height="@dimen/home_channel_item_height"
    class="com.eastelsoft.tv.widget.home.HomeItemContainer"
    android:clickable="true"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:clipChildren="false"
    android:clipToPadding="false" >

    <com.eastelsoft.tv.widget.ESImageView
        android:id="@+id/img"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@drawable/holder_nor"
        android:duplicateParentState="true"
        android:scaleType="fitXY" />

    <!-- -->
    <com.eastelsoft.tv.widget.ESImageView
        android:id="@+id/hover"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:contentDescription="@string/desc"
        android:duplicateParentState="true"
        android:scaleType="fitXY"
        android:src="@drawable/sl_image_home_navigator" />

    <TextView
        android:id="@+id/text"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="@dimen/home_item_text_margin"
        android:layout_marginLeft="@dimen/home_item_text_margin"
        android:layout_marginRight="@dimen/home_item_text_margin"
        android:ellipsize="marquee"
        android:gravity="bottom|right|center"
        android:includeFontPadding="false"
        android:marqueeRepeatLimit="5"
        android:maxWidth="@dimen/px310"
        android:shadowColor="#88333333"
        android:shadowDx="2.0"
        android:shadowDy="2.0"
        android:shadowRadius="2.0"
        android:singleLine="true"
        android:textColor="#ffffffff" />

</view>

这里定义了一个自定义view,代码在后面放上,每个item里添加了一个img,用于放置内容图片,一个hover,用于显示选中的边框,以及一个text,显示一些文字说明。

hover的src是一个selector drawable,当未focus时,它的背景是tansparent,当focus,放入外框图片。

自定义的HomeItemContainer 代码:

public class HomeItemContainer extends RelativeLayout {

	private Animation scaleSmallAnimation;
	private Animation scaleBigAnimation;

	public HomeItemContainer(Context context) {
		super(context);
	}

	public HomeItemContainer(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	public HomeItemContainer(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
	}

	@Override
	protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
		super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
		if (gainFocus) {
			this.bringToFront();
			getRootView().requestLayout();
			getRootView().invalidate();
			zoomOut();
		} else {
			zoomIn();
		}
	}

	private void zoomIn() {
		if (scaleSmallAnimation == null) {
			scaleSmallAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.anim_scale_small);
		}
		startAnimation(scaleSmallAnimation);
	}

	private void zoomOut() {
		if (scaleBigAnimation == null) {
			scaleBigAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.anim_scale_big);
		}
		startAnimation(scaleBigAnimation);
	}

}

注意onFocusChanged方法,为防止item被其他item遮挡,先调用bringToFront方法,使此item处于最上层,之后调用父view的方法进行重新绘制,其实注意一点,item必须处于同一父view中,否则requestLayout和invalidate可能会不起作用。

顺便放上一个scaleanimation缩小的效果代码:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="false"
    android:fillBefore="true"
    android:shareInterpolator="false" >

    <scale
        android:duration="200"
        android:fromXScale="1.1"
        android:fromYScale="1.1"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:pivotX="50.0%"
        android:pivotY="50.0%"
        android:repeatCount="0"
        android:toXScale="1.0"
        android:toYScale="1.0" />

</set>

里面的属性就不详细介绍了,有兴趣的可以自己谷歌。

最后放上item的父view:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:padding="10dp"
    android:clipChildren="false"
    android:clipToPadding="false" >

    <include
        android:id="@+id/channel_0"
        android:layout_width="@dimen/home_channel_item_width"
    	android:layout_height="@dimen/home_channel_item_height"
        layout="@layout/home_page_channel_item"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_margin="3dp" />

    <include
        android:id="@+id/channel_1"
        android:layout_width="@dimen/home_channel_item_width"
    	android:layout_height="@dimen/home_channel_item_height"
        layout="@layout/home_page_channel_item"
        android:layout_below="@id/channel_0"
        android:layout_alignLeft="@id/channel_0" />

    <include
        android:id="@+id/channel_2"
        android:layout_width="@dimen/home_channel_item_width"
    	android:layout_height="@dimen/home_channel_item_height"
        layout="@layout/home_page_channel_item"
        android:layout_toRightOf="@id/channel_0"
        android:layout_alignTop="@id/channel_0"
        android:layout_marginRight="3dp"
        android:layout_marginBottom="3dp"/>

    <include
        android:id="@+id/channel_3"
        android:layout_width="@dimen/home_channel_item_width"
    	android:layout_height="@dimen/home_channel_item_height"
        layout="@layout/home_page_channel_item"
        android:layout_alignLeft="@id/channel_2"
        android:layout_below="@id/channel_2"/>

    <include
        android:id="@+id/channel_4"
        android:layout_width="@dimen/home_channel_item_width"
    	android:layout_height="@dimen/home_channel_item_height"
        layout="@layout/home_page_channel_item"
        android:layout_toRightOf="@id/channel_2"
        android:layout_alignTop="@id/channel_2"
        android:layout_marginRight="3dp"
        android:layout_marginBottom="3dp"/>

    <include
        android:id="@+id/channel_5"
        android:layout_width="@dimen/home_channel_item_width"
    	android:layout_height="@dimen/home_channel_item_height"
        layout="@layout/home_page_channel_item"
        android:layout_alignLeft="@id/channel_4"
        android:layout_below="@id/channel_4"/>

    <include
        android:id="@+id/channel_6"
        android:layout_width="@dimen/home_channel_item_width"
    	android:layout_height="@dimen/home_channel_item_height"
        layout="@layout/home_page_channel_item"
        android:layout_toRightOf="@id/channel_4"
        android:layout_alignTop="@id/channel_4"
        android:layout_marginRight="3dp"
        android:layout_marginBottom="3dp"/>

    <include
        android:id="@+id/channel_7"
        android:layout_width="@dimen/home_channel_item_width"
    	android:layout_height="@dimen/home_channel_item_height"
        layout="@layout/home_page_channel_item"
        android:layout_alignLeft="@id/channel_6"
        android:layout_below="@id/channel_6"/>

    <include
        android:id="@+id/channel_8"
        android:layout_width="@dimen/home_channel_item_width"
    	android:layout_height="@dimen/home_channel_item_height"
        layout="@layout/home_page_channel_item"
        android:layout_toRightOf="@id/channel_6"
        android:layout_alignTop="@id/channel_6"
        android:layout_marginRight="3dp"
        android:layout_marginBottom="3dp"/>

    <include
        android:id="@+id/channel_9"
        android:layout_width="@dimen/home_channel_item_width"
    	android:layout_height="@dimen/home_channel_item_height"
        layout="@layout/home_page_channel_item"
        android:layout_alignLeft="@id/channel_8"
        android:layout_below="@id/channel_8"/>

</RelativeLayout>

这里我定义了10个item,注意RelativeLayout的两个属性,clipChildren设置false,让children view可以超出自身所设置的大小,clipToPadding设置为false,让children view可以使用padding 的位置进行绘制,有了这2个属性,item就可以实现放大而不被遮挡了。

好了,焦点特效的教程就说到这里了,有问题可以在评论中反馈。

时间: 2024-11-03 03:24:36

android tv焦点特效实现浅析的相关文章

android tv 焦点移动特效

最近在研究电视launcher的动画效果,看小米电视做的挺好.现在主要有焦点放大,平移等特效,百度了半天,没有多少有价值的东西,大部分都是提问并没有回答,后来在github找到了一个比较好的案例,动画效果看起来比较好,含移动过程焦点边框的变化,高斯模糊等.代码还是有一定难度,不过效果挺好 地址:https://github.com/FrozenFreeFall/Android-tv-widget

Android TV 开发相关文章

Android TV 开发相关文章 Android TV 开发与Android移动设备开发类似,网络上针对其开发文章较少,平时查阅关于TV 开发资料收集于此,方便日后查阅. 持续更新 --. Android TV 焦点特效实现浅析

Android Tv app 与 mobile app 界面呈现的区别

公司的一个项目是android tv的谢了片日报总结:android tv app呈现ui 与手机app的区别 android tv  app和 mobile app 的主要区别在表现形式上 1.焦点移动的处理 从代码上可以明显看出到处都有对焦点获取的处理,这是mobile app所不需要的. 触摸屏与遥控的不同操作方式决定了:tv遥控操作方式在屏幕上是先获取焦点(遥控决定焦点移动)再获取点击,而mobile触摸方式是直接的点击获取与焦点获取一起通常只需要处理点击获取 2.布局边界处理 遥控操作

TCL Android TV 开发环境搭建实录

要求:Eclipse版本3.5以上 ADT版本10.0.1 TCL的SDK(我看了看核心是Android2.2的API) 步骤: 1.下載SDK和TCL的模拟器 2.Eclipse安装ADT(版本一定要符合哦,要不不行) 3.Eclipse挂载SDK Eclipse环境中设置Window->Preferences,在弹出的对话框中选中第二项Android,在SDK Location中设置解压好的开发包文 件夹路径 4.用下载的TCL的模拟器(emulator.exe)把SDK路径/tools文件

Android TV APPs 的介绍与创建

最近开始接触到Andorid TV编程,发现目前这方便的资料与比较还比较少,但现在随着产品与用户的升级,涉及到Android TV与 Android Watch的编程离我们越来越近了,本篇博客开始,将以笔记的方式记录我Android TV从零到有的一个过程. 本博客创建步骤主要参考Android官方文档. Get Started with TV Apps TV应用程序使用相同的结构与手机和平板电脑.这种相似性意味着你也可以修改现有的应用程序运行在TV设备或创建新的应用程序基于你现在已经掌握的An

Android TV开发总结(二)构建一个TV Metro界面(仿泰捷视频TV版)

前言:上篇是介绍构建TV app前要知道的一些事儿,开发Android TV和手机本质上没有太大的区别,屏大,焦点处理,按键处理,是有别于有手机和Pad的实质区别.今天来介绍TV中Metro UI风格,并结合实例说明. Android TV发展离不开Metro UI,先看最新的泰捷TV的会员区效果,属于典型的Metro风格,如下: 什么是Metro UI: Metro的设计意念来源于交通局巴士站站牌机场和地铁的指示牌给了微软设计团队灵感,设计团队说Metro是来源于美国华盛顿州金县都会交通局(K

Android TV界面聚焦效果---凸显效果

Android TV端应用程序的开发时,在聚焦效果上往往是将图标发大并且凸显到最上层来显示,如下图的效果. 该聚焦凸显效果有两种可行的实现方案,不过太麻烦了. 1)全两层布局,所谓全两层布局,就是图标显示层和聚焦凸显层分开,他们是完全重叠的两层.这种方式在程序上是非常不好办的,既要实现焦点转换又要实现上层凸显控件的消失或不消失状态,状态和逻辑都非常复杂. 2)部分两层布局,所谓部分两层布局,就是底层放需要呈现的图标,上层就只有2个可移动的图标,底层哪个图标获取了焦点,那么上层的焦点发大图标就马上

Android之Activity生命周期浅析(一)

??Activity作为四大组件之一,出现的频率相当高,基本上我们在android的各个地方都能看见它的踪影,因此深入了解Activity,对于开发高质量应用程序是很有帮助的.今天我们就来详细地聊聊Activity的生命周期,以便我们在以后的开发中能如鱼得水. 一.初识Activity ??在日常应用中Activity是与用户交互的接口,它提供了一个用户完成相关操作的窗口.当我们在开发中创建Activity后,通过调用setContentView(View)方法来给该Activity指定一个布局

Android TV 盒子开发焦点控制

Android TV app开发与一般Android开发最大的区别在于焦点控制 , 用户在使用Android TV设备主要是通过遥控器操作app. CSDN博客平台看到大牛总结出的2套实用的焦点控制,在此收藏分享: 第一种方法: 采用Android自带的直接控制焦点上下左右的方法.这种方法的前提是必须知道每个view的id,因此在进行布局时有必须要通过view.setId(-)指定view的特定ID,然后通过view.setNextLeftView(-)等四个方法控制该view的上下左右移动后所