寻找垂直和水平Scrollview的解决方案真的很累。
我读到框架中没有实现此功能的任何视图/布局,但是我需要这样的东西:
我需要在其他布局中定义一个布局,子布局必须实现垂直/水平滚动才能移动。
最初实现的代码逐像素移动布局,但是我认为这不是正确的方法。我使用ScrollView和Horizontal ScrollView进行了尝试,但是没有什么能像我想要的那样工作,因为它仅实现垂直或水平滚动。
画布不是我的解决方案,因为我需要在某人的子元素中附加侦听器。
我能做什么?
寻找垂直和水平Scrollview的解决方案真的很累。
我读到框架中没有实现此功能的任何视图/布局,但是我需要这样的东西:
我需要在其他布局中定义一个布局,子布局必须实现垂直/水平滚动才能移动。
最初实现的代码逐像素移动布局,但是我认为这不是正确的方法。我使用ScrollView和Horizontal ScrollView进行了尝试,但是没有什么能像我想要的那样工作,因为它仅实现垂直或水平滚动。
画布不是我的解决方案,因为我需要在某人的子元素中附加侦听器。
我能做什么?
Answers:
混合上面的一些建议,就能得到一个好的解决方案:
自定义ScrollView:
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>
LinearLayout
我猜您不需要初始的)
由于这似乎是Google中“ Android垂直+水平ScrollView”的第一个搜索结果,因此我认为应该在此处添加此内容。马特·克拉克(Mat Clark)已基于Android源构建了一个自定义视图,它似乎运行得很好:二维ScrollView
请注意,该页面中的类存在一个错误,该错误会计算视图的水平宽度。评论中有Manuel Hilty的修复程序:
解决方案:将第808行的语句替换为以下内容:
final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.leftMargin + lp.rightMargin, MeasureSpec.UNSPECIFIED);
编辑:链接不再起作用,但是这里是指向旧版本博客文章的链接。
fillViewport
并且onMeasure
完全像ScrollView源(v2.1)。我还用:this( context, null );
和更改了两个第一个构造函数this(context, attrs, R.attr.scrollViewStyle);
。这样,我就可以在setVerticalScrollBarEnabled
和setHorizontalScrollBarEnabled
中使用滚动条。
我找到了更好的解决方案。
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
ImageView
可滚动内容,但它可能适用于或不适用于任意其他内容,并且Google相信您的方法会存在问题。Google的意见对于未来的发展也很重要-如果他们建议人们不要一开始就使用它,他们可能不会试图确保您的方法长期有效。
我的解决方案基于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>
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。
试试这个
<?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>
由于“二维滚动视图”链接已失效,因此我无法获取它,因此我创建了自己的组件。它可以应对并为我正常工作。唯一的限制是wrap_content可能不适用于该组件。
玩代码,您可以将HorizontalScrollView放入ScrollView。因此,您可以在同一视图中使用两种滚动方法。
来源:http : //androiddevblog.blogspot.com/2009/12/creating-two-dimensions-scroll-view.html
希望对您有所帮助。
用这种方式我尝试了这个我修复了它
将所有XML布局放入
<android.support.v4.widget.NestedScrollView
我在此链接中解释了这一点,即 垂直recyclerView和水平recyclerview一起滚动