标签:
垂直滚动:
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;
}
}
}
标签:
原文地址:http://my.oschina.net/hailongqiu/blog/471525