在android中滚动垂直和水平

我真的很疲惫,寻找垂直和水平滚动视图的解决scheme。

我读了框架中没有任何实现此function的视图/布局,但我需要这样的东西:

我需要定义其他的布局,子布局必须实现滚动垂直/水平移动。

最初实现了一个按像素移动布局的代码,但我认为这不是正确的方法。 我用ScrollView和Horizo​​ntal ScrollView试了一下,但没有像我想要的那样工作,因为它只实现了垂直或水平滚动。

canvas不是我的解决scheme,因为我需要在某些子元素中附加侦听器。

我能做什么?

混合上面的一些build议,并能得到一个很好的解决scheme:

自定义滚动视图:

package com.scrollable.view; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.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; } } 

自定义Horizo​​ntalScrollView:

 package com.scrollable.view; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.HorizontalScrollView; 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; } } 

ScrollableImageActivity:

 package com.scrollable.view; import android.app.Activity; import android.os.Bundle; import android.view.MotionEvent; import android.widget.HorizontalScrollView; import android.widget.ScrollView; public class ScrollableImageActivity extends Activity { private float mx, my; private float curX, curY; private ScrollView vScroll; private HorizontalScrollView hScroll; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); vScroll = (ScrollView) findViewById(R.id.vScroll); hScroll = (HorizontalScrollView) findViewById(R.id.hScroll); } @Override public boolean onTouchEvent(MotionEvent event) { float curX, curY; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mx = event.getX(); my = event.getY(); break; case MotionEvent.ACTION_MOVE: curX = event.getX(); curY = event.getY(); vScroll.scrollBy((int) (mx - curX), (int) (my - curY)); hScroll.scrollBy((int) (mx - curX), (int) (my - curY)); mx = curX; my = curY; break; case MotionEvent.ACTION_UP: curX = event.getX(); curY = event.getY(); vScroll.scrollBy((int) (mx - curX), (int) (my - curY)); hScroll.scrollBy((int) (mx - curX), (int) (my - curY)); break; } return true; } } 

布局:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <com.scrollable.view.VScroll android:layout_height="fill_parent" android:layout_width="fill_parent" android:id="@+id/vScroll"> <com.scrollable.view.HScroll android:id="@+id/hScroll" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:layout_width="fill_parent" android:layout_height="fill_parent" android:src="@drawable/bg"></ImageView> </com.scrollable.view.HScroll> </com.scrollable.view.VScroll> </LinearLayout> 

由于这似乎是谷歌“Android vertical + horizo​​ntal ScrollView”的第一个search结果,我想我应该在这里添加这个。 马特·克拉克(Matt Clark)基于Android源代码构build了一个自定义的视图,而且它看起来很完美: 二维滚动视图( Two Dimensional ScrollView)

请注意,该页面中的类有一个错误,计算视图的水平宽度。 曼努埃尔·希尔蒂(Manuel Hilty)的意见是:

解决scheme:将808行中的语句replace为以下内容:

 final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.leftMargin + lp.rightMargin, MeasureSpec.UNSPECIFIED); 

编辑:该链接不工作了,但这是一个旧版本的博客链接 。

我find了更好的解决scheme。

XML:(design.xml)

 <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <FrameLayout android:layout_width="90px" android:layout_height="90px"> <RelativeLayout android:id="@+id/container" android:layout_width="fill_parent" android:layout_height="fill_parent"> </RelativeLayout> </FrameLayout> </FrameLayout> 

Java代码:

 public class Example extends Activity { private RelativeLayout container; private int currentX; private int currentY; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.design); container = (RelativeLayout)findViewById(R.id.container); int top = 0; int left = 0; ImageView image1 = ... RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); layoutParams.setMargins(left, top, 0, 0); container.addView(image1, layoutParams); ImageView image2 = ... left+= 100; RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); layoutParams.setMargins(left, top, 0, 0); container.addView(image2, layoutParams); ImageView image3 = ... left= 0; top+= 100; RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); layoutParams.setMargins(left, top, 0, 0); container.addView(image3, layoutParams); ImageView image4 = ... left+= 100; RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); layoutParams.setMargins(left, top, 0, 0); container.addView(image4, layoutParams); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { currentX = (int) event.getRawX(); currentY = (int) event.getRawY(); break; } case MotionEvent.ACTION_MOVE: { int x2 = (int) event.getRawX(); int y2 = (int) event.getRawY(); container.scrollBy(currentX - x2 , currentY - y2); currentX = x2; currentY = y2; break; } case MotionEvent.ACTION_UP: { break; } } return true; } } 

这是行之有效的!

如果你想加载其他布局或控件,结构是一样的。

我使用它,工作正常:

 <?xml version="1.0" encoding="utf-8"?> <ScrollView android:id="@+id/ScrollView02" android:layout_width="wrap_content" android:layout_height="wrap_content" xmlns:android="http://schemas.android.com/apk/res/android"> <HorizontalScrollView android:id="@+id/HorizontalScrollView01" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageView android:id="@+id/ImageView01" android:src="@drawable/pic" android:isScrollContainer="true" android:layout_height="fill_parent" android:layout_width="fill_parent" android:adjustViewBounds="true"> </ImageView> </HorizontalScrollView> </ScrollView> 

来源链接在这里: Android-spa

我的解决scheme基于Mahdi Hijazi答案 ,但没有任何自定义视图:

布局:

 <HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/scrollHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <ScrollView android:id="@+id/scrollVertical" android:layout_width="wrap_content" android:layout_height="match_parent" > <WateverViewYouWant/> </ScrollView> </HorizontalScrollView> 

代码(onCreate / onCreateView):

  final HorizontalScrollView hScroll = (HorizontalScrollView) value.findViewById(R.id.scrollHorizontal); final ScrollView vScroll = (ScrollView) value.findViewById(R.id.scrollVertical); vScroll.setOnTouchListener(new View.OnTouchListener() { //inner scroll listener @Override public boolean onTouch(View v, MotionEvent event) { return false; } }); hScroll.setOnTouchListener(new View.OnTouchListener() { //outer scroll listener private float mx, my, curX, curY; private boolean started = false; @Override public boolean onTouch(View v, MotionEvent 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.scrollBy(0, dy); hScroll.scrollBy(dx, 0); } else { started = true; } mx = curX; my = curY; break; case MotionEvent.ACTION_UP: vScroll.scrollBy(0, dy); hScroll.scrollBy(dx, 0); started = false; break; } return true; } }); 

您可以更改滚动视图的顺序。 只需在布局和代码中更改它们的顺序。 显然,而不是WateverViewYouWant你把布局/视图你想滚动双向。

选项1:你可以想出一个新的UIdevise,不需要同时进行水平和垂直滚动。

选项2:您可以获得ScrollViewHorizontalScrollView的源代码,了解核心Android团队如何实现这些,并创build自己的BiDirectionalScrollView实现。

选项3:您可以摆脱要求您使用窗口小部件系统并直接绘制到canvas的依赖关系。

选项4:如果你偶然发现一个似乎实现你所寻求的开源应用程序,看看他们是如何做到的。

尝试这个

 <?xml version="1.0" encoding="utf-8"?> <ScrollView android:id="@+id/Sview" android:layout_width="wrap_content" android:layout_height="wrap_content" xmlns:android="http://schemas.android.com/apk/res/android"> <HorizontalScrollView android:id="@+id/hview" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageView ....... [here xml code for image] </ImageView> </HorizontalScrollView> </ScrollView> 

由于二维滚动视图链接死了我无法得到它,所以我创build了我自己的组件。 它处理投掷并为我正常工作。 唯一的限制是wrap_content可能无法正常工作。

https://gist.github.com/androidseb/9902093

我有你的问题的解决scheme。 您可以检查它只处理垂直滚动的ScrollView代码,并忽略水平滚动并修改它。 我想像一个webview的视图,所以修改的滚动视图,它对我很好。 但是这可能不适合你的需要。

让我知道你的目标是什么样的用户界面。

问候,

拉维潘迪特

玩这个代码,你可以把一个Horizo​​ntalScrollView放到一个ScrollView中。 因此,您可以在同一视图中使用两种滚动方法。

资料来源: http : //androiddevblog.blogspot.com/2009/12/creating-two-dimensions-scroll-view.html

我希望这可以帮助你。

要设置垂直和水平滚动条,请参阅http://android-code-crumbs.blogspot.com/