×Закрыть

Одновременная (синхронная) прокрутка троих ScrollView

Здравствуйте. Есть пользовательский интерфейс, в котором отображени три элемента ScrollView. Как сделать синхронную одновременную прокрутку всех троих ScrollView в не зависимости от того, какой из них пользователь будет прокручивать?

Желательно описать как это сделать в C# (Xamarin) или просто напишите логику с примером, думаю разберусь.

Спасибо :)

Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Решение задачи!

_ScrollViewLeft.ScrollChange += _ScrollViewLeft_ScrollChange;
_ScrollViewMedium.ScrollChange += _ScrollViewMedium_ScrollChange;
_ScrollViewRight.ScrollChange += _ScrollViewRight_ScrollChange;

}

private void _ScrollViewLeft_ScrollChange(object sender, ScrollChangeEventArgs e)
{

int ScrollX = _ScrollViewLeft.ScrollX;
int ScrollY = _ScrollViewLeft.ScrollY;
_ScrollViewMedium.ScrollTo(ScrollX, ScrollY);
_ScrollViewRight.ScrollTo(ScrollX, ScrollY);
}
private void _ScrollViewMedium_ScrollChange(object sender, ScrollChangeEventArgs e)
{
int ScrollX = _ScrollViewMedium.ScrollX;
int ScrollY = _ScrollViewMedium.ScrollY;
_ScrollViewLeft.ScrollTo(ScrollX, ScrollY);
_ScrollViewRight.ScrollTo(ScrollX, ScrollY);
}
private void _ScrollViewRight_ScrollChange(object sender, ScrollChangeEventArgs e)
{
int ScrollX = _ScrollViewRight.ScrollX;
int ScrollY = _ScrollViewRight.ScrollY;
_ScrollViewLeft.ScrollTo(ScrollX, ScrollY);
_ScrollViewMedium.ScrollTo(ScrollX, ScrollY);
}

синхронную одновременную прокрутку

А если в первом scrollview содержимого настолько мало, что его незачем крутить, а в остальных — много или тоже мало (или вообще нет, во втором 100500 букв текста, в третьем — hello world)?
Первый не прокручивается, потому что всё содержимое поместилось и в скролле нет нужды, а остальные, соответственно, тоже. Что будете делать?
И прокрутку хотите считать в точках, типа, прокрутил вниз на 20 точек, содержимое поползло вверх, или в процентах?
Андрей Буланов направление подсказал, но scrollview могут иметь разного размера содержимое: в одном — «привет мой свет», а в другом — длиннющее лицензионное соглашение на 10000 строк, в третьем — вообще ничего. Что крутить и зачем крутить тогда?
Задача неоднозначная сильно.

Все предельно просто. Три scrollview, в каждом по одному LinearLayout и в каждом layout’е по 18 текстовых блоков, текст которых уже будет задаватся програмно. И надо чтобы при скролле любого элемента все синхронно скролилось как будто это один большой scrollview

Похоже на какой-то титановый костыль..

по 18 текстовых блоков, текст которых уже будет задаватся програмно.

Текст всегда с фиксированным шрифтом , фиксированным количеством срок, и (если нужно) межстрочным интервалом?
То есть в одном блоке
«Lorem ipsum»
а в другом
«Lorem ipsum
dolor»

Да, но не в этом суть. По логике это должно работать. Но что пытается сделать код
(new View.OnScrollChangeListener() ? Тут должны быть другие ключевые слова или другие параметры. Вот с этим не могу разобратся.

scrollView1.setOnScrollChangeListener(new View.OnScrollChangeListener() {
@Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
scrollView2.scrollTo(scrollX, scrollY);
scrollView3.scrollTo(scrollX, scrollY);
}
});

Ошибка «Имя „OnScrollChangeListener“ не существует в текущем контексте.» есть только интерфейс с таким именем, экземпляр которого создать нельзя.

new NestedScrollView.OnScrollChangeListener()

	
 myScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
        @Override
        public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
            Log.d("ScrollView","scrollX_"+scrollX+"_scrollY_"+scrollY+"_oldScrollX_"+oldScrollX+"_oldScrollY_"+oldScrollY);
            //Do something
        }
    });

stackoverflow.com/...​listener-for-a-scrollview

Спасибо, я только понять не могу что делает эта строка

myScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {

Это создание анонимного типа в параметрах метода? Или как?
Знаком только с синтаксисом шарпа, собственно по этому и прошу помощь

Сам ни гугу, но от этого пояснение доходчивое выйдет. Хотя могу и не в ту степь ...
У тебя есть экземпляр объекта

myScrollView

на событие прокрутки в нем ты вешаешь «свой код» реакции, точнее перердаешь/регистрируешь экземпляр объекта слушателя, который реализует интерфейс взаимодействия, на который ты наткнулся и стопорнулся. Чтоб не писать свою реализацию интерфейса в виде своего объекта и подсовывать его экземпляр в качестве обработчика, ты используешь готовый объект, создавая его экземпляр

new NestedScrollView.OnScrollChangeListener()

. Но вместо того, чтоб писать (забыл уже транскрипцию языка): А = new Object() и дальше v.OnScroll(A), так как тебе сама ссылка на промежуточный объект А тебе дальше не нужна, пишешь кратко v.OnScroll(new Object() {...}). Но, это только увязка, тебе надо написать свой код реакции в паре нужных тебе методов (заменить в объекте «стандартный» на свой), для этого дальше и идет их переопределение на твой код

@Override public void onScrollChange ...

.

И если в методах будешь оперировать произошедшим смешением — величина на которую изменилось, а не смещение от 0/начала, применяя ее к другим прокруткам +/-, то можешь попасть в цикл. По событию от пользователя на двух других выставиться/прокрутится, например, по +10, на них сработают свои события от изменения величины прокрутки, и пойдет крутится на всех трех до упора.
А если указывать относительно 0, то возможно будет обратной волной на прокрученный скрул возвращаться его же значение. Возможно будет проявляться как мерцание интерфейса. Так что может быть надо будет что-то придумывать на остановку обратных волн, если они порождаются программным перемещением скрулов на действия пользователя в каком-то одном из трех. Но это так фантазии о ловушках и проблемах.

На шарпе немного по другому, но все в пример кидают джаву...
Получается что я к ScrollView прикрутил метод слушателя, который в параметры принимает интерфейс (?!), другого варианта нет. Получается теперь мне надо бы этому объявленному интерфейсу присвоить значения, но как?

private IOnScrollChangeListener listener;
_ScrollViewLeft.SetOnScrollChangeListener(listener);

И еще вопрос, если перейти к определению то получается:

public interface IOnScrollChangeListener : IJavaObject, IDisposable
{void OnScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY); }

Интерфейсы вроде созданы, для того чтобы реализововали их методы, но в даном случае он не требует реализации OnScrollChange. Так зачем тогда слушателю в виде параметра захотелось увидеть интерфейс, что это значит и правильным путем я иду?

Он не интерфейс от тебя хочет получить в качестве параметра для вставки в список слушателей события (когда произойдет события, по списку у каждого слушателя будет вызван согласно реализуемому им интерфейсу метод под определенным именем), а объект с таким интерфейсом. Слушателем вроде нужно прикручивать экземпляр класса

NestedScrollView.OnScrollChangeListener()

с переписанным на свой код методом.

Я НАШЕЛ РЕШЕНИЕ
Все оказалось очень и очень простым. Нашел событие ScrollChange, прикрутил его к первому ScrollView, потом создал две переменных которые получают значение из свойства .ScrollX/Y (оно возвращает прокрученную позицию) и передал это все в качестве параметра к методу ScrollTo. Все делалось по «Методу научного тыка»
Запустил и действительно они одновременно движутся как будто это 1 елемент.
Спасибо всем за помощь!

_ScrollViewLeft.ScrollChange += _ScrollViewLeft_ScrollChange;

private void _ScrollViewLeft_ScrollChange(object sender, ScrollChangeEventArgs e)
{

int OldScrollX = _ScrollViewLeft.ScrollX;
int OldScrollY = _ScrollViewLeft.ScrollY;
_ScrollViewMedium.ScrollTo(OldScrollX, OldScrollY);

}

P.S. Оказывается тот велосипед который я придумывал уже был в шарпе)

А тебе не кажется что это другая проблема? Вот когда она возникнет тогда ее и будем решать.

Хз как там в этих хамаринах, но в js например это бы делалось так — вешаешь на каждый обработчик события onscroll и в нём скроллишь программно остальные два. Не вижу причин чтобы это работало не так в C#. Вроде в плане логики ничего сложного.

Даже один обработчик на все три события. Зачем много букв тратить)) Один счетчик изменился остальным присвоить новые значения..

Давайте уже пройдём за него собеседование и просто напишем во сколько куда прийти на работу. Далее это уже проблемы тимлида :)

В общих чертах примерно так: вешаешь на ScrollView слушателя, и в колбэке меняешь позицию для двух других.

scrollView1.setOnScrollChangeListener(new View.OnScrollChangeListener() {
@Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
scrollView2.scrollTo(scrollX, scrollY);
scrollView3.scrollTo(scrollX, scrollY);
}
});

Спасибо огромное. До этого в гугле искал и никак найти логику не мог, так как под Xamarin документации мало. Приходится искать на жабе и адаптировать под шарп и искать схожие события)

Ты тут чё, stackoverflow себе устроил?

И не говори, негде ему спросить больше..

Что, не надо было ему отвечать?

Ну а как же обычные — «гугл забанили?», «учи основы», «что за программисты пошли» и т.д. Чему будущее поколение учишь, на вопросы отвечать сразу, а не гнобить? Куда только катимся..

Не, ну а вдруг человеку и правда надо =)

Под xamarin документации очень и очень мало, если что. Не все же сразу стали такими великими программистами как Вы.

А какую Вы документацию по нему хотите? На офсайте помоему куча всего...

Ну к примеру, какие события можно применять к ScrollView? На русском нет ни учебников ничего. Приходится смотреть все по англ, что не совсем удобно и не всегда есть или смотреть как это все делается под android studio на джаве, улавливать логику кода и это все переписывать на синтаксис шарпа. С такими костылями и обучаюсь)

Привыкайте. Самая свежая и самая актуальная информация всегда на английском.

Я уже догадался. К счастью есть такие люди как Андрей, которые возьмут и помогут)

www.google.pl/...​&sourceid=chrome&ie=UTF-8

Но можно, конечно, и дальше продолжать ждать Андрея...

Официальных доков по API нет? Если нет — это мертвая технология, не стоит даже трогать такое. Если есть — то для данной задачи должно хватать, вроде не rocket science.

На оф. сайте есть но очень мало и без каких то примеров. А так как я начинающий и после windows form взялся за xamarin то кроме MSDN особо не ориентируюсь в документации. Был бы рад, если бы меня кто то ткнул носом и оказал документацию по xamarin.
developer.xamarin.com/guides
находил только такое, но тут минимум информации

Если в поиск вбить scrollview, а потом перейти на вкладку APIs в результатах поиска -
находится это, и вроде бы там всё есть.

Вы так говорите, будто в этом есть что-то плохое.

Порошенку и МАУ разумнее же здесь обсуждать. Согласись?

На это пойтить я не могу.

Подписаться на комментарии