Android-tv-垂直滚动

垂直滚动:

 public class NewScrollView extends ScrollView {
 public NewScrollView(Context context) {
  super(context);
 }
 public NewScrollView(Context context, AttributeSet attrs) {
  super(context, attrs);
 }
 public NewScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
 }
 @Override
 protected int computeScrollDeltaToGetChildRectOnScreen(Rect rect) {
  if (getChildCount() == 0)
   return 0;
  int height = getHeight();
  int screenTop = getScrollY();
  int screenBottom = screenTop + height;
  int fadingEdge = 100;
  if (rect.top > 0) {
   screenTop += fadingEdge;
  }
  if (rect.bottom < getChildAt(0).getHeight()) {
   screenBottom -= fadingEdge;
  }
  //
  int scrollYDelta = 0;
  if (rect.bottom > screenBottom && rect.top > screenTop) {
   if (rect.height() > height) {
    scrollYDelta += (rect.top - screenTop);
   } else {
    scrollYDelta += (rect.bottom - screenBottom);
   }
   int bottom = getChildAt(0).getBottom();
   int distanceToBottom = bottom - screenBottom;
   scrollYDelta = Math.min(scrollYDelta, distanceToBottom);
  } else if (rect.top < screenTop && rect.bottom < screenBottom) {
   if (rect.height() > height) {
    scrollYDelta -= (screenBottom - rect.bottom);
   } else {
    scrollYDelta -= (screenTop - rect.top);
   }
   scrollYDelta = Math.max(scrollYDelta, -getScrollY());
  }
  return scrollYDelta;
 }

横向滚动(原代码,小米):

 public class SmoothHorizontalScrollView extends HorizontalScrollView {
 final String TAG = "SmoothHorizontalScrollView";
 public SmoothHorizontalScrollView(Context context) {
  this(context, null, 0);
 }
 public SmoothHorizontalScrollView(Context context, AttributeSet attrs) {
  this(context, attrs, 0);
 }
 public SmoothHorizontalScrollView(Context context, AttributeSet attrs,
   int defStyle) {
  super(context, attrs, defStyle);
 }
 @Override
 public void scrollBy(int dx, int dy) {
  super.scrollBy(dx, dy);
 }
 @Override
 public void computeScroll() {
  super.computeScroll();
 }
 private int _index = -1;
 public void setTabIndex(int index) {
  _index = index;
 }
 private int _tabcount = -1;
 public void setTabCount(int _count) {
  _tabcount = _count;
 }
 @Override
 public boolean dispatchKeyEvent(KeyEvent event) {
  View currentFocused = findFocus();
  if (currentFocused == this)
   currentFocused = null;
  if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_LEFT
    && event.getAction() == KeyEvent.ACTION_DOWN) {
   View nextFocused = FocusFinder.getInstance().findNextFocus(this,
     currentFocused, View.FOCUS_LEFT);
   if (nextFocused == null && _index == 0) {
    Object obj = currentFocused
      .getTag(R.integer.tag_view_focused_host_view);
    if (MetroCursorView.class.isInstance(obj)) {
     Utils.playKeySound((MetroCursorView) obj,
       Utils.SOUND_ERROR_KEY);
     ((MetroCursorView) obj).showIndicator();
    }
    return true;
   }
   /*
    * } else if(event.getKeyCode() == KeyEvent.KEYCODE_DPAD_DOWN &&
    * event.getAction() == KeyEvent.ACTION_DOWN){ View nextFocused =
    * FocusFinder.getInstance().findNextFocus(this, currentFocused,
    * View.FOCUS_DOWN); if(nextFocused == null){ Object obj =
    * currentFocused.getTag(R.integer.tag_view_focused_host_view);
    * if(MetroCursorView.class.isInstance(obj)){
    * Utils.playKeySound((MetroCursorView)obj, Utils.SOUND_ERROR_KEY);
    * ((MetroCursorView)obj).showIndicator(); } Log.d(TAG,
    * "no move to down"); }
    */
  } else if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_RIGHT
    && event.getAction() == KeyEvent.ACTION_DOWN) {
   View nextFocused = FocusFinder.getInstance().findNextFocus(this,
     currentFocused, View.FOCUS_RIGHT);
   if (nextFocused == null) {
    Object obj = currentFocused
      .getTag(R.integer.tag_view_focused_host_view);
    if (MetroCursorView.class.isInstance(obj)) {
     if (_tabcount != -1 && _index == _tabcount - 1) {
      Utils.playKeySound((MetroCursorView) obj,
        Utils.SOUND_ERROR_KEY);
      ((MetroCursorView) obj).showIndicator();
      return true;
     }
    }
    Log.d(TAG, "no move to right");
   }
  }
  boolean ret = super.dispatchKeyEvent(event);
  if (ret == true
    && (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_RIGHT
      && event.getAction() == KeyEvent.ACTION_DOWN || event
      .getKeyCode() == KeyEvent.KEYCODE_DPAD_LEFT
      && event.getAction() == KeyEvent.ACTION_DOWN)) {
   Utils.playKeySound(this, Utils.SOUND_KEYSTONE_KEY);
  }
  return ret;
 }
 @Override
 protected int computeScrollDeltaToGetChildRectOnScreen(Rect rect) {
  if (getChildCount() == 0)
   return 0;
  int width = getWidth();
  int screenLeft = getScrollX();
  int screenRight = screenLeft + width;
  int fadingEdge = this.getResources().getDimensionPixelSize(
    R.dimen.fading_edge);
  // leave room for left fading edge as long as rect isn‘t at very left
  if (rect.left > 0) {
   screenLeft += fadingEdge;
  }
  // leave room for right fading edge as long as rect isn‘t at very right
  if (rect.right < getChildAt(0).getWidth()) {
   screenRight -= fadingEdge;
  }
  int scrollXDelta = 0;
  if (rect.right > screenRight && rect.left > screenLeft) {
   // need to move right to get it in view: move right just enough so
   // that the entire rectangle is in view (or at least the first
   // screen size chunk).
   if (rect.width() > width) {
    // just enough to get screen size chunk on
    scrollXDelta += (rect.left - screenLeft);
   } else {
    // get entire rect at right of screen
    scrollXDelta += (rect.right - screenRight);
   }
   // make sure we aren‘t scrolling beyond the end of our content
   int right = getChildAt(0).getRight();
   int distanceToRight = right - screenRight;
   scrollXDelta = Math.min(scrollXDelta, distanceToRight);
  } else if (rect.left < screenLeft && rect.right < screenRight) {
   // need to move right to get it in view: move right just enough so
   // that
   // entire rectangle is in view (or at least the first screen
   // size chunk of it).
   if (rect.width() > width) {
    // screen size chunk
    scrollXDelta -= (screenRight - rect.right);
   } else {
    // entire rect at left
    scrollXDelta -= (screenLeft - rect.left);
   }
   // make sure we aren‘t scrolling any further than the left our
   // content
   scrollXDelta = Math.max(scrollXDelta, -getScrollX());
  }
  return scrollXDelta;
 }
 @Override
 protected boolean onRequestFocusInDescendants(int direction,
   Rect previouslyFocusedRect) {
  // convert from forward / backward notation to up / down / left / right
  // (ugh).
  if (previouslyFocusedRect != null) {
   if (direction == View.FOCUS_FORWARD) {
    direction = View.FOCUS_RIGHT;
   } else if (direction == View.FOCUS_BACKWARD) {
    direction = View.FOCUS_LEFT;
   }
   View nextFocus = FocusFinder.getInstance().findNextFocusFromRect(
     this, previouslyFocusedRect, direction);
   if (nextFocus == null) {
    return false;
   }
   return nextFocus.requestFocus(direction, previouslyFocusedRect);
  } else {
   int index;
   int increment;
   int end;
   int count = this.getChildCount();
   if ((direction & FOCUS_FORWARD) != 0) {
    index = 0;
    increment = 1;
    end = count;
   } else {
    index = count - 1;
    increment = -1;
    end = -1;
   }
   for (int i = index; i != end; i += increment) {
    View child = this.getChildAt(i);
    if (child.getVisibility() == View.VISIBLE) {
     if (child.requestFocus(direction, previouslyFocusedRect)) {
      return true;
     }
    }
   }
   return false;
  }
 }
}
时间: 2024-08-09 02:39:48

Android-tv-垂直滚动的相关文章

Android添加垂直滚动ScrollView 常见问题

今天在使用ScrollView时出现错误,提示: Unexpected namespace prefix "xmlns" found for tag ScrollView 布局如下: <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"       xmlns:tools="http://schemas.android.com/tools"       

Android 公告新闻消息资讯之垂直滚动效果

垂直滚动新闻栏的实现原理: 就是一个自定义的LinearLayout,并且textView能够循环垂直滚动,而且条目可以点击,显示区域最多显示2个条目,并且还有交替的属性垂直移动的动画效果,通过线程来控制滚动的实现. ................................................... 自定义属性: <style name="AppTheme" parent="@android:style/Theme.Light.NoTitleBar&

android tv 实现颜色条滚动效果

直接贴代码: ColorView.java package com.xxx.demo; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.util.Log; import android.view.V

Android中TextView如何实现水平和垂直滚动

一.只想让TextView显示一行,但是文字超过TextView的长度怎么办? 在开头显示省略号 android:singleLine="true" android:ellipsize="start" 在结尾显示省略号 android:singleLine="true" android:ellipsize="end" 在中间显示省略号 android:singleLine="true" android:el

Android视图之滚动视图

滚动视图(ScrollView)是当需要显示的信息一个屏幕显示不下时使用的控件. 1.ScrollView概述 ScrollView由FrameLayout派生,同样位于android.widget包下.ScrollView类实际上是一个帧布局,一般情况下,其中的控件是按照线性进行布局的,用户可以对其进行滚动,以达到在屏幕中显示更多信息的目的. 默认情况下,ScrollView只是为其他组件添加垂直滚动条,如果应用需要添加水平滚动条,,则可借助于另一个滚动条视图来实现.ScrollView与Ho

ScrollView垂直滚动控件的使用

一.ScrollView控件只是支持垂直滚动,而且在ScrollView中只能包含一个控件,通常是在< ScrollView >标签中定义了一个<LinearLayout> 标签并且在<LinearLayout>标签中android:orientation属性值设置为vertical,然后在<LinearLayout>标签中放置多个控件,如果<LinearLayout>标签中的控件所占用的总高度超出屏幕的高度,就会在屏幕的右侧出现一个滚动条. 在

Android TV开发总结(五)TV上屏幕适配总结

前言:前面几篇总结一些TV上的小Sample,开源到GitHub:https://github.com/hejunlin2013/TVSample, 点击链接,可以持续关注.今天总结下TV上屏幕适配.: 看下Agenda: 一.屏幕适配的一些背景知识 二.TV屏幕适配怎么适配?有哪些规则? 三.多屏幕适配,android读取res/drawable优先级是什么? 四.屏幕分辨率及density .densityDpi代码 一.屏幕适配的一些背景知识 介绍几个在Android屏幕适配上非常重要的名

Android:TextView 自动滚动(跑马灯) (转)

Android:TextView 自动滚动(跑马灯) TextView实现文字滚动需要以下几个要点: 1.文字长度长于可显示范围:android:singleLine="true" 2.设置可滚到,或显示样式:android:ellipsize="marquee" 3.TextView只有在获取焦点后才会滚动显示隐藏文字,因此需要在包中新建一个类,继承TextView.重写isFocused方法,这个方法默认行为是,如果TextView获得焦点,方法返回true,失

Android View中滚动相关

方法 scrollTo: (内容的左上角)达到某个地点 scrollBy: 根据当前位置,再移动多少 属性: mScrollX, 以下是文档解释 The offset, in pixels, by which the content of this view is scrolled horizontally. mScrollY, 以下是文档解释 The offset, in pixels, by which the content of this view is scrolled vertica

Android 自学之滚动视图ScrollView

滚动视图ScrollView由FarmeLayout派生而出,他就是一个用于为普通组件添加垂直滚动条的组件:ScrollView里面最多包含一个组件,而ScrollView的作用就是为该组件添加一个垂直滚动条.(ScrollView的作用和JScrollPane非常相似,他们甚至不能被称为真正的容器.他们只是为其他的容器添加滚动条.)默认的情况下ScrollView只是为其他组件添加垂直滚动条,如果应用需要水平的滚动条,则可以借助于另一个组件:HorizontalScrollView来实现.Ho