Scrollview вертикальный и горизонтальный в android

Я действительно устал искать решение для вертикального и горизонтального Scrollview.

Я читал, что нет никаких представлений / макетов в рамках, которые реализуют эту функцию, но мне нужно что-то вроде этого:

Мне нужно определить макет внутри другого, дочерний макет должен реализовать прокрутку по вертикали / горизонтали для перемещения.

Первоначально был реализован код, который перемещал пиксель пикселя по пикселям, но я думаю, что это неправильный путь. Я попробовал это с помощью ScrollView и Horizontal ScrollView, но ничего не работает, как я хочу, потому что он реализует только вертикальную или горизонтальную прокрутку.

Canvas не является моим решением, потому что мне нужно присоединить слушателей к дочерним элементам someones.

Что я могу сделать?

Solutions Collecting From Web of "Scrollview вертикальный и горизонтальный в android"

Смешивая некоторые из приведенных выше предложений и смог получить хорошее решение:

Пользовательский 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> 

Поскольку это, по-видимому, первый результат поиска в Google для «Android вертикальный + горизонтальный ScrollView», я думал, что должен добавить это здесь. Мэтт Кларк создал собственное представление, основанное на Android-источнике, и кажется, что он отлично работает: Two Dimensional ScrollView

Помните, что класс на этой странице имеет ошибку, вычисляющую горизонтальную ширину представления. Исправление Мануэля Хильти в комментариях:

Решение. Замените оператор в строке 808 следующим текстом:

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

Изменить: ссылка больше не работает, но вот ссылка на старую версию blogpost .

Я нашел лучшее решение.

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

Мое решение, основанное на ответе Махди Хиджази , но без каких-либо пользовательских представлений:

Планировка:

 <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: вы можете создать новый интерфейс, который не требует одновременной горизонтальной и вертикальной прокрутки.

Вариант №2: вы можете получить исходный код для ScrollView и HorizontalScrollView , узнать, как команда разработчиков Android реализовала их, и создать собственную реализацию BiDirectionalScrollView .

Вариант № 3: вы можете избавиться от зависимостей, которые требуют от вас использования системы виджетов, и прямо на холст.

Вариант № 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> 

Так как ссылка Two Dimensional Scrollview мертва, я не смог ее получить, поэтому создал свой собственный компонент. Он обрабатывает дрожание и работает правильно для меня. Единственным ограничением является то, что wrap_content может работать неправильно для этого компонента.

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

У меня есть решение проблемы. Вы можете проверить код ScrollView, который обрабатывает только вертикальную прокрутку и игнорирует горизонтальный и модифицирует это. Мне понравилось представление, подобное веб-просмотру, так что модифицированный ScrollView и он работал хорошо для меня. Но это может не соответствовать вашим потребностям.

Дайте мне знать, на какой интерфейс вы ориентируетесь.

С Уважением,

Рави Пандит

Играя с кодом, вы можете поместить HorizontalScrollView в ScrollView. Таким образом, вы можете использовать два метода прокрутки в одном представлении.

Источник: http://androiddevblog.blogspot.com/2009/12/creating-two-dimensions-scroll-view.html

Надеюсь, это поможет вам.

Для установки вертикальных и горизонтальных полос прокрутки см. http://android-code-crumbs.blogspot.com/