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比较丑,请见谅):
接下来就一步一步介绍具体的实现方案。
由于项目中使用了HorizontalGridView,所以要引入依赖
- compile 'com.android.support:leanback-v17:24.2.1'
compile 'com.android.support:leanback-v17:24.2.1'
此外使用HorizontalGridView还需要在清单文件中进行声明下
- <uses-feature
- android:name="android.software.leanback"
- android:required="false" />
<uses-feature
android:name="android.software.leanback"
android:required="false" />
到此,准备工作就完毕了,接下来就开始写布局文件了。
- <?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>
<?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代码去实现了。
- 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);
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点击和获取焦点的回调:
- public interface OnItemCallBack {
- public void onFocusChange(View v, boolean hasFocus, int posiotion);
- public void onItemClick(View v, int position);
- }
public interface OnItemCallBack {
public void onFocusChange(View v, boolean hasFocus, int posiotion);
public void onItemClick(View v, int 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;
- }
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;
}
然后,在定义一个处理获取焦点的内部类,完成获取交单时的处理,具体代码如下:
- 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 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的整个代码:
- 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;
- }
- }
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;
}
}
到此,就完美实现了此功能。以上仅是自己的见解,如有不足之处欢迎讨论。