欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

android leanback使用详解以及获取焦点高亮

程序员文章站 2022-07-14 23:18:11
...

转自:http://blog.csdn.net/dongdengke123789/article/details/53541833?hp.com

最近公司有个电视端的项目,对于从未接触过TV端开发的我来说是一种跳转,同时也是一个机遇。TV端开发和手机端开发最大的 不同是焦点的处理以及获取焦点时的酷炫效果。本例子主要实现了利用HorizontalGridView来实现水平滑动的gridview以及获取焦点时的特效。

刚拿到效果时,感觉so easy!可真正到动手写代码时,却卡到了获取焦点时的特效了。上网查了好多资料,但是有关TV端的开发却非常少。于是,自己就尝试分析实现方式。获取焦点时的具体需求是这样的:获取焦点时,整个图片在原来的基础上放大到1.15倍,并在外层有种选中时带有阴影的高亮的图片。通过分析,使用动画来实现较为简单。经过尝试,放大实现了,但是达不到预期效果。经过多次尝试,终于实现了最终效果。基本效果图如下(由于是测试内容,UI比较丑,请见谅android leanback使用详解以及获取焦点高亮):

android leanback使用详解以及获取焦点高亮

接下来就一步一步介绍具体的实现方案。

由于项目中使用了HorizontalGridView,所以要引入依赖

  1. compile 'com.android.support:leanback-v17:24.2.1'  
compile 'com.android.support:leanback-v17:24.2.1'

此外使用HorizontalGridView还需要在清单文件中进行声明下

  1. <uses-feature  
  2.     android:name="android.software.leanback"  
  3.     android:required="false" />  
    <uses-feature
        android:name="android.software.leanback"
        android:required="false" />

到此,准备工作就完毕了,接下来就开始写布局文件了。

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:app="http://schemas.android.com/apk/res-auto"  
  4.     xmlns:tools="http://schemas.android.com/tools"  
  5.     android:id="@+id/activity_main"  
  6.     android:layout_width="match_parent"  
  7.     android:background="@drawable/index_bg"  
  8.     android:layout_height="match_parent">  
  9.   
  10.     <android.support.v17.leanback.widget.HorizontalGridView  
  11.         android:id="@+id/horizontalgridview"  
  12.         android:layout_width="match_parent"  
  13.         android:layout_height="match_parent"  
  14.         android:layout_margin="10dp"  
  15.         app:numberOfRows="2" />  
  16. </RelativeLayout>  
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:background="@drawable/index_bg"
    android:layout_height="match_parent">

    <android.support.v17.leanback.widget.HorizontalGridView
        android:id="@+id/horizontalgridview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="10dp"
        app:numberOfRows="2" />
</RelativeLayout>


接下来,就需要在JAVA代码去实现了。

  1. horizontalgridview=(HorizontalGridView) findViewById(R.id.horizontalgridview);  
  2. horizontalgridview.requestFocus();  
  3. for (int i=0;i<50;i++)  
  4.     mdatas.add("这是测试的"+i);  
  5. MyAdapter adapter=new MyAdapter(this,mdatas);  
  6. horizontalgridview.setAdapter(adapter);  
        horizontalgridview=(HorizontalGridView) findViewById(R.id.horizontalgridview);
        horizontalgridview.requestFocus();
        for (int i=0;i<50;i++)
            mdatas.add("这是测试的"+i);
        MyAdapter adapter=new MyAdapter(this,mdatas);
        horizontalgridview.setAdapter(adapter);

最为关键的就是Adapter的,在这里面要完成获取焦点时的特效,以及通过接口实现Item点击时的处理。

首先,我们自定义一个接口,完成item点击和获取焦点的回调:

  1. public interface OnItemCallBack {  
  2.     public void onFocusChange(View v, boolean hasFocus, int posiotion);  
  3.   
  4.     public void onItemClick(View v, int position);  
  5. }  
public interface OnItemCallBack {
    public void onFocusChange(View v, boolean hasFocus, int posiotion);

    public void onItemClick(View v, int position);
}

接下来,自定义一个内部类,完成点击事件的处理,具体代码如下:

  1. private class MyClick implements View.OnClickListener {  
  2.   
  3.        int position;  
  4.   
  5.        public MyClick(int position) {  
  6.            this.position = position;  
  7.        }  
  8.   
  9.        @Override  
  10.        public void onClick(View v) {  
  11.            if (onItemCallBack != null) {  
  12.                onItemCallBack.onItemClick(v, position);  
  13.            }  
  14.        }  
  15.   
  16.    }  
  17.    public void setOnItemCallBack(OnItemCallBack onItemCallBack) {  
  18.        this.onItemCallBack = onItemCallBack;  
  19.    }  
 private class MyClick implements View.OnClickListener {

        int position;

        public MyClick(int position) {
            this.position = position;
        }

        @Override
        public void onClick(View v) {
            if (onItemCallBack != null) {
                onItemCallBack.onItemClick(v, position);
            }
        }

    }
    public void setOnItemCallBack(OnItemCallBack onItemCallBack) {
        this.onItemCallBack = onItemCallBack;
    }

然后,在定义一个处理获取焦点的内部类,完成获取交单时的处理,具体代码如下:

  1. private class MyFocusChange implements View.OnFocusChangeListener {  
  2.   
  3.        int position;  
  4.        MyViewHolder holder;  
  5.   
  6.        public MyFocusChange(int position, MyViewHolder holder) {  
  7.            this.position = position;  
  8.            this.holder = holder;  
  9.        }  
  10.   
  11.        @Override  
  12.        public void onFocusChange(View v, boolean hasFocus) {  
  13.            if (hasFocus) {  
  14.                holder.rl_scale.animate().scaleX(1.15f).scaleY(1.15f).start();  
  15.                holder.rl_scale.setBackgroundResource(R.drawable.bg_pic_s);  
  16.            } else {  
  17.                holder.rl_scale.animate().scaleX(1f).scaleY(1f).start();  
  18.                holder.rl_scale.setBackgroundResource(R.drawable.bg_pic_n);  
  19.            }  
  20.            if (onItemCallBack != null) {  
  21.                onItemCallBack.onFocusChange(v, hasFocus, position);  
  22.            }  
  23.        }  
  24.   
  25.    }  
 private class MyFocusChange implements View.OnFocusChangeListener {

        int position;
        MyViewHolder holder;

        public MyFocusChange(int position, MyViewHolder holder) {
            this.position = position;
            this.holder = holder;
        }

        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (hasFocus) {
                holder.rl_scale.animate().scaleX(1.15f).scaleY(1.15f).start();
                holder.rl_scale.setBackgroundResource(R.drawable.bg_pic_s);
            } else {
                holder.rl_scale.animate().scaleX(1f).scaleY(1f).start();
                holder.rl_scale.setBackgroundResource(R.drawable.bg_pic_n);
            }
            if (onItemCallBack != null) {
                onItemCallBack.onFocusChange(v, hasFocus, position);
            }
        }

    }

到此,整个功能就实现了,最后粘上Adapter的整个代码:

  1. package cn.chinaiptv.horiziengridviewdemo;  
  2.   
  3. import android.content.Context;  
  4. import android.support.v7.widget.RecyclerView;  
  5. import android.view.LayoutInflater;  
  6. import android.view.View;  
  7. import android.view.ViewGroup;  
  8. import android.widget.ImageView;  
  9. import android.widget.LinearLayout;  
  10. import android.widget.RelativeLayout;  
  11. import android.widget.TextView;  
  12.   
  13. import java.util.ArrayList;  
  14.   
  15. /** 
  16.  * Created by Administrator on 2016/12/9. 
  17.  */  
  18.   
  19. public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {  
  20.     private Context context;  
  21.     private ArrayList<String> mdatas;  
  22.     private OnItemCallBack onItemCallBack;  
  23.     public MyAdapter(Context context, ArrayList<String> mdatas) {  
  24.         this.context = context;  
  25.         this.mdatas = mdatas;  
  26.     }  
  27.   
  28.     @Override  
  29.     public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
  30.         View inflate = LayoutInflater.from(context).inflate(  
  31.                 R.layout.item, null);  
  32.         MyViewHolder holder = new MyViewHolder(inflate);  
  33.         return holder;  
  34.     }  
  35.   
  36.     @Override  
  37.     public void onBindViewHolder(MyAdapter.MyViewHolder holder, int position) {  
  38.         holder.tv_text.setText(mdatas.get(position));  
  39.         holder.itemView.setOnClickListener(new MyClick(position));  
  40.         holder.itemView.setOnFocusChangeListener(new MyFocusChange(position,  
  41.                 holder));  
  42.     }  
  43.   
  44.     @Override  
  45.     public int getItemCount() {  
  46.         return mdatas.size();  
  47.     }  
  48.   
  49.     class MyViewHolder extends RecyclerView.ViewHolder{  
  50.         public ImageView iv_pic;  
  51.         public TextView tv_text;  
  52.         public RelativeLayout rl_scale;  
  53.         public MyViewHolder(View itemView) {  
  54.             super(itemView);  
  55.             iv_pic=(ImageView) itemView.findViewById(R.id.iv_pic);  
  56.             tv_text=(TextView) itemView.findViewById(R.id.tv_text);  
  57.             rl_scale=(RelativeLayout) itemView.findViewById(R.id.rl_scale);  
  58.         }  
  59.     }  
  60.   
  61.   
  62.     private class MyFocusChange implements View.OnFocusChangeListener {  
  63.   
  64.         int position;  
  65.         MyViewHolder holder;  
  66.   
  67.         public MyFocusChange(int position, MyViewHolder holder) {  
  68.             this.position = position;  
  69.             this.holder = holder;  
  70.         }  
  71.   
  72.         @Override  
  73.         public void onFocusChange(View v, boolean hasFocus) {  
  74.             if (hasFocus) {  
  75.                 holder.rl_scale.animate().scaleX(1.15f).scaleY(1.15f).start();  
  76.                 holder.rl_scale.setBackgroundResource(R.drawable.bg_pic_s);  
  77.             } else {  
  78.                 holder.rl_scale.animate().scaleX(1f).scaleY(1f).start();  
  79.                 holder.rl_scale.setBackgroundResource(R.drawable.bg_pic_n);  
  80.             }  
  81.             if (onItemCallBack != null) {  
  82.                 onItemCallBack.onFocusChange(v, hasFocus, position);  
  83.             }  
  84.         }  
  85.   
  86.     }  
  87.   
  88.     private class MyClick implements View.OnClickListener {  
  89.   
  90.         int position;  
  91.   
  92.         public MyClick(int position) {  
  93.             this.position = position;  
  94.         }  
  95.   
  96.         @Override  
  97.         public void onClick(View v) {  
  98.             if (onItemCallBack != null) {  
  99.                 onItemCallBack.onItemClick(v, position);  
  100.             }  
  101.         }  
  102.   
  103.     }  
  104.     public void setOnItemCallBack(OnItemCallBack onItemCallBack) {  
  105.         this.onItemCallBack = onItemCallBack;  
  106.     }  
  107. }  
package cn.chinaiptv.horiziengridviewdemo;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import java.util.ArrayList;

/**
 * Created by Administrator on 2016/12/9.
 */

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
    private Context context;
    private ArrayList<String> mdatas;
    private OnItemCallBack onItemCallBack;
    public MyAdapter(Context context, ArrayList<String> mdatas) {
        this.context = context;
        this.mdatas = mdatas;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View inflate = LayoutInflater.from(context).inflate(
                R.layout.item, null);
        MyViewHolder holder = new MyViewHolder(inflate);
        return holder;
    }

    @Override
    public void onBindViewHolder(MyAdapter.MyViewHolder holder, int position) {
        holder.tv_text.setText(mdatas.get(position));
        holder.itemView.setOnClickListener(new MyClick(position));
        holder.itemView.setOnFocusChangeListener(new MyFocusChange(position,
                holder));
    }

    @Override
    public int getItemCount() {
        return mdatas.size();
    }

    class MyViewHolder extends RecyclerView.ViewHolder{
        public ImageView iv_pic;
        public TextView tv_text;
        public RelativeLayout rl_scale;
        public MyViewHolder(View itemView) {
            super(itemView);
            iv_pic=(ImageView) itemView.findViewById(R.id.iv_pic);
            tv_text=(TextView) itemView.findViewById(R.id.tv_text);
            rl_scale=(RelativeLayout) itemView.findViewById(R.id.rl_scale);
        }
    }


    private class MyFocusChange implements View.OnFocusChangeListener {

        int position;
        MyViewHolder holder;

        public MyFocusChange(int position, MyViewHolder holder) {
            this.position = position;
            this.holder = holder;
        }

        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (hasFocus) {
                holder.rl_scale.animate().scaleX(1.15f).scaleY(1.15f).start();
                holder.rl_scale.setBackgroundResource(R.drawable.bg_pic_s);
            } else {
                holder.rl_scale.animate().scaleX(1f).scaleY(1f).start();
                holder.rl_scale.setBackgroundResource(R.drawable.bg_pic_n);
            }
            if (onItemCallBack != null) {
                onItemCallBack.onFocusChange(v, hasFocus, position);
            }
        }

    }

    private class MyClick implements View.OnClickListener {

        int position;

        public MyClick(int position) {
            this.position = position;
        }

        @Override
        public void onClick(View v) {
            if (onItemCallBack != null) {
                onItemCallBack.onItemClick(v, position);
            }
        }

    }
    public void setOnItemCallBack(OnItemCallBack onItemCallBack) {
        this.onItemCallBack = onItemCallBack;
    }
}

到此,就完美实现了此功能。以上仅是自己的见解,如有不足之处欢迎讨论。