Как создать собственную библиотеку для Android на примере BottomTabLayout

Рано или поздно у всех разработчиков накапливается достаточное количество готовых решений и хочется поделиться ими с друзьями, сотрудниками или со всем миром. Но к сожалению у большинства «руки не доходят», так как нужно оформить решение как отдельную библиотеку и потом разобраться как залить ее на открытый репозиторий. К тому же бытует мнение что это не так просто. Так вот, в этой статье мы разрушим этот миф, так как с приходом Gradle в стек технологий Android все стало намного проще.

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

Понятно, что первый шаг — написание собственной библиотеки. В этом примере я использую библиотеку BottomTabLayout. Эта библиотека позволяет в несколько строчек добавить нижний TabLayout, который перекочевал к нам в Android из мира iOS.

Библиотека BottomTabLayout в действии

1. Набор табов задается через xml-файл ресурсов menu. Например:

<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="https://schemas.android.com/apk/res/android"><item
        android:id="@+id/menu_button1"
        android:icon="@drawable/tab_button1_selector"
        android:title="Button1"/>
 
    <item
        android:id="@+id/menu_button2"
        android:icon="@drawable/tab_button1_selector"
        android:title="Button2"/>
 
    <item
        android:id="@+id/menu_button3"
        android:icon="@drawable/tab_button1_selector"
        android:title="Button3"/></menu>

2. В коде выше свойство icon — это ресурс selector, который мы создаем в drawable:

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="https://schemas.android.com/apk/res/android"><item android:drawable="@drawable/ic_button1_dark" android:state_pressed="true"/><!-- pressed --><item android:drawable="@drawable/ic_button1_dark" android:state_selected="true"/><!-- selected --><item android:drawable="@drawable/ic_button1"/><!--default--></selector>

Состояния state_selected и default здесь обязательные, так как нам нужно выделять выбранный таб.

3. Создаем selector для текста:

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="https://schemas.android.com/apk/res/android"><item android:color="@color/black" android:state_pressed="true"/><!-- pressed --><item android:color="@color/black" android:state_selected="true"/><!-- selected --><item android:color="@color/white"/><!--default--></selector>

4. Создаем стиль текста:

<style name="TabButtonTextStyle" parent="android:Widget.Button"><item name="android:textSize">12sp</item><item name="android:textColor">@drawable/tab_button_text_selector</item></style>

5. Добавляем BottomTabLayout на разметку activity:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.stfalcon.bottomtablayout_sample.MainActivity">
 
    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/bottomTabLayout"/>
 
    <com.stfalcon.bottomtablayout.BottomTabLayout
        android:id="@+id/bottomTabLayout"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:layout_alignParentBottom="true"
        android:background="@color/dark"/></RelativeLayout>

6. Настраиваем в классе activity:

@Override
    protectedvoid onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        container = R.id.container;//Container for fragments//Setup button tab layout
        bottomTabLayout =(BottomTabLayout) findViewById(R.id.bottomTabLayout);//set button text style
        bottomTabLayout.setButtonTextStyle(R.style.TextGray16);// set buttons from menu resource
        bottomTabLayout.setItems(R.menu.menu_bottom_layout);//set on selected tab listener.
        bottomTabLayout.setListener(new BottomTabLayout.OnItemSelectedListener(){
            @Override
            publicvoid onItemSelected(int id){
                switchFragment(id);}});//set button that will be select on start activity
        bottomTabLayout.setSelectedTab(R.id.menu_button1);}

7. В нашем примере при переключении таба меняется фрагмент в контейнере:

*** Show fragment in container
     * @param id Menu item res id
     */publicvoid switchFragment(int id){
        Fragment fragment =null;switch(id){case R.id.menu_button1:
                fragment = ColoredFragment.newInstance(R.color.blue, "Fragment 1");break;case R.id.menu_button2:
                fragment = ColoredFragment.newInstance(R.color.green, "Fragment 2");break;case R.id.menu_button3:
                fragment = ColoredFragment.newInstance(R.color.pink, "Fragment 3");break;case R.id.menu_button4:
                fragment = ColoredFragment.newInstance(R.color.blueDark, "Fragment 4");break;case R.id.menu_button5:
                fragment = ColoredFragment.newInstance(R.color.white, "Fragment 5");break;}if(fragment !=null){
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            transaction.replace(container, fragment);
            transaction.commit();}}

Вот такая вот простенькая библиотека. На GitHub можно подробней ознакомится с BottomTabLayout.

Публикация Android-библиотеки

Теперь я расскажу вам, как имея похожие наработки, поделиться ими с миром.

Создание модуля в Android Studio

1. Для начала создаем проект в Android Studio. Для удобства модуль app переименовываем в sample. Здесь будет лежать пример использования нашей библиотеки.

2. Создаем новый модуль:

Создание нового модуля в Android Studio

3. Тип модуля выбираем Android Library:

Выбор типа модуля в Android Studio

4. Это и будет наша библиотека, поэтому название соответствующее — bottomtablayout.

5. Теперь settings.gradle у нас должен выглядеть так:

include ':sample', ':bottomtablayout'

6. В модуле sample, в build.gradle добавляем зависимость:

compile project(':bottomtablayout')

Это делается временно, пока наша библиотека существует только локально.

7. Теперь мы можем написать нашу библиотеку (или перенести готовый код) и протестировать ее в модуле sample.

8. Когда библиотека готова, заливаем ее на свой GitHub-аккаунт.

9. Пишем туториал в README.md.

Добавление библиотеки на Bintray

1. Если библиотека готова и вы считаете что пора миру ее увидеть, заходим и регистрируемся на сайте Bintray.

2. В файл build.gradle проекта добавляем зависимость:

dependencies {
   ...
   classpath'com.novoda:bintray-release:0.3.4'}

3. В build.gradle-файле модуля библиотеки (в нашем случае это bottomtablayout) применяем плагин:

apply plugin:'com.novoda.bintray-release'

И в этом же файле:

publish {
   groupId ='com.github.stfalcon'
   artifactId ='contentmanager'
   publishVersion ='0.1.1'
   desc ='Library that helps a few lines of code to get pictures and video from the android file system, or ures cloud, as well as the camera device.'
   licences =['Apache-2.0']
   uploadName='ContentManager'
   website ='https://github.com/stfalcon-studio/ContentManager.git'}

Где:

  • groupId — пакет (может отличаться от пекейджа самого модуля). Рекомендую называть groupId так: com.github.<username вашего github аккаунта>, поскольку если вы когда-то захотите залить свою библиотеку на Maven Central нужно быть владельцем домена который фигурирует в названии groupId.
  • artifactId — название модуля.
  • publishVersion — версия публикации.
  • desc — описание библиотеки.
  • licences — лицензия.
  • uploadName — название библиотеки.
  • website — ссылка на GitHub проекта.

4. Далее нам нужен API Key вашего аккаунта на Bintray. Заходим на страницу вашего профайла:

Профиль на Bintray

5. Ищем кнопочку Edit и переходим по ней:

Редактирование профиля Bintray

6. Теперь переходим по пункту меню API Key:

Получение API Key с Bintray

7. Сохраняем ключ в надежном месте.

8. Открываем терминал в Android Studio и выполняем:

gradlew clean build bintrayUpload -PbintrayUser=<юзернейм на bintray>-PbintrayKey=<api ключ с bintray>-PdryRun=false

9. Дожидаемся сборки и отгрузки библиотеки на сервер.

10. Теперь открываем сайт Bintray и ищем переход на страницу свежедобавленной библиотеки.

11. Пока что для того, чтобы подключить нашу библиотеку нужно добавить ссылку на репозиторий в build.gradle-файл проекта:

repositories {
    maven {
        url  "https://dl.bintray.com/<username>/maven"}}

Какой-то лишний шаг получается, правда? Значить нужно это исправить :)

Добавление Android-библиотеки в jCenter

С недавних пор, репозиторием по умолчанию в Android считается jCenter (до этого был Maven Central). Благо, что добавление библиотеки в jCenter делается в один клик.

1. На странице нашей библиотеки переходим по ссылке add to jCenter и отправляем запрос на добавление. В течении суток библиотека будет добавлена в jCenter и вас оповестят соответствующим письмом на почту.

2. Теперь есть возможность подключить библиотеку через build.gradle модуля, добавив зависимость в dependencies:

compile 'com.github.stfalcon:contentmanager:0.1.1'

Завершение

Поздравляю! Ваша библиотека вышла в свет и уже можно начинать хвастаться ею перед друзьями, пиарить в пабликах и смотреть, как страница библиотеки на гитхабе набирает звездочки и форки.

UPD: читайте о наших Android-библиотеках в новой статье!

Нужен MVP, разработка под iOS, Android или прототип приложения? Ознакомьтесь с нашим портфолио и сделайте заказ уже сегодня!