应该做过android tv开发的同学都知道,在TV上使用GridView的时候,如果焦点上下移动的时候,如果移动到在屏幕上可见的第一行或者最后一行的时候,如果再继续上下移动,

的话,是比较生硬呆滞的的上下滚动页面,焦点移动到下一个item上,这是非常不太好的体验效果,我们要的是比较平滑的滚动效果。

首先我们要来了解一下GridView的如下这个方法:

smoothScrollToPositionFromTop(int position,int offset,int duration);

滚动到position项目的位置,并且position项目距离GirdView上边的距离为offset个像素,duration指定滚动需要的时间(毫秒)。

这个方法是今天的主角,虽然是主角,但不是说只有使用这个方法就可以了?当然不是,当然也需要一定的逻辑算法配合。

今天就说说我是如何实现的。

先说说我的思路:

首先你要知道当前item所在的行,才知道按上下按键的时候,要滚动到哪一个postion。

public class AppsGridViewAdapter extends BaseAdapter {private int mCurrentSelectedPosition = 0;private int mLastSelectedPosition = 0;private static final int ITEM_BG_COLORS[] = new int[]{Color.parseColor("#e0c101"),Color.parseColor("#fbaf54"),Color.parseColor("#684cb5"),Color.parseColor("#23a5ba"),Color.parseColor("#03ba9f"),Color.parseColor("#88c04c"),Color.parseColor("#684cb5"),Color.parseColor("#23a5ba"),Color.parseColor("#03ba9f"),Color.parseColor("#88c04c"),Color.parseColor("#e0c101"),Color.parseColor("#fbaf54"),};private int mColorIndex = 0;private List<AppInfo> mApps = new ArrayList<AppInfo>();private Context mContext;private int mGridViewRows = 0;public AppsGridViewAdapter(Context context, List<AppInfo> apps) {this.mContext = context;if(apps!=null)this.mApps = apps;setRows();mColorIndex = 0;}private void setRows() {int remainder = mApps.size() % 6;mGridViewRows =(remainder == 0)? (this.mApps.size() > 0 ?  this.mApps.size() / 6:0) : (mApps.size() / 6) +1;}public int getNumRows() {return mGridViewRows;}public int getNumColumns(){return 6;}@Overridepublic void notifyDataSetChanged() {mColorIndex = 0;super.notifyDataSetChanged();}public void setApps(List<AppInfo> apps){mApps.clear();if(apps!=null)mApps = apps;setRows();}public void addApp(AppInfo app){if(app!=null && app.isValidate())mApps.add(app);setRows();}public void removeApp(AppInfo app){if(app!=null)mApps.remove(app);setRows();}public int getCurrentSelectedPosition() {return mCurrentSelectedPosition;}public int getLastSelectedPosition() {return mLastSelectedPosition;}@Overridepublic int getCount() {return mApps.size();}@Overridepublic Object getItem(int position) {return mApps.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder = null;if(convertView == null){convertView = View.inflate(mContext, R.layout.apps_page_gridview_item_layout, null);holder = new ViewHolder();holder.mAppIcon = (ImageView) convertView.findViewById(R.id.app_icon);holder.mAppName = (TextView) convertView.findViewById(R.id.app_name);holder.mAppIconColorBg = (RelativeLayout) convertView.findViewById(R.id.app_icon_color_bg);convertView.setTag(holder);}holder = (ViewHolder) convertView.getTag();holder.mAppName.setText(mApps.get(position).getName());holder.mAppIcon.setBackgroundDrawable(mApps.get(position).getIcon());holder.mAppIconColorBg.setBackgroundColor(ITEM_BG_COLORS[mColorIndex]);++mColorIndex;mColorIndex =( (mColorIndex / 6) != 0 && (mColorIndex / 6) % 2 == 0 ) ? 0 :mColorIndex;return convertView;}private static final class ViewHolder{private ImageView mAppIcon;private TextView mAppName;private RelativeLayout mAppIconColorBg;}}

我们看到,Adapter中定一个了两个方法,可以用来获取多少行,和多少列(列一般是已知的)。

setRows() ;是每次设置给adapter数据的时候,都重新弄设置一下总行数。

getNumRows,返回获取当前所有的行数,getNumColumns返回所有的列数。

OK,接下来,我们就可以通过postion来算出当前选中的postion在哪一行了。

package net.sunniwell.projector.luncher.page;import java.util.List;import net.sunniwell.projector.luncher.CategoryPageActivity;
import net.sunniwell.projector.luncher.R;
import net.sunniwell.projector.luncher.adapter.AppsGridViewAdapter;
import net.sunniwell.projector.luncher.bean.AppInfo;
import net.sunniwell.projector.luncher.engine.PackageAsyncTask;
import net.sunniwell.projector.luncher.engine.PackageAsyncTask.OnQueryPackageStateListener;
import net.sunniwell.projector.luncher.engine.PackageEngine;
import net.sunniwell.projector.luncher.engine.PackageEngine.OnPackageStateChangeListener;
import net.sunniwell.projector.luncher.views.CommonGridView;
import android.content.Intent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.TextView;
/*** * @author zhanghuagang 2017.7.6**/
public class AppsPage extends BasePage implements OnPackageStateChangeListener, OnItemSelectedListener,OnQueryPackageStateListener ,OnItemClickListener{static{sCategory = 3;}private int mCurrentRow = 0;private TextView mIndexTextView;private CommonGridView mGridView;private AppsGridViewAdapter mAppsAdapter;private PackageAsyncTask mAsyncTask;private PackageEngine mPackageEngine;public AppsPage(CategoryPageActivity activity, ViewGroup contentView,int category) {super(activity, contentView, category);this.mPackageEngine = PackageEngine.getDefault(activity);this.mPackageEngine.setOnPackageStateChangeListener(this);}@Overridepublic void initView() {mIndexTextView = (TextView) mContentView.findViewById(R.id.index_textview);mGridView = (CommonGridView) mContentView.findViewById(R.id.apps_gridview);mGridView.setOnItemSelectedListener(this);mGridView.setOnItemClickListener(this);mAppsAdapter = new AppsGridViewAdapter(mActivity,null);mGridView.setAdapter(mAppsAdapter);mAppsAdapter.notifyDataSetChanged();}@Overridepublic void onResume() {mPackageEngine.register();queryApps();}private void queryApps() {if(mAsyncTask!=null)mAsyncTask.stop();mAsyncTask = new PackageAsyncTask(mActivity, this);mAsyncTask.start();}@Overridepublic void onStop() {}@Overridepublic void onPause() {mPackageEngine.unregister();}@Overridepublic void onDestroy() {}private int getItemIndex(int position){int r = position % mAppsAdapter.getNumColumns() ;if(r  == 0){if(position > 0 ){return (position/mAppsAdapter.getNumColumns())+1;}else{return 1;}}else{return (position/mAppsAdapter.getNumColumns())+1;}}@Overridepublic void onItemSelected(AdapterView<?> parent, View view, int position,long id) {if(getItemIndex(position) > mCurrentRow){mGridView.smoothScrollToPositionFromTop(position, 0,500);}else if(getItemIndex(position) < mCurrentRow){mGridView.smoothScrollToPositionFromTop(position-2, 0,500);}mGridView.onItemSelected(parent, view, position, id);mIndexTextView.setText(getItemIndex(position)+"  |  "+mAppsAdapter.getNumRows());mCurrentRow =getItemIndex(position); }@Overridepublic void onNothingSelected(AdapterView<?> parent) {}@Overridepublic void onFinish(List<AppInfo> apps) {mAppsAdapter.setApps(apps);mAppsAdapter.notifyDataSetChanged();}@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position,long id) {AppInfo app = (AppInfo) mAppsAdapter.getItem(position);if(app!=null){final Intent intent = new Intent();intent.setClassName(app.packageName, app.className);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);mActivity.startActivity(intent);}}@Overridepublic void onPackageAdded(AppInfo app) {mAppsAdapter.addApp(app);mAppsAdapter.notifyDataSetChanged();}@Overridepublic void onPackageDeleted(AppInfo app) {mAppsAdapter.removeApp(app);mAppsAdapter.notifyDataSetChanged();}
}

我的getItemIndex(int postion)就是根据position获取当前所在行的。

然后我们在onItemSelected对平滑滑动做处理。

如果下一个获取焦点的item所在行小于当前行,说明是向上按的,如果是大于当前行,说明是向下按住的。

这里我们特殊的处理的向下按的,position-2,这个意思就是当我向下按的时候,每次移动两个postion的距离,并且postion和边缘距离为0

android GridView 在TV上,上下翻页的时候平滑滑动的实现相关推荐

  1. Android自定义控件之3D上下翻页效果的倒计时控件

    这是一个自定义的倒计时控件,具有3D上下翻页翻转效果.最近项目中需要做一个倒计时控件,需要和iOS端的效果保持一样.大致效果是这样的,如下图所示: 由于暂时还不会怎么样制作gif动态图,所以想看具体效 ...

  2. 在PHP当中制作隔行换色的效果以及制作上下翻页的效果!

    首先说明隔行换色的效果,需要用到tr:nth_child(odd);或者括号里的值是even,odd是从第一行开始隔一行,even是从第二行开始: 具体代码如下图案所示: 1 <style> ...

  3. 手机qq浏览器怎么设置上下翻页按钮 手机qq浏览器设置上下翻页按钮的方法

    1.打开qq浏览器,点击右下角"我的". 手机qq浏览器怎么设置上下翻页按钮?手机qq浏览器设置上下翻页按钮的方法[多图] 2.点击右上角设置图标. 手机qq浏览器怎么设置上下翻页 ...

  4. HTML5手机页面触屏滑动上下翻页特效

    和手机桌面管理的翻页特效一样,这个是html5实现上下翻页 下载地址: http://www.webkfa.com/one328/w1026.html

  5. html表格翻页简单,利用jQuery实现一个简单的表格上下翻页效果

    前言 本文主要介绍的是利用jQuery实现一个简单的表格上下翻页效果,注:实现原理与轮播图相似.下面话不多说,来看看详细的 实现方法吧. html: 日期参与团购场次团购结果当前状态 02.08 第一 ...

  6. 康佳android 9tv,康佳易TV史上最大规模系统升级 安卓4.4体验

    康佳作为家电领域的领跑企业,不仅注重硬件上的研发,以核芯驱动技术发展,不断提高电视的性能:更以软件方面的研发见长,创新的研发出了YIUI易柚系统,致力于打造最专业的电视操控系统.YIUI易柚一经推出, ...

  7. CentOs上下翻页

    在windows上虚拟机中安装的CentOS,在命令窗口输入某个命令后,显示的内容较多,但是我想看前面几行的内容,可以使用下面的按键进行上下翻页的操作: 向上翻页查看 Shift + PgUp 向下翻 ...

  8. html 上下翻页效果代码,原生js实现可以带上下翻页的翻页功能(代码)

    本篇文章给大家带来的内容是关于原生js实现可以带上下翻页的翻页功能(代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 翻页功能在渲染数据时经常用到,下面是使用原生JS去实现的一个 ...

  9. Linux 命令之 less -- 分屏上下翻页浏览文件内容(查看文件内容/显示文件内容)

    文章目录 介绍 语法格式 常用选项 浏览文本内容的快捷键 向前滚屏 向后滚屏 跳跃 搜索 退出 less 参考示例 (一)查看文件 (二)ps查看进程信息并通过less分页显示 (三)查看命令历史使用 ...

最新文章

  1. 五分钟搞懂MySQL索引下推
  2. SQL Server 2005 Compact Edition 程序设计与性能优化
  3. Oracle数据库管理员职责(二)
  4. php数组重置,php 重置数组索引,兼容多维数组
  5. STL 算法/容器——总论
  6. centos7 redis分布式集群问题总结
  7. X-Cache和X-Pad
  8. 智能电视机顶盒开发记录
  9. linux下安装rabbitMQ和springboot+rabbitMQ使用案例
  10. 将字符串中的英文大写字母换成小写字母-c语言实现
  11. 微信企业号服务器搭建,微信企业号开发之如何建立连接
  12. 安卓自定义view仿小米商城购物车动画
  13. 尚硅谷算法与数据结构学习笔记05 -- 递归
  14. pdf 能打开但不能打印复制
  15. oracle 版本演进,【比较】Oracle不同版本中关于ALTER TABLESPACE的功能演进
  16. 【渝粤题库】陕西师范大学151209 财务报告分析 作业(高起专、专升本)
  17. 会计学原理学习笔记——第一章——总论(1.5会计目标)
  18. vuejs视图不能及时更新的问题 ,深入响应式原理
  19. Java学习20天 String 类 常用方法 String、StringBuffer、StringBuilder三者的异同
  20. “开放共享与价值回归”2022开放原子全球开源峰会区块链分论坛成功举办

热门文章

  1. 充电宝买1万还是2万?充电宝2w和1w的哪个耐用
  2. 前端数据交互的五种方式
  3. PDA程序安装制作(zt)
  4. python1到100累加_python 累加100
  5. 阿里资深架构师——支付宝和蚂蚁花呗的技术架构及双十一实践
  6. Win 7 下eclipse添加Courier New字体
  7. DLSS/NIS/FSR
  8. QT学习笔记(4) 信号和槽
  9. linux服务器杀进程,linux杀死进程命令
  10. arm64入栈出栈_使用 ARM64 汇编实现共享栈式协程