在android中滚动垂直和水平
我真的很疲惫,寻找垂直和水平滚动视图的解决scheme。
我读了框架中没有任何实现此function的视图/布局,但我需要这样的东西:
我需要定义其他的布局,子布局必须实现滚动垂直/水平移动。
最初实现了一个按像素移动布局的代码,但我认为这不是正确的方法。 我用ScrollView和Horizontal 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; } }
自定义HorizontalScrollView:
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 + horizontal 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:您可以获得ScrollView
和HorizontalScrollView
的源代码,了解核心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可能无法正常工作。
我有你的问题的解决scheme。 您可以检查它只处理垂直滚动的ScrollView代码,并忽略水平滚动并修改它。 我想像一个webview的视图,所以修改的滚动视图,它对我很好。 但是这可能不适合你的需要。
让我知道你的目标是什么样的用户界面。
问候,
拉维潘迪特
玩这个代码,你可以把一个HorizontalScrollView放到一个ScrollView中。 因此,您可以在同一视图中使用两种滚动方法。
资料来源: http : //androiddevblog.blogspot.com/2009/12/creating-two-dimensions-scroll-view.html
我希望这可以帮助你。
要设置垂直和水平滚动条,请参阅http://android-code-crumbs.blogspot.com/