1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/zhongrui_developer-PullToRefresh

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

ПуллТоРесет

v1 декораторная версия

v2 декораторная версия

Краткое описание

PullToRefresh реализует вертикальное списковое отображение для пулл-до-рессета, вертикальное списковое отображение для загрузки, горизонтальное списковое отображение для левого пулл-до-рессета и правого пулл-до-загрузки.

Центральный репозиторий PullToRefresh OpenHarmony

Установка

ohpm install @zhongrui/pull_to_refresh
import {
  PullToRefreshLayout,
  RefreshLayout,
  RefreshLayoutConfig,
  PullDown,
  PullStatus,
  RefreshController,
  PullToRefreshConfig,
} from 'PullToRefresh/Index';

Особенности

  1. Нет вторжения, не требуется передача данных источника.

  2. Не ограничивает компоненты, поддерживает любые макеты (списки, сетки, веб, прокрутка, текст, строки, колонки и т.д.).

  3. Поддерживает кастомизацию header и footer (поддерживает анимацию Lottie).

  4. Поддерживает пулл-до-рессет и пулл-до-загрузку для вертикальных и горизонтальных списков.

  5. Поддерживает пулл-до-открытие других страниц.


Предоставлены RefreshLayout и PullToRefreshLayout
  1. RefreshLayout поддерживает различные кастомизации.
  2. PullToRefreshLayout настроен на основе RefreshLayout, реализует стандартные функции пулл-до-рессета и пулл-до-загрузки.
  3. Если нет специфических требований, можно использовать PullToRefreshLayout напрямую.Если изображения не отображаются корректно нажмите здесь| Эффект пулл-до-рессета для вертикального списка | Эффект пулл-до-рессета для вертикальной сетки | Открытие других страниц при пулл-до- | Автоматический пулл-до- | |---|---|---|---| | | | | | | Веб-вью для обновления эффекта | Пользовательский анимированный эффект обновления | Эффект обновления с использованием Lottie | Горизонтальный список для обновления | |---|---|---|---| | | | | |

Три горизонтальных режима заголовка (для футера аналогично)| Заголовок в нормальном горизонтальном режиме
Ширина заголовка фиксирована, высота занимает всё доступное пространство | Заголовок в горизонтальном режиме с поворотом на 90° против часовой стрелки
Ширина заголовка занимает всё доступное пространство, высота фиксирована
Аналогично вертикальному списку | Заголовок в горизонтальном режиме с поворотом на 90° по часовой стрелке
Ширина заголовка занимает всё доступное пространство, высота фиксирована
Аналогично вертикальному списку |

|---|---|---| | | | |#### Настройка страницы по умолчанию (загрузка, пустые данные, неудачная загрузка, отсутствие сети)

### Пояснения по использованию PullToRefreshLayout (общий подход) (для персонализации используйте RefreshLayout)
По умолчанию для списков с эластичным эффектом необходимо отключить эластичное скольжение, .edgeEffect(EdgeEffect.None)
@Component
export struct Example {
   /*Контроллер RefreshLayout*/
   controller: RefreshController = new RefreshController()
   /*Конфигурация RefreshLayout*/
   config: RefreshLayoutConfig = new RefreshLayoutConfig()
   /*Необходимо установить scroller для компонента списка*/
   scroller: Scroller = new Scroller()
   /*Конфигурация webview*/
   webviewController: web.WebviewController = new web.WebviewController()
}
build() {
   PullToRefreshLayout({
      /*Необязательное поле, загрузка заголовка анимации*/
      headerLoadIngView: () => {
         this.loading()
      },
      /*Необязательное поле, загрузка анимации футера*/
      footerLoadIngView: () => {
         this.loading()
      },
      /*Обязательное поле, ключ для записи времени обновления*/
      viewKey: "идентификатор списка",
      /*Необязательное поле, настройка параметров обновления, если не задано, используются значения по умолчанию*/
      config: this.config,
      /*Обязательное поле, PullToRefreshLayout контроллер*/
      controller: this.controller,
      /*Обязательное поле, настройка Scroller, связанного со списком, например List, Grid, Scroll, WaterFlow и другие компоненты*/
      scroller: this.scroller,
      /*Если contentView является компонентом Web, то это обязательное поле, необходимо задать WebviewController, не нужно задавать scroller*/
      webviewController: this.webviewController,
      /*Настройка содержимого списка*/
      contentView: () => {
         this.contentView()
      }
   })
}
```       },
         /*Check if refresh is possible when scrolling down, true: refresh is possible, false: refresh is not possible*/
        onCanPullRefresh: () => {
          //Check if the list is at the top
          /*By default, for lists with rubber band effect, the rubber band effect needs to be disabled, .  edgeEffect(EdgeEffect.  None)*/
          return (this.  scroller.  currentOffset().  yOffset ?  ?   0) <= 0
        },
         /*Check if load is possible when scrolling up, true: load is possible, false: load is not possible*/
        onCanPullLoad: () => {
          //Check if the list is at the bottom
          return this.  scroller.  isAtEnd()
        },
         /*Call refresh*/
        onRefresh: () => {
          //Perform operations to refresh data
        },
         /*Call load*/
        onLoad: () => {
          //Perform operations to load data
        },
         /*Call opening page when scrolling down*/
        onOpenPage: () => {
          //Perform transition to page or other business logic operations
        },
         /*Call opening page when scrolling up*/
        onLoadOpenPage: () => {
          //Perform transition to page or other business logic operations
        },
      })
        .  width("100%").  height("100%")
    }
    @Builder
    contentView() {
      List({ scroller: this.  scroller }) {
      }.  width("100%").  height("100%").  edgeEffect(EdgeEffect.  None)
    }
  }

Примечания по использованию RefreshLayout (можно расширить до различных вариантов взаимодействия)

По умолчанию, для списков с эффектом резинового полотна необходимо отключить резиновый эффект, . edgeEffect(EdgeEffect. None)

@Component
export struct Example {
    /*Контроллер RefreshLayout*/
    controller: RefreshController = new RefreshController()
    /*Конфигурация RefreshLayout*/
    config: RefreshLayoutConfig = new RefreshLayoutConfig()
    /*Необходимо установить scroller для компонента списка*/
    scroller: Scroller = new Scroller()
    /*Контроллер, требуемый для конфигурации webview*/
    webviewController: web.WebviewController = new web.WebviewController()
}
    RefreshLayout({
        /*Необязательный параметр, настройка конфигурации обновления, если не задан, используется значение по умолчанию*/
        config: this.config,
        /*Обязательный параметр, контроллер RefreshLayout*/
        controller: this.controller,
        /*Обязательный параметр, настройка Scroller, связанного со списком, таких как List, Grid, Scroll, WaterFlow и т. д. компоненты*/
        scroller: this.scroller,
        /*Обязательный параметр, если contentView является компонентом Web, необходимо задать WebviewController, не нужно задавать scroller*/
        webviewController: this.webviewController,
        /*1: Настройка шаблона header*/
        headerView: () => {
            this.headerView()
        },
        /*2: Настройка шаблона контента списка*/
        contentView: () => {
            this.contentView()
        },
        /*3: Настройка шаблона footer*/
        loadView: () => {
            this.loadView()
        },
        /*По текущему положению списка или другим бизнес-логикам определяется, можно ли выполнить обновление, true: можно обновлять, false: нельзя обновлять*/
        onCanPullRefresh: () => {
            //Проверка, находится ли список в верхней части
        }
    })
}
```        /*По умолчанию, для списков с эластичным эффектом необходимо отключить эластичное скольжение. edgeEffect(EdgeEffect.None)*/
        return (this.scroller.currentOffset()?.yOffset ?? 0) <= 0
      },
        /*По текущему положению списка или другим бизнес-логикам определяется, можно ли выполнить загрузку. true: можно загружать, false: нельзя загружать*/
      onCanPullLoad: () => {
        //Проверка, находится ли список в нижней части
        return this.scroller.isAtEnd()
      },
        /*Триггер обновления*/
      onRefresh: () => {
        //Выполнение операций обновления данных
      },
        /*Триггер загрузки*/
      onLoad: () => {
        //Выполнение операций загрузки данных
      },
        /*Триггер открытия страницы при выполнении обновления*/
      onOpenPage: () => {
        //Выполнение операций перехода на страницу или других бизнес-логических операций
      },
        /*Триггер открытия страницы при выполнении загрузки*/
      onLoadOpenPage: () => {
        //Выполнение операций перехода на страницу или других бизнес-логических операций
      },
        /*Мониторинг состояния процесса обновления или загрузки, можно реализовать пользовательский интерфейс header и footer с помощью onPullListener*/
      onPullListener: (pullDown: PullDown) => {```markdown
      }
    })
      .clip(true) // Обязательный параметр clip:true
      .width("100%").height("100%")
  }  @Builder
  headerView() {
  }
  @Builder
  contentView() {
    List({ scroller: this.scroller }) {
    }.width("100%").height("100%").edgeEffect(EdgeEffect.None)
  }
  @Builder
  loadView() {
  }
}

контроллер: RefreshController

Метод Описание Возвращаемое значение
refreshSuccess() Уведомляет RefreshLayout о успешном обновлении Нет
refreshError() Уведомляет RefreshLayout о неудачном обновлении Нет
refreshComplete(true or false) Уведомляет RefreshLayout о завершении обновления (успешно или неудачно) Нет
loadSuccess() Уведомляет RefreshLayout о успешной загрузке Нет
loadError() Уведомляет RefreshLayout о неудачной загрузке Нет
loadComplete(true or false) Уведомляет RefreshLayout о завершении загрузки (успешно или неудачно) Нет
getStatus() Получает текущий статус RefreshLayout PullStatus
refresh() Ручное запуск обновления RefreshLayout Нет
load() Ручное запуск загрузки RefreshLayout Нет
refreshIsEnable() Проверяет, включен ли режим обновления boolean
loadIsEnable() Проверяет, включен ли режим загрузки boolean
setConfig(config: RefreshLayoutConfig) Устанавливает конфигурацию RefreshLayout Нет
getConfig() Получает конфигурацию RefreshLayout RefreshLayoutConfig
onWebviewScroll(xOffset: number, yOffset: number) Слушатель прокрутки для webview Нет
 | --- | --- | --- |
 | isVertical | Является ли список вертикальным, true: вертикальный, false: горизонтальный | true |
 | horizontalMode | Режим горизонтального расположения: 0 - нормальное горизонтальное расположение, 1 - header и footer поворачиваются на 90° против часовой стрелки, 2 - header и footer поворачиваются на 90° по часовой стрелке | 0 |
 | pullRefreshEnable | Включено ли управление обновлением | true |
 | pullLoadEnable | Включено ли управление загрузкой | true |
 | **Настройки обновления** | | |
 | releaseRefresh | При достижении условий обновления, требуется ли освобождение для активации обновления | true |
 | pullMaxDistance | Максимальное расстояние для прокрутки | 500vp |
 | pullRefreshResistance | Сопротивление прокрутки, значение должно быть в диапазоне (0,1] | 0.5 |
 | pullHeaderHeightRefresh | Расстояние прокрутки, при котором достигаются условия обновления. Если значение меньше или равно 0, автоматически устанавливается в 1.5 раза больше высоты или ширины header | 0 |
 | pullRefreshOpenPageEnable | Включено ли управление открытием других страниц при прокрутке | false |
 | pullHeaderHeightOpenPage | Расстояние прокрутки, при котором достигаются условия открытия других страниц. Если значение меньше или равно 0, автоматически устанавливается в 2.6 раза больше высоты или ширины header | 0 |
 | durationToHeader | Время, за которое headerView возвращается к своему начальному положению при освобождении обновления | 250ms || durationCloseHeader | Время, за которое headerView возвращается к своему начальному положению после завершения обновления | 200ms |
 | durationCloseForOpenPage | Время, за которое происходит возврат к начальному положению при открытии других страниц | 180ms |
 | refreshKeepHeader | Отображается ли headerView при обновлении | true |
 | refreshShowSuccess | Отображается ли view успешного завершения обновления | true |
 | refreshShowError | Отображается ли view неудачного завершения обновления | true |
 | refreshResultDurationTime | Время, в течение которого отображается view результата обновления | 600ms |
 | **Настройки загрузки** | | |
 | releaseLoad | При достижении условий загрузки, требуется ли освобождение для активации загрузки | true |
 | pullLoadMaxDistance | Максимальное расстояние для прокрутки | 500vp |
 | pullLoadResistance | Сопротивление прокрутки, значение должно быть в диапазоне (0,1] | 0.5 |
 | pullFooterHeightLoad | Расстояние прокрутки, при котором достигаются условия загрузки. Если значение меньше или равно 0, автоматически устанавливается в 1.1 раза больше высоты или ширины footer | 0 |
 | pullLoadOpenPageEnable | Включено ли управление открытием других страниц при прокрутке | false |
 | pullFooterHeightOpenPage | Расстояние прокрутки, при котором достигаются условия открытия других страниц. Если значение меньше или равно 0, автоматически устанавливается в 2.6 раза больше высоты или ширины footer | 0 |
 | durationToFooter | Время, за которое footerView возвращается к своему начальному положению при освобождении загрузки | 250ms || durationCloseFooter | Время, за которое `footerView` возвращается к своему начальному положению после завершения загрузки | 200ms |
| durationCloseLoadForOpenPage | Время отскока при открытии других страниц | 180ms |
| loadKeepFooter | Отображать ли `footerView` при загрузке | true |
| loadShowSuccess | Отображать ли `view` успешной загрузки | true |
| loadShowError | Отображать ли `view` неудачной загрузки | true |
| loadResultDurationTime | Время отображения `view` результата загрузки | 600ms |
#### Описание PullDown (с помощью этих данных можно реализовать персонализированный интерактив)|  Свойство |  Описание |
|---|---|
| isPullDown |  Состояние "открытия" при нажатии |
| isPullUp |  Состояние "загрузки" при отпускании |
| isTouch |  Состояние прикосновения |
| distance |  Расстояние открытия в пикселях (vp) |
| distanceLoad |  Расстояние загрузки в пикселях (vp) |
| headerViewSize |  Высота headerView в пикселях (vp)<br/>Ширина headerView в пикселях (vp) (если ориентация горизонтальная и horizontalMode равно 0) |
| footerViewSize |  Высота footerView в пикселях (vp)<br/>Ширина footerView в пикселях (vp) (если ориентация горизонтальная и horizontalMode равно 0) |
| status |  Текущее состояние PullStatus |


#### Описание PullStatus

|  Свойство |  Описание |
|---|---|
|  DEF |  По умолчанию (без расстояния открытия или загрузки) |
|  **Состояния, связанные с обновлением** |   |
|  PullDown |  Состояние "открытия" |
|  PreRefresh |  Состояние, когда "открытие" достигает условия обновления |
|  Refresh |  Обновление в процессе |
|  PreOpenPage |  Состояние, когда "открытие" достигает условия открытия других страниц |
|  OpenPage |  Открытие других страниц |
|  RefreshSuccess | Успешное обновление |
|  RefreshError | Неудачное обновление |
|  **Состояния, связанные с загрузкой** |   |
| PullUp | Состояние "загрузки" |
|  PreLoad |  Состояние, когда "загрузка" достигает условия загрузки |
| Load | Загрузка в процессе |
| PreLoadOpenPage | Состояние, когда "загрузка" достигает условия открытия других страниц |
| LoadOpenPage | Открытие других страниц |
| LoadSuccess | Успешная загрузка |
|  LoadError |  Неудачная загрузка |<br/>#### Пользовательские настройки PullToRefreshLayout
```typescript
    /*Ширина индикатора обновления*/
    public refreshLoadingWidth: Length = 25
    /*Высота индикатора обновления*/
    public refreshLoadingHeight: Length = 25
    /*Цвет индикатора обновления*/
    public refreshLoadingColor: ResourceColor = "#333333"
    /*Изображение стрелки для обновления*/
    public arrowImage: Resource = $r("app.media.zr_refresh_arrow")
    /*Ширина стрелки для обновления*/
    public arrowImageWidth: Length = 20
    /*Высота стрелки для обновления*/
    public arrowImageHeight: Length = 20
    /*Изображение стрелки для загрузки*/
    public arrowLoadImage: Resource = $r("app.media.zr_refresh_arrow")
    /*Цвет стрелки для загрузки*/
    public arrowLoadImageColor: ResourceColor = "#333333"
    /*Ширина стрелки для загрузки*/
    public arrowLoadImageWidth: Length = 20
    /*Высота стрелки для загрузки*/
    public arrowLoadImageHeight: Length = 20
    /*Подсказка "Нет больше данных"*/
    public noMoreTips: string | Resource = $r("app.string.zr_load_no_more")
    /*Размер подсказки "Нет больше данных"*/
    public noMoreTipsSize: number | string | Resource = 13
    /*Цвет подсказки "Нет больше данных"*/
    public noMoreTipsColor: ResourceColor = "#666666"
    /*Подсказка "Нет больше данных" для горизонтального списка*/
    public noMoreTipsHorizontal: string | Resource = $r("app.string.h_zr_load_no_more")
    /*Показывать время последнего обновления*/
    public showRefreshTime: boolean = false
    /*Размер подсказки времени последнего обновления*/
    public refreshTimeTipsSize: number | string | Resource = 11
    /*Цвет подсказки времени последнего обновления*/
    public refreshTimeTipsColor: ResourceColor = "#999999"
    /*Подсказка "Потяните вниз для обновления"*/
    public pullDownTips: string | Resource = $r("app.string.zr_pull_down_to_refresh")
```    /*Подсказка "Потяните вниз для обновления" для горизонтального списка*/
    public pullDownTipsHorizontal: string | Resource = $r("app. string.h_zr_pull_down_to_refresh")
     /*Размер подсказки "Потяните вниз для обновления"*/
    public pullDownTipsSize: number | string | Resource = 13
     /*Цвет подсказки "Потяните вниз для обновления"*/
    public pullDownTipsColor: ResourceColor = "#666666"
     /*Подсказка "Отпустите для обновления"*/
    public releaseRefreshTips: string | Resource = $r("app. string.zr_release_to_refresh")
     /*Подсказка "Отпустите для обновления" для горизонтального списка*/
    public releaseRefreshTipsHorizontal: string | Resource = $r("app. string.h_zr_release_to_refresh")
     /*Подсказка "Загрузка. . ."*/
    public refreshTips: string | Resource = $r("app. string.zr_refreshing")
     /*Подсказка "Загрузка. . ." для горизонтального списка*/
    public refreshTipsHorizontal: string | Resource = $r("app. string.h_zr_refreshing")
 ```  /*Успешное обновление подсказки*/
    public refreshSuccessTips: string | Resource = $r("app. string.zr_refresh_success")
     /*Успешное обновление подсказка — горизонтальный список*/
    public refreshSuccessTipsHorizontal: string | Resource = $r("app. string.h_zr_refresh_success")
     /*Подсказка об ошибке при обновлении*/
    public refreshErrorTips: string | Resource = $r("app. string.zr_refresh_error")
     /*Подсказка об ошибке при обновлении — горизонтальный список*/
    public refreshErrorTipsHorizontal: string | Resource = $r("app. string.h_zr_refresh_error")
     /*Подсказка для открытия других страниц при свайпе вниз*/
    public pullOpenPageTips: string | Resource = $r("app. string.zr_release_to_open_age")
     /*Подсказка для открытия других страниц при свайпе вниз — горизонтальный список*/
    public pullOpenPageTipsHorizontal: string | Resource = $r("app. string.h_zr_release_to_open_age")
     /*Подсказка для свайпа вверх для загрузки*/
    public pullUpTips: string | Resource = $r("app.string.zr_pull_up_to_load")
     /*Подсказка для свайпа вверх для загрузки — горизонтальный список*/
    public pullUpTipsHorizontal: string | Resource = $r("app.string.h_zr_pull_up_to_load")
     /*Размер подсказки для свайпа вверх для загрузки*/
    public pullUpTipsSize: number | string | Resource = 13
     /*Цвет подсказки для свайпа вверх для загрузки*/
    public pullUpTipsColor: ResourceColor = "#333333"
     /*Подсказка для немедленной загрузки при отпускании*/
    public releaseLoadTips: string | Resource = $r("app.string.zr_release_to_load")
     /*Подсказка для немедленной загрузки при отпускании — горизонтальный список*/
    public releaseLoadTipsHorizontal: string | Resource = $r("app.string.h_zr_release_to_load")
     /*Подсказка для загрузки*/
    public loadTips: string | Resource = $r("app.string.zr_loading")
     /*Подсказка для загрузки — горизонтальный список*/
    public loadTipsHorizontal: string | Resource = $r("app.string.h_zr_loading")
     /*Подсказка для успешной загрузки*/
    public loadSuccessTips: string | Resource = $r("app.string.zr_load_success")
     /*Подсказка для успешной загрузки — горизонтальный список*/
    public loadSuccessTipsHorizontal: string | Resource = $r("app.string.h_zr_load_success")
     /*Подсказка для неудачной загрузки*/
    public loadErrorTips: string | Resource = $r("app.string.zr_load_error")
     /*Подсказка для неудачной загрузки — горизонтальный список*/
    public loadErrorTipsHorizontal: string | Resource = $r("app.string.h_zr_load_error")
     /*Подсказка для открытия других страниц при свайпе вниз*/
    public loadOpenPageTips: string | Resource = $r("app.string.zr_release_to_open_page")
     ### Версия обновления
     #### 1.0.8
 ```typescript
 @Builder
 viewLoading(){
  Text("Загрузка (поддерживает кастомизацию)") 
}PullToRefreshLayout({
  /*Установка загрузочного представления*/
  viewLoading:()=>{
    this.viewLoading()
  },
  /*Установка представления пустого состояния*/
  viewEmpty:()=>{
    this.viewEmpty()
  },
  /*Установка представления ошибки*/
  viewError:()=>{
    this.viewError()
  },
  /*Установка представления отсутствия сети*/
  viewNoNetwork:()=>{
    this.viewNoNetwork()
  }
}).width("100%").layoutWeight(1).clip(true)
  
//RefreshController
//Отображение кастомизированного загрузочного представления
this.controller.viewLoading()
//Отображение кастомизированного пустого представления
this.controller.viewEmpty()
//Отображение кастомизированного представления ошибки
this.controller.viewError()
//Отображение кастомизированного представления отсутствия сети
this.controller.viewNoNetwork()

# История версий
### 1.1.5
1. Исправлено появление горизонтальной линии в заголовке
2. PullToRefreshLayout по умолчанию автоматически вычисляет возможность прокрутки в зависимости от переданного Scroller

### 1.1.4
1. Исправлены проблемы с отскоком или касанием во время прокрутки, а также проблемы с отскоком

### 1.1.3
1. В RefreshController добавлен метод setRefreshEnable(enable) для включения или отключения возможности прокрутки вниз
2. В RefreshController добавлен метод setLoadEnable(enable) для включения или отключения возможности прокрутки вверх

### 1.1.2
1. Добавлена поддержка внешнего установления свойства clip для PullToRefreshLayout

### 1.1.1
1. Исправлено проблемное значение context### 1.1.0
1. Возможность установки состояния страницы до монтирования компонента

### 1.0.9
1. Решена проблема с невозможностью смены состояния при успешном обновлении

### 1.0.8
1. Добавлены методы для кастомизации представлений (загрузка, пустое состояние, ошибка, отсутствие сети)

### 1.0.7
1. В RefreshController добавлены методы для отмены обновления и отмены загрузки

### 1.0.6
1. В PullToRefreshConfig добавлены настройки цвета стрелок для прокрутки вниз и вверх

### 1.0.5
1. После успешного обновления RefreshLayout по умолчанию не изменяет состояние наличия данных

### 1.0.4
1. В PullToRefreshLayout добавлены базовые настройки кастомизации

### 1.0.3
1. Добавлено проверение состояния загрузки или обновления перед триггером события

### 1.0.2
1. Добавлены пояснения в README

### 1.0.1
1. Решена проблема с ошибкой при получении ресурсов в релизном пакете

### 1.0.0 Изначальная версия
1. Выпуск версии 1.0.0

#### Лицензия
Проект использует лицензию [MIT license](https://gitee.com/zhongrui_developer/PullToRefresh/blob/master/LICENSE), пожалуйста, наслаждайтесь и участвуйте в открытом исходном коде.

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Открытая библиотека для отслеживания свайпов вниз для обновления данных в HarmonyOS. Развернуть Свернуть
TypeScript
MIT
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/zhongrui_developer-PullToRefresh.git
git@api.gitlife.ru:oschina-mirror/zhongrui_developer-PullToRefresh.git
oschina-mirror
zhongrui_developer-PullToRefresh
zhongrui_developer-PullToRefresh
master