在Android中,如何以不同的滚动速度同步scrollview?
我有一些依赖的scrollview方法(当我滚动一个视图时,其他视图也会滚动)。我能够正确地执行此操作,但现在我想管理其他(scrollview2和scrollview3)的滚动方式的速度(当我滚动scrollview1时,scrollview2应滚动+10,scrollview3应滚动+20或任何速度) 我检查是否有一个名为scrollview.scrollto(x,y)的方法。它用于管理滚动,但当我将scollto(x,y+scrollviews(i).getSpeed())增加时,会出现stackOverflow异常 我附上我的代码,请调查这一点,并给我一些如何解决这个问题的建议 我的自定义scrollView类是:在Android中,如何以不同的滚动速度同步scrollview?,android,Android,我有一些依赖的scrollview方法(当我滚动一个视图时,其他视图也会滚动)。我能够正确地执行此操作,但现在我想管理其他(scrollview2和scrollview3)的滚动方式的速度(当我滚动scrollview1时,scrollview2应滚动+10,scrollview3应滚动+20或任何速度) 我检查是否有一个名为scrollview.scrollto(x,y)的方法。它用于管理滚动,但当我将scollto(x,y+scrollviews(i).getSpeed())增加时,会出现s
public class CustomVerticalObserveScroll extends ScrollView {
private GestureDetector mGestureDetector;
View.OnTouchListener mGestureListener;
public CustomVerticalObserveScroll(Context context, AttributeSet attrs) {
super(context, attrs);
mGestureDetector = new GestureDetector(context, new YScrollDetector());
setFadingEdgeLength(0);
// TODO Auto-generated constructor stub
}
private CustomScrollLisner scrollViewListener = null;
public CustomVerticalObserveScroll(Context context) {
super(context);
mGestureDetector = new GestureDetector(context, new YScrollDetector());
setFadingEdgeLength(0);
}
public CustomVerticalObserveScroll(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
mGestureDetector = new GestureDetector(context, new YScrollDetector());
setFadingEdgeLength(0);
}
public void setScrollViewListener(CustomScrollLisner scrollViewListener) {
this.scrollViewListener = scrollViewListener;
}
@Override
protected void onScrollChanged(int x, int y, int oldx, int oldy) {
super.onScrollChanged(x, y, oldx, oldy);
if (scrollViewListener != null) {
scrollViewListener.onScrollChanged(this, x, y, oldx, oldy);
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return super.onInterceptTouchEvent(ev)
&& mGestureDetector.onTouchEvent(ev);
}
// Return false if we're scrolling in the x direction
class YScrollDetector extends SimpleOnGestureListener {
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
if (Math.abs(distanceY) > Math.abs(distanceX)) {
return true;
}
if (Math.abs(distanceX) > Math.abs(distanceY)) {
return true;
}
return false;
}
}
}
我用这段代码来创建与滚动相关的滚动视图
public class RelativePanoFeature implements IFeaturetype, OnTouchListener {
private String type;
private FeatureCordinates locationCordinates;
private int mOrientation;
private String image;
private FeatureCordinates triggerCordinates;
private String scrollDirection;
private String scrollSpeed;
private String scrollHandler;
CustomVerticalObserveScroll vertical_scroll;
CustomHorizontalObserveScroll horizontal_scroll;
RelativeLayout vsChild;
long timeonDown, timeonUp;
Thread t;
Handler mhandler;
float downx, downy;
int touchId;
public static int scrollid = 0;
public static ArrayList<RelativePanoHandler> storePanoHandler = new ArrayList<RelativePanoHandler>();
public RelativePanoFeature(String type) {
this.type = type;
}
@Override
public void setType(String type) {
this.type = type;
}
@Override
public String getType() {
return type;
}
public void setImage(String image) {
this.image = image;
}
public String getImage() {
return image;
}
public FeatureCordinates getLocation() {
return locationCordinates;
}
public void setLocation(FeatureCordinates featureCordinates) {
this.locationCordinates = featureCordinates;
}
public void setOrientation(int mOrientation) {
this.mOrientation = mOrientation;
}
public int getOrientation() {
return mOrientation;
}
public FeatureCordinates getTrigger() {
return triggerCordinates;
}
public void setTrigger(FeatureCordinates trigger) {
this.triggerCordinates = trigger;
}
public void setScrollDirection(String scrollDirection) {
this.scrollDirection = scrollDirection;
}
public String getScrollDirection() {
return scrollDirection;
}
public void setScrollSpeed(String scrollSpeed) {
this.scrollSpeed = scrollSpeed;
}
public String getScrollSpeed() {
return scrollSpeed;
}
public void setScrollHandler(String scrollHandler) {
this.scrollHandler = scrollHandler;
}
public String getScrollHandler() {
return scrollHandler;
}
public void setTouchId(int touchid) {
this.touchId = touchid;
}
public int getTOuchId() {
return touchId;
}
/* function to draw relative pano */
public void drawRelativePano(final Context con,
final RelativeLayout parent, final Handler handle) {
/* splitting the path from images key in the string */
RelativePanoHandler panHandler = new RelativePanoHandler();
final int height;
final int width;
vsChild = new RelativeLayout(con);
mhandler = handle;
/* giving size of of vertical scroll's child */
LayoutParams imageViewLayoutParams = new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
vsChild.setLayoutParams(imageViewLayoutParams);
/* splitting the path from images key in the string */
String path[] = getImage().split("images");
try {
/* Initialise loader to load the image inside child */
BackgroundImageLoader loader = new BackgroundImageLoader(vsChild,
Property.FILEPATH + path[1], con);
try {
loader.execute();
} catch (IllegalStateException e) {
e.printStackTrace();
}
/* getting height and width of image from loader object */
height = loader.get().getHeight();
width = loader.get().getWidth();
/*
* condition for putting the child view in vertical scroll and
* implementing the multi directional scroll for event pano
*/
int locWidth = getLocation().getWidth(), locHeight = getLocation()
.getHeight();
System.out.println("Width= " + width + " Location width= "
+ locWidth);
System.out.println("Heoght= " + height + " Location Height= "
+ locHeight
);
if (width > (getLocation().getWidth())
|| height > (getLocation().getHeight())) {
vertical_scroll = new CustomVerticalObserveScroll(con);
horizontal_scroll = new CustomHorizontalObserveScroll(con);
vertical_scroll.setFillViewport(true);
horizontal_scroll.setFillViewport(true);
vertical_scroll.setId(scrollid);
horizontal_scroll.setFadingEdgeLength(0);
/*
* adding the soft later on vertical and horizontal scroll if
* the detected device is on api level 10 or more than that
*/
if (Build.VERSION.SDK_INT > 10) {
vertical_scroll
.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
horizontal_scroll.setLayerType(View.LAYER_TYPE_SOFTWARE,
null);
}
vsChild.setEnabled(true);
/*
* parameters for setting the height and width of vertical
* scroll
*/
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
getLocation().getWidth(), getLocation().getHeight());
params.leftMargin = getLocation().getX();
params.topMargin = getLocation().getY();
vertical_scroll.setLayoutParams(params);
/* adding vertical scroll child this child will hold the image */
vertical_scroll.addView(vsChild, width, height);
horizontal_scroll.setLayoutParams(params);
/*
* adding vertical scroll as a child of horizontal scroll for
* multidirectional scrolling
*/
horizontal_scroll.addView(vertical_scroll);
/*
* at last add this horizontal scroll in side parent which will
* hold the multidirectional scroll
*/
parent.setTag(getScrollHandler());
parent.addView(horizontal_scroll);
// vertical_scroll.setId(id)
panHandler.setVerticalScroll(vertical_scroll);
panHandler.setHandlerTag(getScrollHandler());
panHandler.setPanoSpeed(Integer.parseInt(getScrollSpeed()));
storePanoHandler.add(panHandler);
int size = storePanoHandler.size();
System.out.println("Vertical Scroll objec size=" + size);
}
System.out.println("TAg= " + parent.getTag());
String scdir = getScrollDirection();
System.out.println("Scroll Directoion= " + scdir);
scrollid++;
if (getScrollDirection().equalsIgnoreCase("Y")) {
vertical_scroll.setScrollViewListener(new CustomScrollLisner() {
@Override
public void onScrollChanged(
CustomHorizontalObserveScroll scrollView, int x,
int y, int oldx, int oldy) {
}
@Override
public void onScrollChanged(
CustomVerticalObserveScroll scrollView, int x,
int y, int oldx, int oldy) {
if (scrollView == storePanoHandler.get(getTOuchId())
.getVerticalScroll()) {
for (int i = 0; i < storePanoHandler.size(); i++) {
storePanoHandler.get(i).getVerticalScroll()
.scrollTo(x, y);
storePanoHandler.get(i).getVerticalScroll().
// storePanoHandler.
// .get(i)
// .getVerticalScroll()
// .scrollTo(
// x,
// oldy
// + storePanoHandler.get(
// i)
// .getPanoSpeed());
}
}
}
});
}
// if (getScrollDirection().equalsIgnoreCase("X")) {
// vertical_scroll.setScrollViewListener(new CustomScrollLisner() {
//
// @Override
// public void onScrollChanged(
// CustomHorizontalObserveScroll scrollView, int x,
// int y, int oldx, int oldy) {
// // if (scrollView == storePanoHandler.get(getTOuchId())
// // .getVerticalScroll()) {
// //
// // for (int i = 0; i < storePanoHandler.size(); i++) {
// // storePanoHandler.get(i).getVerticalScroll()
// // .smoothScrollTo(x, y);
// //
// // }
// // }
// }
//
// @Override
// public void onScrollChanged(
// CustomVerticalObserveScroll scrollView, int x,
// int y, int oldx, int oldy) {
// }
// });
// }
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
/*
* set touch listeners on vertical and horizontal scrolls it will use to
* disable the scroll for it's parent like [image or view pager when
* user interacting with any of custom scroll]
*/
horizontal_scroll.setOnTouchListener(this);
vertical_scroll.setOnTouchListener(this);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
boolean scrollingPanaroma = true;
// changing token value for getting scroll
if (v == vertical_scroll || v == horizontal_scroll) {
/*
* Disabling the parent control [list, pager] when user interacting
* with multidirectional scroll
*/
System.out.println("Pano touch Id= " + vertical_scroll.getId());
setTouchId(vertical_scroll.getId());
if (scrollingPanaroma == true) {
v.getParent().getParent().getParent()
.requestDisallowInterceptTouchEvent(true);
}
/*
* enable the parent control [list, pager] when user done with
* multidirectional scroll
*/
else {
v.getParent().getParent().getParent()
.requestDisallowInterceptTouchEvent(false);
}
}
return false;
}
}
公共类RelativePanoFeature实现IFeaturetype,OnTouchListener{
私有字符串类型;
私人设施科迪纳特酒店位置科迪纳特酒店;
私人托管;
私有字符串图像;
私人特征心形物触发心形物;
私有字符串滚动方向;
私有字符串滚动速度;
私有字符串处理程序;
自定义垂直观察滚动垂直滚动;
自定义水平观察滚动水平滚动;
相对年轻人;
时间长了,时间长了;
螺纹t;
汉德勒;
飘落,飘落;
int-touchId;
公共静态int scrollid=0;
公共静态ArrayList storePanoHandler=新ArrayList();
公共RelativePanoFeature(字符串类型){
this.type=type;
}
@凌驾
公共void集合类型(字符串类型){
this.type=type;
}
@凌驾
公共字符串getType(){
返回类型;
}
公共void setImage(字符串图像){
这个图像=图像;
}
公共字符串getImage(){
返回图像;
}
公共功能Cordinates getLocation(){
返回位置cordinates;
}
公共无效设置位置(特征坐标系特征坐标系){
this.locationCordinates=特征cordinates;
}
公共空间设置方向(内部安装){
this.morentation=morentation;
}
public int getOrientation(){
复生;
}
公共特性cordinates getTrigger(){
返回触发器cordinates;
}
public void设置触发器(FeatureCordinates触发器){
this.triggerCordinates=触发器;
}
公共void设置滚动方向(字符串滚动方向){
this.scrollDirection=滚动方向;
}
公共字符串getScrollDirection(){
返回方向;
}
公共无效设置滚动速度(字符串滚动速度){
this.scrollSpeed=滚动速度;
}
公共字符串getScrollSpeed(){
返回速度;
}
public void setScrollHandler(字符串scrollHandler){
this.scrollHandler=scrollHandler;
}
公共字符串getScrollHandler(){
返回处理程序;
}
公共无效setTouchId(int-touchid){
this.touchId=touchId;
}
公共int getTOuchId(){
返回touchId;
}
/*绘制相对全景的函数*/
公共无效图纸编号(最终上下文con,
最终相对性(父级,最终处理程序句柄){
/*从字符串中的图像键拆分路径*/
RelativePanHandler=新的RelativePanHandler();
最终整数高度;
最终整型宽度;
vsChild=新的相对值(con);
mhandler=手柄;
/*给出垂直卷轴的子对象的大小*/
LayoutParams imageViewLayoutParams=新的LayoutParams(
LayoutParams.WRAP_内容,LayoutParams.WRAP_内容);
vsChild.setLayoutParams(imageViewLayoutParams);
/*从字符串中的图像键拆分路径*/
字符串路径[]=getImage().split(“图像”);
试一试{
/*初始化加载程序以加载子系统中的图像*/
BackgroundImageLoader=新的BackgroundImageLoader(vsChild,
Property.FILEPATH+路径[1],con);
试一试{
loader.execute();
}捕获(非法状态){
e、 printStackTrace();
}
/*从loader对象获取图像的高度和宽度*/
height=loader.get().getHeight();
width=loader.get().getWidth();
/*
*将子视图置于垂直滚动和
*实现事件全景的多方向滚动
*/
int locWidth=getLocation().getWidth(),locHeight=getLocation()
.getHeight();
System.out.println(“Width=“+Width+”位置宽度=”
+locWidth);
System.out.println(“Heoght=“+height+”位置高度=”
+洛希特
);
如果(宽度>(getLocation().getWidth())
||高度>(getLocation().getHeight()){
垂直滚动=新自定义垂直观测滚动(con);
水平滚动=新客户水平观测滚动(con);
垂直滚动。setFillViewport(真);
水平滚动。设置填充视口(真);
垂直滚动设置ID(滚动ID);
水平滚动。设置渐变边长度(0);
/*
*如果需要,请稍后在垂直和水平滚动上添加软键
*检测到的设备的api级别为10或更高
*/
如果(Build.VERSION.SDK_INT>10){
垂直滚动
.setLayerType(View.LAYER\u TYPE\u软件,空);
水平滚动。设置图层类型(View.LAYER类型)软件,
无效);
}
vsChild.setEnabled(true);
/
new CountDownTimer(2000, 20) {
public void onTick(long millisUntilFinished) {
hv.scrollTo((int) (2000 - millisUntilFinished), 0);
}
public void onFinish() {
}
}.start();
private OverScroller myScroller;
private void init()
{
try
{
Class parent = this.getClass();
do
{
parent = parent.getSuperclass();
} while (!parent.getName().equals("android.widget.HorizontalScrollView"));
Log.i("Scroller", "class: " + parent.getName());
Field field = parent.getDeclaredField("mScroller");
field.setAccessible(true);
myScroller = (OverScroller) field.get(this);
} catch (NoSuchFieldException e)
{
e.printStackTrace();
} catch (IllegalArgumentException e)
{
e.printStackTrace();
} catch (IllegalAccessException e)
{
e.printStackTrace();
}
}
public void customSmoothScrollBy(int dx, int dy)
{
if (myScroller == null)
{
smoothScrollBy(dx, dy);
return;
}
if (getChildCount() == 0)
return;
final int width = getWidth() - getPaddingRight() - getPaddingLeft();
final int right = getChildAt(0).getWidth();
final int maxX = Math.max(0, right - width);
final int scrollX = getScrollX();
dx = Math.max(0, Math.min(scrollX + dx, maxX)) - scrollX;
myScroller.startScroll(scrollX, getScrollY(), dx, 0, 500);
invalidate();
}
public void customSmoothScrollTo(int x, int y)
{
customSmoothScrollBy(x - getScrollX(), y - getScrollY());
}
ObjectAnimator anim = ObjectAnimator.ofInt(mScrollView, "scrollY", mScrollView.getBottom());
anim.setDuration(9000);
anim.start();
mScrollView = (ScrollView) findViewById(R.id.scrollView1);