2D滚动,支持RTL布局
2D Scrolling, supporting RTL layout
最近,我们开始添加对阿拉伯语的支持——这需要 RTL 布局。我们的一个屏幕使用了 2D 滚动条,我在这里找到了它:
但是,当我们切换到 RTL 时,有两个问题:
childview
被截断
- 最初不想向左滚动,但允许向右滚动(远离 child 视图)。
我已经尝试查看 Horizontal scrollview
的源代码 - 它可以正确处理 rtl。到目前为止,我只在代码中看到两个对 rtl 的引用:在 onLayout()
期间。但是,当我尝试类似的操作时,我的 child 视图就消失了。
到目前为止,我找不到其他同时支持 2d 滚动和 rtl 的解决方案。所以,我希望在这里为我和未来需要类似东西的灵魂解决它。
好的,所以将一大堆不同的解决方案放在一起:
创建两个自定义组件,一个扩展 ScrollView,另一个扩展 Horizontal ScrollView:
public class VScroll extends ScrollView {
public VScroll(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public VScroll(Context context, AttributeSet attrs) {
super(context, attrs);
}
public VScroll(Context context) {
super(context);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return false;
}
}
和
public class HScroll extends HorizontalScrollView {
public HScroll(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public HScroll(Context context, AttributeSet attrs) {
super(context, attrs);
}
public HScroll(Context context) {
super(context);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return false;
}
}
在需要“2d 滚动条”的 activity 中,使用以下命令:
在 OnCreate() 中:
vScroll = findViewById(R.id.vScroll);
hScroll = findViewById(R.id.hScroll);
然后
private VelocityTracker mVelocityTracker;
private float mx, my;
private float curX, curY;
private boolean started;
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(event);
curX = event.getX();
curY = event.getY();
int dx = (int) (mx - curX);
int dy = (int) (my - curY);
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
if (started) {
vScroll.smoothScrollBy(0, dy);
hScroll.smoothScrollBy(dx, 0);
} else {
started = true;
}
mx = curX;
my = curY;
break;
case MotionEvent.ACTION_UP:
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000);
int initialXVelocity = (int) velocityTracker.getXVelocity();
int initialYVelocity = (int) velocityTracker.getYVelocity();
vScroll.fling(-initialYVelocity);
hScroll.fling(-initialXVelocity);
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
}
return true;
}
这允许双向滚动(是的,甚至是对角线滚动)以及一些速度以允许 'fling' 效果。最重要的是,它可以很好地与 RTL 和 LTR 布局配合使用!希望这对其他人也有用....
编辑:忘记添加 XML 部分:
<pack.customcomponents.VScroll android:layout_height="fill_parent"
android:layout_width="fill_parent" android:id="@+id/vScroll">
<pack.customcomponents.HScroll android:id="@+id/hScroll"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:id="@+id/view_to_scroll"/>
</pack.customcomponents.HScroll>
</pack.customcomponents.VScroll>
最近,我们开始添加对阿拉伯语的支持——这需要 RTL 布局。我们的一个屏幕使用了 2D 滚动条,我在这里找到了它:
但是,当我们切换到 RTL 时,有两个问题:
childview
被截断- 最初不想向左滚动,但允许向右滚动(远离 child 视图)。
我已经尝试查看 Horizontal scrollview
的源代码 - 它可以正确处理 rtl。到目前为止,我只在代码中看到两个对 rtl 的引用:在 onLayout()
期间。但是,当我尝试类似的操作时,我的 child 视图就消失了。
到目前为止,我找不到其他同时支持 2d 滚动和 rtl 的解决方案。所以,我希望在这里为我和未来需要类似东西的灵魂解决它。
好的,所以将一大堆不同的解决方案放在一起:
创建两个自定义组件,一个扩展 ScrollView,另一个扩展 Horizontal ScrollView:
public class VScroll extends ScrollView { public VScroll(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public VScroll(Context context, AttributeSet attrs) { super(context, attrs); } public VScroll(Context context) { super(context); } @Override public boolean onTouchEvent(MotionEvent ev) { return false; } }
和
public class HScroll extends HorizontalScrollView { public HScroll(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public HScroll(Context context, AttributeSet attrs) { super(context, attrs); } public HScroll(Context context) { super(context); } @Override public boolean onTouchEvent(MotionEvent ev) { return false; } }
在需要“2d 滚动条”的 activity 中,使用以下命令: 在 OnCreate() 中:
vScroll = findViewById(R.id.vScroll); hScroll = findViewById(R.id.hScroll);
然后
private VelocityTracker mVelocityTracker;
private float mx, my;
private float curX, curY;
private boolean started;
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(event);
curX = event.getX();
curY = event.getY();
int dx = (int) (mx - curX);
int dy = (int) (my - curY);
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
if (started) {
vScroll.smoothScrollBy(0, dy);
hScroll.smoothScrollBy(dx, 0);
} else {
started = true;
}
mx = curX;
my = curY;
break;
case MotionEvent.ACTION_UP:
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000);
int initialXVelocity = (int) velocityTracker.getXVelocity();
int initialYVelocity = (int) velocityTracker.getYVelocity();
vScroll.fling(-initialYVelocity);
hScroll.fling(-initialXVelocity);
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
}
return true;
}
这允许双向滚动(是的,甚至是对角线滚动)以及一些速度以允许 'fling' 效果。最重要的是,它可以很好地与 RTL 和 LTR 布局配合使用!希望这对其他人也有用....
编辑:忘记添加 XML 部分:
<pack.customcomponents.VScroll android:layout_height="fill_parent"
android:layout_width="fill_parent" android:id="@+id/vScroll">
<pack.customcomponents.HScroll android:id="@+id/hScroll"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:id="@+id/view_to_scroll"/>
</pack.customcomponents.HScroll>
</pack.customcomponents.VScroll>