Android: включить полосы прокрутки в пользовательском представлении - PullRequest
6 голосов
/ 06 сентября 2011

Я реализовал пользовательский макет, который расширяет RelativeLayout. Он отображает множество различных элементов, созданных во время выполнения, и прокручивается в обоих измерениях с помощью scrollTo () и scrollBy (). Прокрутка работает, и теперь я хотел бы добавить стандартные полосы прокрутки Android.

Использование прокрутки не возможно, поскольку мне нужно, чтобы макет прокручивался в двух измерениях, поэтому я попытался сделать это, как описано здесь: Android: включить полосы прокрутки в представлении на основе холста

Я реализовал все методы compute * с некоторыми (поддельными) значениями и включил полосы прокрутки. Но я все еще не могу заставить их появиться. Есть идеи, в чем может быть проблема?

Существует множество подобных вопросов в различных списках рассылки и в SO, но везде ответ кажется «1. вызовите setHorizontScrollbarEnabled (true), 2. реализуйте все методы compute *, 3. вызовите awakenScrollbars ()» , Насколько я могу судить, я сделал все это и даже попытался использовать initializeScrollbars (), но ничего не происходит, и документы не предлагают никакой помощи.

public NodeLayout(Context context) {
    super(context);

    setVerticalScrollBarEnabled(true);
    setHorizontalScrollBarEnabled(true);

    TypedArray a = context.obtainStyledAttributes(R.styleable.View);
    initializeScrollbars(a);
    a.recycle();
}

@Override
protected int computeHorizontalScrollExtent() {
    return 5;
}

@Override
protected int computeHorizontalScrollOffset() {
    return 10;
}

@Override
protected int computeHorizontalScrollRange() {
    return 50;
}

@Override
protected int computeVerticalScrollExtent() {
    return getHeight() / 2;
}

@Override
protected int computeVerticalScrollOffset() {
    return getHeight() / 2;
}

@Override
protected int computeVerticalScrollRange() {
    return getHeight();
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    awakenScrollBars();
    invalidate();
    return true;
}

А вот так выглядит мой файл attrs.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="View">
<attr name="android:background"/>
<attr name="android:clickable"/>
<attr name="android:contentDescription"/>
<attr name="android:drawingCacheQuality"/>
<attr name="android:duplicateParentState"/>
<attr name="android:fadeScrollbars"/>
<attr name="android:fadingEdge"/>
<attr name="android:fadingEdgeLength"/>
<attr name="android:fitsSystemWindows"/>
<attr name="android:focusable"/>
<attr name="android:focusableInTouchMode"/>
<attr name="android:hapticFeedbackEnabled"/>
<attr name="android:id"/>
<attr name="android:isScrollContainer"/>
<attr name="android:keepScreenOn"/>
<attr name="android:longClickable"/>
<attr name="android:minHeight"/>
<attr name="android:minWidth"/>
<attr name="android:nextFocusDown"/>
<attr name="android:nextFocusLeft"/>
<attr name="android:nextFocusRight"/>
<attr name="android:nextFocusUp"/>
<attr name="android:onClick"/>
<attr name="android:padding"/>
<attr name="android:paddingBottom"/>
<attr name="android:paddingLeft"/>
<attr name="android:paddingRight"/>
<attr name="android:paddingTop"/>
<attr name="android:saveEnabled"/>
<attr name="android:scrollX"/>
<attr name="android:scrollY"/>
<attr name="android:scrollbarAlwaysDrawHorizontalTrack"/>
<attr name="android:scrollbarAlwaysDrawVerticalTrack"/>
<attr name="android:scrollbarDefaultDelayBeforeFade"/>
<attr name="android:scrollbarFadeDuration"/>
<attr name="android:scrollbarSize"/>
<attr name="android:scrollbarStyle"/>
<attr name="android:scrollbarThumbHorizontal"/>
<attr name="android:scrollbarThumbVertical"/>
<attr name="android:scrollbarTrackHorizontal"/>
<attr name="android:scrollbarTrackVertical"/>
<attr name="android:scrollbars"/>
<attr name="android:soundEffectsEnabled"/>
<attr name="android:tag"/>
<attr name="android:visibility"/>
</declare-styleable>
</resources>

Я разрабатываю для Android 3.0.

Ответы [ 2 ]

9 голосов
/ 21 декабря 2011

Просто была такая же проблема и, наконец, разобрался.

«Проблема» в том, что вы расширяете RelativeLayout, который является подклассом ViewGroup. Я обнаружил, что у меня не было проблем с тем, что вы описали в своем вопросе, чтобы пользовательский View отображал полосы прокрутки, но когда я расширил ViewGroup или один из его подклассов, полосы прокрутки не появились.

Я наконец-то вспомнил, что ViewGroup по умолчанию не рисуют сами. Я добавил одну строку в свой пользовательский конструктор ViewGroup: setWillNotDraw(false);

Что вы знаете, появились полосы прокрутки!

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

2 голосов
/ 27 ноября 2012

Fyi, на Android 3.2 / Google TV и Android 3.2.1 / Tablet, часть решения не является дополнительной при расширении ViewGroup. Кажется, проблема в том, что ни один из элементов рисования и размеров полосы прокрутки, используемых View для рисования полос прокрутки, не загружается, если не установлены все соответствующие свойства полосы прокрутки в . Если не установить какое-либо значительное количество этих свойств, во время компоновки 3.2 будет исключение нулевого указателя. Я также подозреваю, что серии классов GridView / ListView / AbsListView / AdapterView не устанавливают атрибуты горизонтальной полосы прокрутки, если это то, что вы преследуете.

Общие шаги выглядят так:

  • Используйте (как описано выше).
  • Вызовите initScrollbars в начале вашего конструктора (как описано выше).
  • Вызовите setHor HorizontalScrollbarEnabled / setrVerticalScrollBarEnbled после вызова initScrollbars.
  • Реализуйте набор из трех computeHor horizontalScrollXXX и computeVerticalScrollXXX в зависимости от ситуации.
  • совершайте частые вызовы awakenScrollBars (), чтобы отображать полосы прокрутки.
  • Скорее всего, вызов setWillNotDraw (false) должен быть сделан в конструкторе. Рисование полосы прокрутки реализовано в View; но я на самом деле называю этот метод сам.
  • рассмотрим вызов setScrollBarStyle для управления размещением полос прокрутки. Наиболее полезные пользовательские представления, которые прокручиваются, в конечном итоге обрезают поля отступа, что приводит к искажению вида прокрутки полос прокрутки в представлении, если они располагаются вне прямоугольника заполнения, поскольку у нас нет доступа к тем же скрытым методам в View, что и на складе Android взгляды делают.

Я думаю, вот и все. Шансы всего, что работает на Android 6.0 ... невелики. : - /

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...