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

OSCHINA-MIRROR/i-android-android-page

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

Андроид-пейдж

Введение

Андроид-пейдж — это фреймворк для разбиения на страницы списка данных в Android, который объединяет различные компоненты разбиения на страницы. Если у вас есть список, который нужно разбить на страницы, вы можете использовать этот фреймворк. Основные функции фреймворка:

  • автоматическое поддержание информации о разбиении на страницы;
  • поддержка расширения для запросов данных разбиения на страницы;
  • поддержка расширений для компонентов «тянуть, чтобы обновить» и «прокручивать, чтобы загрузить»;
  • поддержка настройки представления загрузки и пустого представления;
  • функция повторной попытки при сбое загрузки;
  • возможность поиска текущих данных списка;
  • выбор (одиночный или множественный) текущих данных списка;
  • сохранение и восстановление состояния данных списка.

Основные сведения

Фреймворк состоит из следующих основных компонентов:

  • запросчик данных разбиения на страницы IPageRequester, отвечающий за запросы данных к серверу и обратные вызовы;
  • фреймворк поставляется с собственным запросом Retrofit + okhttp, но вы также можете использовать другие запросы, следуя примеру OkHttpPageRequester;
  • анализатор данных разбиения на страницы IPageDataParser, ответственный за анализ полученных данных и получение набора данных для отображения в AbsListView или RecyclerView, а также общего количества данных;
  • перехватчик данных разбиения на страницы IPageDataIntercept, ответственный за перехват данных после анализа и перед отображением в списке;
  • менеджер данных разбиения на страницы PageManager, управляющий запросами, анализом и перехватом данных, а также поддерживающий объект Page, содержащий информацию о разбиении на страницы, такую как размер страницы, общее количество данных и текущий номер страницы;
  • адаптер данных разбиения на страницы IPageAdapter, ответственный за адаптацию проанализированных данных к адаптеру и их отображение;
  • поставщик компонента «тянуть, чтобы обновить» OnPullToRefreshProvider, предоставляющий компоненты «тянуть, чтобы обновить», такие как XListView, XExpandableListView и SwipeRefreshLayout от Google;
  • основной движок разбиения на страницы PageEngine, управляющий всеми компонентами и предоставляющий основные операции;
  • провайдер представлений разбиения на страницы, загрузчика и пустых представлений IPageViewProvider, обеспечивающий представления разбиения на страницы, загружаемые представления и пустые представления;
  • слушатель разбиения на страницы OnPageListener, охватывающий весь жизненный цикл запроса; наиболее часто используемым методом является onPageLoadComplete, который вызывается после адаптации данных к адаптеру, что позволяет получить доступ к окончательным адаптированным данным;
  • контекст разбиения на страницы PageContext, инкапсулирующий интерфейс PageEngine для UI-слоя, предоставляя некоторые интерфейсы для Activity и Fragment, а также предоставляя класс конфигурации PageConfig для настройки разбиения на страницы, такой как размер страницы и автоматическая загрузка данных при запуске;
  • провайдер контекста разбиения на страницы IPageContextProvider, представляющий собой интерфейс для предоставления некоторых компонентов PageContext для Activity и Fragment;
  • поисковик данных разбиения на страницы IPageSearcher, ответственный за поиск данных текущего списка;
  • селектор данных разбиения на страницы IPageChecker, ответственный за выбор данных текущего списка (одиночный и множественный);
  • сохранение и восстановление состояния данных разбиения на страницы: OnPageDataStateSaved, по умолчанию данные реализуют Serializable, если вы используете другой метод сериализации, вам необходимо реализовать свой собственный OnPageDataStateSaved.

Основной процесс: клиент инициирует загрузку, вызывая IPageRequester для запроса данных и обратного вызова, IPageDataParser анализирует обратный вызов данных, получая данные для адаптации и общее количество данных, IPageDataIntercept перехватывает данные, IPageAdapter адаптирует проанализированные данные к PageView. В первом запросе инициализируется объект page на основе размера страницы и dataTotal, затем при обновлении «тянуть, чтобы обновить» увеличивается номер страницы, и каждый последующий запрос передаёт этот объект запросу данных.

Конфигурация Gradle

compile 'cn.yhq:android-page:3.6.0'

Использование

  1. Загрузка локальных данных (1) Синхронная загрузка Текущая активность должна наследовать SimplePageDataActivity, реализовывать четыре метода. Обратите внимание, что если включена функция автоматической загрузки данных при запуске, код для установки setContentView и получения findViewById должен быть помещён в метод onViewCreated. ``` Если это операция, не занимающая времени, то можно сразу вернуть данные для адаптации.
@Override
public List<String> getPageData() {
    List<String> data = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        data.add("Пункт" + i);
    }
    return data;
}

(2) Асинхронная загрузка

При асинхронной загрузке необходимо реализовать метод IPageRequester. В местах, где требуется обратный вызов данных, можно вызывать callCacheResponse или callNetworkResponse. Обратите внимание, что эти два метода должны вызываться в UI потоке.

    @Override
    public void onViewCreated(Bundle savedInstanceState) {
        setContentView(R.layout.activity_main);
        mListView = (ListView) this.findViewById(R.id.list_view);
        mPageAdapter = new SimplePageAdapter(this);
        mListView.setAdapter(mPageAdapter);
    }

    @Override
    public View getPageView() {
        return mListView;
    }

    @Override
    public IPageAdapter<String> getPageAdapter() {
        return mPageAdapter;
    }

    // Если это операция, не занимающая времени, то не нужно переопределять этот метод
    // Если это затратная по времени операция, то нужно переопределить
    @Override
    public IPageRequester<List<String>, String> getPageRequester() {
        return new PageRequester<List<String>, String>(this) {
            private Thread thread;

            @Override
            public void onCancel() {
                thread.interrupt();
            }

            @Override
            public void executeRequest(Context context, PageAction pageAction, Page<String> page) {
                final Handler handler = new Handler() {
                    @Override
                    public void handleMessage(Message msg) {
                        super.handleMessage(msg);
                        switch (msg.what) {
                            case 1:
                                callCacheResponse((List<String>) msg.obj);
                                break;
                            case 2:
                                callNetworkResponse((List<String>) msg.obj);
                                break;
                        }
                    }
                };
                // Имитация затратной по времени операции, получение данных из кэша через 1 секунду и возврат, получение запрошенных данных через 2 секунды и возврат
                thread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        Message msg1 = new Message();
                        msg1.obj = getCacheData();
                        msg1.what = 1;
                        handler.sendMessage(msg1);
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        Message msg2 = new Message();
                        msg2.obj = getNetworkData();
                        msg2.what = 2;
                        handler.sendMessage(msg2);
                    }
                });
                thread.start();
            }
        };
    }

    private List<String> getNetworkData() {
        List<String> data = new ArrayList<>();
//        for (int i = 0; i < 10; i++) {
//            data.add("Запрошенный пункт" + i);
//        }
        return data;
    }

    private List<String> getCacheData() {
        List<String> data = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            data.add("Кэшированный пункт" + i);
        }
        return data;
    }

    @Override
    public List<String> getPageData() {
        return null;
    }
``` **Текст запроса:**

public void onPageConfig(PageConfig pageConfig) { super.onPageConfig(pageConfig); pageConfig.setPageSize(5); }

@Override
public Call<AlbumInfo> executePageRequest(int pageSize, int currentPage, Tracks mData) {
    return HttpAPIClient.getAPI().getAlbumInfo("夜曲", pageSize, currentPage);
}

@Override
public IPageAdapter<Tracks> getPageAdapter() {
    return mPageAdapter;
}

@Override
public IPageDataParser<AlbumInfo, Tracks> getPageDataParser() {
    return new IPageDataParser<AlbumInfo, Tracks>() {

        @Override
        public List<Tracks> getPageList(AlbumInfo data, boolean isFromCache) {
            return data.getTracks();
        }

        @Override
        public long getPageTotal(AlbumInfo data, boolean isFromCache) {
            return data.getTotal_tracks();
        }
    };
}

**Перевод текста на русский язык:**

public void onPageConfig (PageConfig pageConfig) { super.onPageConfig (pageConfig); pageConfig.setPageSize (5); }

@Override public Call executePageRequest (int pageSize, int currentPage, Tracks mData) { return HttpAPIClient.getAPI ().getAlbumInfo («夜曲», pageSize, currentPage); }

@Override public IPageAdapter getPageAdapter () { return mPageAdapter; }

@Override public IPageDataParser <AlbumInfo, Tracks> getPageDataParser () { return new IPageDataParser <AlbumInfo, Tracks>() {

    @Override
    public List <Tracks> getPageList (AlbumInfo data, boolean isFromCache) {
        return data.getTracks ();
    }

    @Override
    public long getPageTotal (AlbumInfo data, boolean isFromCache) {
        return data.getTotal_tracks ();
    }
};

}


Конечно, если вы использовали Volley или другие HTTP-фреймворки для загрузки, вам нужно только наследовать PageRequester и реализовать соответствующий интерфейс, а затем вернуть его.

### 4. Добавление функций pull-to-refresh и load more

(1) Использование XListView: просто замените ListView на XListView в макете:
```xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.markmao.pulltorefresh.widget.XListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerVertical="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"/>
</RelativeLayout>

(2) Использование SwipeRefreshLayout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swiperefreshlayout"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scrollbars="vertical">

        <com.markmao.pulltorefresh.widget.XListView
            android:id="@+id/list_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"/>

    </android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>

Затем реализуйте метод в текущей Activity:

@Override
public OnPullToRefreshProvider getOnPullToRefreshProvider() {
    return new PullToRefreshSwipeLayoutListViewContext(mSwipeRefreshLayout, mListView);
}

5. Создание собственного pull-to-refresh и load more фреймворка

(1) Реализуйте интерфейс OnPullToRefreshProvider.

(2) Верните свою реализацию OnPullToRefreshProvider в текущей Activity.

@Override
public OnPullToRefreshProvider getOnPullToRefreshProvider() {
    return new CustomPullToRefreshContext();
}

6. Использование перехватчиков

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

(2) В текущей Activity реализуйте public void addPageDataIntercepts(List<IPageDataIntercept> intercepts), чтобы добавить перехватчики.

@Override
public void addPageDataIntercepts(List<IPageDataIntercept<String>> intercepts) {
    intercepts.add(new IPageDataIntercept<String>() {
        @Override
        public List<String> intercept(Chain<String> chain) throws Exception {
            List<String> data = chain.data();
            data.add(0, "Перехватчик добавил элемент");
            return chain.handler(data);
        }
    });
}

7. Настройка представления страницы и пустого представления

В текущей activity переопределите метод getPageViewProvider():

@Override
public IPageViewProvider getPageViewProvider() {
    return new IPageViewProvider() {

        @Override
        public View getPageView() {
            return SimplePageActivity2.this.getPageView();
        }

        @Override **8. Список данных: поиск**

1. Самый простой способ  вызвать метод attachSearchEditText и напрямую добавить элемент EditText для поиска. Когда содержимое EditText изменится, список автоматически выполнит поиск по ключевому слову и обновит интерфейс. Обратите внимание: в этом случае также необходимо передать реализацию интерфейса IFilterName, чтобы получить текст, который будет участвовать в поиске.

2. Если вы хотите настроить интерфейс поиска, вызовите метод setPageSearcher и реализуйте интерфейс IPageSearcher. Вы можете обратиться к реализации по умолчанию cn.yhq.page.core.DefaultPageSearcher в системе.

Пример кода:
```java
this.attachSearchEditText(mEditText, new IFilterName<Tracks>() {
            @Override
            public String getFilterName(Tracks entity) {
                return entity.getTitle();
            }
        });

9. Список данных: выбор

Если вашему списку требуется реализовать функцию одиночного или множественного выбора, вам нужно унаследовать класс RetrofitPageCheckedActivity и вызвать метод setPageChecker, чтобы установить тип и значение по умолчанию для выбора, а также интерфейс данных, которые нельзя выбрать. Затем вы можете получить доступ к данным выбора с помощью метода getPageChecker() и вызывать соответствующие методы.

Пример кода:

this.setPageChecker(PageChecker.CHECK_MODEL_MUTIPLE, new OnPageCheckedChangeListener<Tracks>() {
            @Override
            public void onPageCheckedChanged(List<Tracks> checkedList, int count) {
                mAllCheckButton.setChecked(isAllChecked());
                mOKButton.setText("Выбор (" + count + ")");
            }
        }, new OnPageCheckedInitListener<Tracks>() {
            @Override
            public boolean isEnable(int position, Tracks entity) {
                if (position == 0 || position == 8) {
                    return false;
                }
                return true;
            }
            @Override
            public boolean isChecked(int position, Tracks entity) {
                if (position == 1 || position == 9) {
                    return true;
                }
                return false;
            }
        });

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

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

Введение

Описание недоступно Развернуть Свернуть
Отмена

Обновления

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

Участники

все

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

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