Intereting Posts
Байт байта Android для Bitmap Как сделать Android: отобразите TextView в правой части EditText, который находится в TextInputLayout Тайм-аут запуска истек, отказавшись от блокировки слежения! Тайм-аут активности для HistoryRecord. О чем это беспокоиться? Com.example имя пакета не разрешено в Google Play Повторная установка броска исключения IllegalArgumentException для асинхронного вызова DELETE FormUrlEncoded Список всех названий улиц и дорог в Google в API Где можно найти AndroidObservable.fromBroadcast? Выбор цвета Google Calendar Можно ли упаковать исходные двоичные файлы (созданные для ARM) приложения Android с UPX? Android. Как написать текст на действительно большом изображении (растровое изображение) и сохранить это Стиль TabLayout не может решить @ dimen / tab_max_width после перехода на Android Design Support v23 Как сделать ActionBar как Google Play, который исчезает при прокрутке Android ScaleAnimation и TranslateAnimation, как избежать движения ScaleAnimation Как избежать CollapsingToolbarLayout, не будучи разбитым или «неустойчивым» при прокрутке? Android Studio w / gradle: пакет r не существует

Куда пошли стрелы?

Редактировать / Примечание: мне действительно нужен ответ на этот вопрос, и я хотел бы остаться с «запасным» Google Android API. Я создал +100 баунти на этом, но если я получу прямое решение этого, используя API запаса в ближайшие несколько дней, я добавлю еще +100, сделав его стоимостью 200 пунктов.

Я экспериментирую с элементом управления Android CalendarView. Я сделал небольшое приложение с кнопкой и CalendarView в NestedScrollView. Я сделал кнопку, и ее поля действительно большие, поэтому я мог проверить прокрутку. На Samsung Galaxy S5 работает под управлением Android 6.01, он отлично работает. Но на Samsung S Duo (который является моей целевой целью), работающей на 4.2.2, нет возможности продвинуть месяц (не заметите стрелки рядом с месяцем )

Вот скриншот от Samsung S5 под управлением Android 6.01

S5 скриншот

И вот один из продуктов Samsung Duo 4.2.2

S Duo скриншот

Content_main.xml выглядит так. , ,

<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <!-- This linear layout is because the scrollview can have only 1 direct child --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/recordEnd" android:layout_width="200dp" android:layout_height="100dp" android:layout_marginTop="100dp" android:layout_marginBottom="100dp" android:gravity="center" android:text="Record End"/> <CalendarView android:id="@+id/thecalendar" android:layout_width="240dp" android:layout_height="300dp" android:minDate="01/01/2016" android:maxDate="11/30/2016"/> </LinearLayout> </android.support.v4.widget.NestedScrollView> 

… В Android Studio в представлении дизайна отображаются стрелки. Я не знаю, как отладить это.

Хорошее и глубокое объяснение Юлиана Попеску , я просто пытаюсь его упростить. Прежде всего, я хочу прояснить некоторые вещи.

  1. Согласно этой официальной ссылке разработчика Android, точный вид и модель взаимодействия виджета CalenderView могут варьироваться в зависимости от версий ОС и тем (например, Holo versus Material).
  2. Поскольку Iulian Popescu вставил код из класса android.widget.CalendarView Android, вы можете видеть, что класс CalendarViewLegacyDelegate отвечает за рендеринг CalenderView в случае темы HOLO а класс CalendarViewMaterialDelegate отвечает за рендеринг CalenderView в случае темы MATERIAL . Я снова отправляю этот код только для справки.
 public CalendarView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); final TypedArray a = context.obtainStyledAttributes( attrs, R.styleable.CalendarView, defStyleAttr, defStyleRes); final int mode = a.getInt(R.styleable.CalendarView_calendarViewMode, MODE_HOLO); a.recycle(); switch (mode) { case MODE_HOLO: mDelegate = new CalendarViewLegacyDelegate( this, context, attrs, defStyleAttr, defStyleRes); break; case MODE_MATERIAL: mDelegate = new CalendarViewMaterialDelegate( this, context, attrs, defStyleAttr, defStyleRes); break; default: throw new IllegalArgumentException("invalid calendarViewMode attribute"); } } 
  1. В классе CalendarViewMaterialDelegate (android.widget.CalendarViewMaterialDelegate) мы видим, что DayPickerView (android.widget.DayPickerView) используется в качестве контейнера для отображения календаря, который мы видим в теме материала. DayPickerView классе ViewPager используется для отображения одного месяца На одной странице. Также два ImageButton для следующего и предыдущего. Поскольку есть две кнопки для изменения месяца, это не создаст проблем и прекрасно работает в теме MATERIAL .
  private final ViewPager mViewPager; private final ImageButton mPrevButton; private final ImageButton mNextButton; 

  1. Как видно из класса CalendarViewLegacyDelegate (android.widget.CalendarViewLegacyDelegate), ListView используется для отображения списка недель (вертикальная прокрутка) в CalenderView . Нет никакого ImageButton для предыдущего и следующего, поскольку он будет прокручиваться по вертикали.
 /** * The adapter for the weeks list. */ private WeeksAdapter mAdapter; /** * The weeks list. */ private ListView mListView; 

Согласно этой ссылке на веб-сайте разработчика Android, мы никогда не должны использовать ScrollView с ListView , потому что ListView позаботится о своей собственной вертикальной прокрутке. Из-за этого в случае темы HOLO CalenderView будет вести себя непредсказуемо при использовании его внутри ScrollView .

Решение:-

Вы можете использовать ниже заданный пользовательский класс просмотра прокрутки вместо класса NestedScrollView . Это сделает вашу CalenderView вертикальной прокруткой гладкой в ​​случае темы HOLO .

 public class VerticalScrollView extends ScrollView{ public VerticalScrollView(Context context) { super(context); } public VerticalScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public VerticalScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { final int action = ev.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: super.onTouchEvent(ev); break; case MotionEvent.ACTION_MOVE: return false; // redirect MotionEvents to ourself case MotionEvent.ACTION_CANCEL: super.onTouchEvent(ev); break; case MotionEvent.ACTION_UP: return false; default: break; } return false; } @Override public boolean onTouchEvent(MotionEvent ev) { super.onTouchEvent(ev); return true; } } 

Надеюсь, это уберет ваши сомнения.

Имея быстрый взгляд в коде CalendarView похоже, что внешний вид календаря выведен из системы, и я не смог найти способ его изменить. Ниже вы можете узнать, как выбирается вид календаря в зависимости от mode :

 final TypedArray a = context.obtainStyledAttributes( attrs, R.styleable.CalendarView, defStyleAttr, defStyleRes); final int mode = a.getInt(R.styleable.CalendarView_calendarViewMode, MODE_HOLO); a.recycle(); switch (mode) { case MODE_HOLO: mDelegate = new CalendarViewLegacyDelegate( this, context, attrs, defStyleAttr, defStyleRes); break; case MODE_MATERIAL: mDelegate = new CalendarViewMaterialDelegate( this, context, attrs, defStyleAttr, defStyleRes); break; default: throw new IllegalArgumentException("invalid calendarViewMode attribute"); } 

Изменить :

После некоторого времени, потраченного на эту проблему, у меня есть несколько пояснений:

  1. Предварительный просмотр показывает вид со стрелками, потому что вы не установили правильную версию API. Если вы посмотрите на приведенные ниже изображения, вы увидите, что в версиях до Lollipop кнопки отсутствуют, а после этого все хорошо и хорошо. Чтобы изменить версию API, просто нажмите кнопку, выделенную красным цветом, и выберите нужный уровень API, чтобы увидеть точный предварительный просмотр вашего xml на разных платформах.

    Версия KitKat Версия Android N

  2. Почему стрелки отсутствуют в предыдущих версиях Material Design? Здесь я не смог найти ответ, данный кем-то из Google, но я считаю, что это как-то связано с разрешением экрана (на более старых устройствах у вас не так много места, чтобы показать CalendarView как в новых версиях Android И именно поэтому они выбрали ListView поскольку он может отображать только несколько строк и по-прежнему полностью функционален, тогда как отображение с помощью ViewPager будет обрезать некоторые из последних строк).

    Как я уже говорил в оригинальном посте, стиль CalendarView выбирается на основе доступности Material Design (Android 5.0+).

    Версия Legacy (найти ее ниже) имеет ListView а следующие / предыдущие кнопки отсутствуют. Поскольку календарь отображается с помощью ListView вы не можете прокручивать его до следующего месяца, так как родительский вид CalendarView является Scroll . Чтобы исправить это, вы можете найти некоторые объяснения и решения здесь .

     <TextView android:id="@+android:id/month_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:paddingTop="10dip" android:paddingBottom="10dip" style="@android:style/TextAppearance.Medium" /> <!-- This is the header representing the days of the week --> <LinearLayout android:id="@+android:id/day_names" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="6dip" android:layout_marginEnd="2dip" android:layout_marginStart="2dip" android:gravity="center" > <TextView android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:visibility="gone" /> <TextView android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" /> <TextView android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" /> <TextView android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" /> <TextView android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" /> <TextView android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" /> <TextView android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" /> <TextView android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" /> </LinearLayout> <ImageView android:layout_width="match_parent" android:layout_height="1dip" android:scaleType="fitXY" android:gravity="fill_horizontal" android:src="?android:attr/dividerHorizontal" /> <ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="match_parent" android:drawSelectorOnTop="false" android:cacheColorHint="@android:color/transparent" android:fastScrollEnabled="false" android:overScrollMode="never" /> 

    Версия Material Design заменяет ListView на ViewPager и добавляет предыдущие и следующие кнопки.

     <android.widget.DayPickerViewPager android:id="@+id/day_picker_view_pager" android:layout_width="match_parent" android:layout_height="match_parent" /> <ImageButton android:id="@+id/prev" android:layout_width="wrap_content" android:layout_height="wrap_content" android:minWidth="48dp" android:minHeight="48dp" android:src="@drawable/ic_chevron_start" android:background="?attr/selectableItemBackgroundBorderless" android:contentDescription="@string/date_picker_prev_month_button" android:visibility="invisible" /> <ImageButton android:id="@+id/next" android:layout_width="wrap_content" android:layout_height="wrap_content" android:minWidth="48dp" android:minHeight="48dp" android:src="@drawable/ic_chevron_end" android:background="?attr/selectableItemBackgroundBorderless" android:contentDescription="@string/date_picker_next_month_button" android:visibility="invisible" /> 

    На данный момент я не смог найти способ стиля CalendarView поскольку stylable атрибуты удаляются из общедоступных API.

    Класс android.R.styleable и его поля были удалены из общедоступного API, чтобы обеспечить лучшую совместимость приложений для приложений.

    При этом вы можете сохранить стиль старого стиля для старых версий Android, так как вы не можете его изменить, но имейте в виду, что ListView не должен находиться в Scroll или пытаться найти репозиторий, который стабилен и лучше подходит для вашего необходимо.

Редактировать II:

CalendarView не нарушен, он отлично работает на всех версиях Android, даже если он может создать впечатление, что его поведение нарушено из-за реализации с помощью ListView . Теперь «давайте немного разобраться в проблеме, чтобы каждый мог понять, что происходит:

  1. Проблема №. 1: использование ListView в ScrollView
    Вообще говоря, это плохая практика, чтобы использовать эти элементы вложенными, потому что они не смогут правильно обрабатывать действие прокрутки.

  2. Проблема №. 2: использование NestedScrollView не NestedScrollView проблему
    С Android 5.0 Google добавила эту библиотеку поддержки для поддержки вложенной прокрутки, но ListView не сможет обрабатывать свиток, если только он не реализует NestedScrollingChild . Чтобы сделать этот подкласс классом ListView и реализовать методы интерфейса, и из каждого метода вызовите соответствующий метод из NestedScrollingChildHelper . Следуя этим шагам, вы можете использовать ListView в NestedScrollView , но не CalendarView (см. Проблему № 3)

  3. Проблема №. 3: вы не можете изменить список из CalendarView
    Реальная проблема заключается в том, что у CalendarView нет никаких методов, которые позволили бы вам изменить список по умолчанию с помощью специального списка, написанного вами. Предположим, что у вас будет такой метод, вы можете сделать работу CalendarView , заменив список по умолчанию своим пользовательским, и свиток будет работать отлично, но, к сожалению, вы не можете.

Чтобы решить проблему, у вас есть 2 варианта:
– перепроектируйте вы так, чтобы CalendarView не был в классе, содержащем Scroll в его имени
– используйте ответ Правина Диврания, который заставит вас работать в календаре отлично, но имейте в виду, что вложенные свитки плохие (особенно на старых устройствах Android, где экран небольшой)