android tv焦点特效实现浅析

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

\

加载中...

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

首先是item的代码:

 <喎�"http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHByZSBjbGFzcz0="brush:java;"> 这里定义了一个自定义view,代码在后面放上,每个item里添加了一个img,用于放置内容图片,一个hover,用于显示选中的边框,以及一个text,显示一些文字说明。

 

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

自定义的HomeItemContainer 代码:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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缩小的效果代码:

 

?
1
2
3
4
5
6
<!--?xml version= 1.0 encoding=utf- 8 ?-->
<set android:fillafter= "false" android:fillbefore= "true" android:shareinterpolator= "false" xmlns:android= "http://schemas.android.com/apk/res/android" >
 
     <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" >
 
</scale></set>

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

 

最后放上item的父view:

 

?
1
2
3
<relativelayout android:clipchildren= "false" android:cliptopadding= "false" android:layout_height= "match_parent" android:layout_width= "match_parent" android:orientation= "horizontal" android:padding= "10dp" xmlns:android= "http://schemas.android.com/apk/res/android" ><include android:id= "@+id/channel_0" android:layout_alignparentleft= "true" android:layout_alignparenttop= "true" android:layout_height= "@dimen/home_channel_item_height" android:layout_margin= "3dp" android:layout_width= "@dimen/home_channel_item_width" layout= "@layout/home_page_channel_item" ><include android:id= "@+id/channel_1" android:layout_alignleft= "@id/channel_0" android:layout_below= "@id/channel_0" android:layout_height= "@dimen/home_channel_item_height" android:layout_width= "@dimen/home_channel_item_width" layout= "@layout/home_page_channel_item" ><include android:id= "@+id/channel_2" android:layout_aligntop= "@id/channel_0" android:layout_height= "@dimen/home_channel_item_height" android:layout_marginbottom= "3dp/" android:layout_marginright= "3dp" android:layout_torightof= "@id/channel_0" android:layout_width= "@dimen/home_channel_item_width" layout= "@layout/home_page_channel_item" ><include android:id= "@+id/channel_3" android:layout_alignleft= "@id/channel_2" android:layout_below= "@id/channel_2/" android:layout_height= "@dimen/home_channel_item_height" android:layout_width= "@dimen/home_channel_item_width" layout= "@layout/home_page_channel_item" ><include android:id= "@+id/channel_4" android:layout_aligntop= "@id/channel_2" android:layout_height= "@dimen/home_channel_item_height" android:layout_marginbottom= "3dp/" android:layout_marginright= "3dp" android:layout_torightof= "@id/channel_2" android:layout_width= "@dimen/home_channel_item_width" layout= "@layout/home_page_channel_item" ><include android:id= "@+id/channel_5" android:layout_alignleft= "@id/channel_4" android:layout_below= "@id/channel_4/" android:layout_height= "@dimen/home_channel_item_height" android:layout_width= "@dimen/home_channel_item_width" layout= "@layout/home_page_channel_item" ><include android:id= "@+id/channel_6" android:layout_aligntop= "@id/channel_4" android:layout_height= "@dimen/home_channel_item_height" android:layout_marginbottom= "3dp/" android:layout_marginright= "3dp" android:layout_torightof= "@id/channel_4" android:layout_width= "@dimen/home_channel_item_width" layout= "@layout/home_page_channel_item" ><include android:id= "@+id/channel_7" android:layout_alignleft= "@id/channel_6" android:layout_below= "@id/channel_6/" android:layout_height= "@dimen/home_channel_item_height" android:layout_width= "@dimen/home_channel_item_width" layout= "@layout/home_page_channel_item" ><include android:id= "@+id/channel_8" android:layout_aligntop= "@id/channel_6" android:layout_height= "@dimen/home_channel_item_height" android:layout_marginbottom= "3dp/" android:layout_marginright= "3dp" android:layout_torightof= "@id/channel_6" android:layout_width= "@dimen/home_channel_item_width" layout= "@layout/home_page_channel_item" ><include android:id= "@+id/channel_9" android:layout_alignleft= "@id/channel_8" android:layout_below= "@id/channel_8/" android:layout_height= "@dimen/home_channel_item_height" android:layout_width= "@dimen/home_channel_item_width" layout= "@layout/home_page_channel_item" >
 
</include></include></include></include></include></include></include></include></include></include></relativelayout>
这里我定义了10个item,注意RelativeLayout的两个属性,clipChildren设置false,让children view可以超出自身所设置的大小,clipToPadding设置为false,让children view可以使用padding 的位置进行绘制,有了这2个属性,item就可以实现放大而不被遮挡了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值