Обзор библиотеки NavigationTabBar для Android от команды DevLight Overview of the NavigationTabBar for Android from DevLight

[:ru]Сегодня в очередном выпуске Дизайна андроид приложений обзор интересной библиотеки от команды DevLight. Кто не в курсе, это успешные разработчики, которые начинали когда-то с уроков на нашем канале. Теперь у них большая фирма и крутые заказчики. Интервью с ребятами можно посмотреть по ссылке. Ребята рассказывают о том, чего достигли и делятся секретами своего успеха с начинающими разработчиками.

Репозиторий команды DevLight на Github содержит много интересных библиотек для оформления приложений. Одну из таких мы и рассмотрим сегодня. Это библиотека NavigationTabBar. Она позволяет создать и разместить на экране приложения панель навигации — внизу, вверху или сбоку. NavigationTabBar поддерживается с версии SDK API 11, имеет много настроек и легко интегрируется со всеми стандартными компонентами макета экрана.

На странице библиотеки в GitHub описаны способы добавления библиотеки в проект, перечислены параметры и показан пример реализации в проекте.

Также здесь есть ссылка на код приложения, которое демонстрирует несколько способов применения этой библиотеки. Я импортировал этот пример в Android Studio. давайте разберем его более подробно.

В MainActivity просто кнопки для перехода между экранами. Для каждого экрана здесь есть отдельное Activity.

package devlight.io.sample;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPropertyAnimatorListener;
import android.view.View;

public class MainActivity extends Activity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initUI();
    }

    private void initUI() {
        final View btnHorizontalNtb = findViewById(R.id.btn_horizontal_ntb);
        btnHorizontalNtb.setOnClickListener(this);
        final View btnHorizontalCoordinatorNtb = findViewById(R.id.btn_horizontal_coordinator_ntb);
        btnHorizontalCoordinatorNtb.setOnClickListener(this);
        final View btnTopHorizontalNtb = findViewById(R.id.btn_horizontal_top_ntb);
        btnTopHorizontalNtb.setOnClickListener(this);
        final View btnVerticalNtb = findViewById(R.id.btn_vertical_ntb);
        btnVerticalNtb.setOnClickListener(this);
        final View btnSamplesNtb = findViewById(R.id.btn_samples_ntb);
        btnSamplesNtb.setOnClickListener(this);
    }

    @Override
    public void onClick(final View v) {
        ViewCompat.animate(v)
                .setDuration(200)
                .scaleX(0.9f)
                .scaleY(0.9f)
                .setInterpolator(new CycleInterpolator())
                .setListener(new ViewPropertyAnimatorListener() {
                    @Override
                    public void onAnimationStart(final View view) {

                    }

                    @Override
                    public void onAnimationEnd(final View view) {
                        switch (v.getId()) {
                            case R.id.btn_horizontal_ntb:
                                startActivity(
                                        new Intent(MainActivity.this, HorizontalNtbActivity.class)
                                );
                                break;
                            case R.id.btn_horizontal_top_ntb:
                                startActivity(
                                        new Intent(MainActivity.this, TopHorizontalNtbActivity.class)
                                );
                                break;
                            case R.id.btn_horizontal_coordinator_ntb:
                                startActivity(
                                        new Intent(MainActivity.this, HorizontalCoordinatorNtbActivity.class)
                                );
                                break;
                            case R.id.btn_vertical_ntb:
                                startActivity(
                                        new Intent(MainActivity.this, VerticalNtbActivity.class)
                                );
                                break;
                            case R.id.btn_samples_ntb:
                                startActivity(
                                        new Intent(MainActivity.this, SamplesNtbActivity.class)
                                );
                                break;
                            default:
                                break;
                        }
                    }

                    @Override
                    public void onAnimationCancel(final View view) {

                    }
                })
                .withLayer()
                .start();
    }

    private class CycleInterpolator implements android.view.animation.Interpolator {

        private final float mCycles = 0.5f;

        @Override
        public float getInterpolation(final float input) {
            return (float) Math.sin(2.0f * mCycles * Math.PI * input);
        }
    }
}

Первый экран реализует горизонтальный NavigationTabBar.

Его разметка находится в файле activity_horizontal_ntb.xml.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    android:background="#423752"
    android:orientation="vertical">

    <android.support.v4.view.ViewPager
        android:id="@+id/vp_horizontal_ntb"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>

    <devlight.io.library.ntb.NavigationTabBar
        android:id="@+id/ntb_horizontal"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        app:ntb_badge_gravity="top"
        app:ntb_badge_position="right"
        app:ntb_badged="true"
        app:ntb_scaled="true"
        app:ntb_tinted="true"
        app:ntb_title_mode="all"
        app:ntb_titled="true"
        app:ntb_swiped="true"/>

</LinearLayout>

Здесь в корневом LinearLayout стандартный ViewPager для отображения и перелистывания вкладок.

Далее здесь NavigationTabBar из библиотеки Devlight. Кроме стандартных атрибутов размера здесь указаны настройки положения бейджа относительно кнопки, включение отображения бейджа, включения эффекта масштабирования и тонирования активной кнопки, настройка способа отображения заголовка и последний атрибут ntb_swiped — я не разобрался, за что он отвечает. Кто разберется — пишите в комментариях.

Весь список возможных атрибутов компонента NavigationTabBar здесь:

<devlight.io.library.ntb.NavigationTabBar
   android:id="@+id/ntb"
   android:layout_width="match_parent"
   android:layout_height="50dp"
   app:ntb_animation_duration="400"
   app:ntb_preview_colors="@array/colors"
   app:ntb_corners_radius="10dp"
   app:ntb_active_color="#fff"
   app:ntb_inactive_color="#000"
   app:ntb_badged="true"
   app:ntb_titled="true"
   app:ntb_scaled="true"
   app:ntb_tinted="true"
   app:ntb_title_mode="all"
   app:ntb_badge_position="right"
   app:ntb_badge_gravity="top"
   app:ntb_badge_bg_color="#ffff0000"
   app:ntb_badge_title_color="#ffffffff"
   app:ntb_typeface="fonts/custom_typeface.ttf"
   app:ntb_badge_use_typeface="true"
   app:ntb_swiped="true"
   app:ntb_bg_color="#000"
   app:ntb_icon_size_fraction="0.5"
   app:ntb_badge_size="10sp"
   app:ntb_title_size="10sp"/>

Смотрим код HorisontalNtbActivity. В методе initUI находится viewPager и для него устанавливается адаптер с пятью элементами. Далее идут стандартные методы и создаются вкладки на основании макета с несколькими TextView

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;

import devlight.io.library.ntb.NavigationTabBar;

/**
 * Created by GIGAMOLE on 28.03.2016.
 */
public class HorizontalNtbActivity extends Activity {

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_horizontal_ntb);
        initUI();
    }

    private void initUI() {
        final ViewPager viewPager = (ViewPager) findViewById(R.id.vp_horizontal_ntb);
        viewPager.setAdapter(new PagerAdapter() {
            @Override
            public int getCount() {
                return 5;
            }

            @Override
            public boolean isViewFromObject(final View view, final Object object) {
                return view.equals(object);
            }

            @Override
            public void destroyItem(final View container, final int position, final Object object) {
                ((ViewPager) container).removeView((View) object);
            }

            @Override
            public Object instantiateItem(final ViewGroup container, final int position) {
                final View view = LayoutInflater.from(
                        getBaseContext()).inflate(R.layout.item_vp, null, false);

                final TextView txtPage = (TextView) view.findViewById(R.id.txt_vp_item_page);
                txtPage.setText(String.format("Page #%d", position));

                container.addView(view);
                return view;
            }
        });

Самое интересное происходит ниже. Здесь задается массив цветов для кнопок панели навигации.

final String[] colors = getResources().getStringArray(R.array.default_preview);

Затем создается экземпляр NavigationTabBar.
Далее создается список моделей для кнопок панели NavigationTabBar.

final NavigationTabBar navigationTabBar = (NavigationTabBar) findViewById(R.id.ntb_horizontal);
        final ArrayList<NavigationTabBar.Model> models = new ArrayList<>();
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_first),
                        Color.parseColor(colors[0]))
                        .selectedIcon(getResources().getDrawable(R.drawable.ic_sixth))
                        .title("Heart")
                        .badgeTitle("NTB")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_second),
                        Color.parseColor(colors[1]))
//                        .selectedIcon(getResources().getDrawable(R.drawable.ic_eighth))
                        .title("Cup")
                        .badgeTitle("with")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_third),
                        Color.parseColor(colors[2]))
                        .selectedIcon(getResources().getDrawable(R.drawable.ic_seventh))
                        .title("Diploma")
                        .badgeTitle("state")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fourth),
                        Color.parseColor(colors[3]))
//                        .selectedIcon(getResources().getDrawable(R.drawable.ic_eighth))
                        .title("Flag")
                        .badgeTitle("icon")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fifth),
                        Color.parseColor(colors[4]))
                        .selectedIcon(getResources().getDrawable(R.drawable.ic_eighth))
                        .title("Medal")
                        .badgeTitle("777")
                        .build()
        );

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

Затем список кнопок передается экземпляру navigationTabBar методом setModels. Также ему передается ViewPager и устанавливается слушатель смены вкладок. Далее идут пустые методы слушателя. В методе onPageSelected для выбранной вкладки удаляется бейдж.

navigationTabBar.setModels(models);
navigationTabBar.setViewPager(viewPager, 2);
navigationTabBar.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(final int position) {
        navigationTabBar.getModels().get(position).hideBadge();
    }

    @Override
    public void onPageScrollStateChanged(final int state) {

    }
});

Ниже мы видим метод navigationTabBar.postDelayed, где в отдельном потоке реализовано эффектное появление бейджей над кнопками при старте Activity.

navigationTabBar.postDelayed(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < navigationTabBar.getModels().size(); i++) {
                    final NavigationTabBar.Model model = navigationTabBar.getModels().get(i);
                    navigationTabBar.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            model.showBadge();
                        }
                    }, i * 100);
                }
            }
        }, 500);
    }
}

Вот такой относительно несложный пример реализации библиотеки NavigationTabBar.

Следующий пример реализации не намного сложнее, здесь NavigationTabBar используется в связке со стандартными виджетами, такими как AppBarLayout, CollapsingToolbarLayout, Toolbar и FloatingActionButton. За слаженную работу всех компонентов отвечает корневой CoordinatorLayout.

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/parent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#423752"
    android:fitsSystemWindows="true"
    android:orientation="vertical">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="180dp"
        android:fitsSystemWindows="true"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:title="@string/app_name"
            app:expandedTitleTextAppearance="@null"
            app:contentScrim="#605271"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <ImageView
                android:id="@+id/backdrop"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                android:background="#605271"
                android:src="@drawable/ic_eighth"
                android:tint="#9f90af"
                android:padding="32dp"
                app:layout_collapseMode="pin"/>

            <android.support.v7.widget.Toolbar
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:fitsSystemWindows="true"
                app:layout_collapseMode="parallax"
                app:title="@string/app_name"
                app:popupTheme="@style/AppTheme.AppBarOverlay"/>

        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/vp_horizontal_ntb"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

    <devlight.io.library.ntb.NavigationTabBar
        android:id="@+id/ntb_horizontal"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_gravity="bottom"
        app:ntb_badge_size="12sp"
        app:ntb_badge_bg_color="#ffff0000"
        app:ntb_badge_gravity="top"
        app:ntb_badge_position="left"
        app:ntb_badge_title_color="#ffffffff"
        app:ntb_badge_use_typeface="true"
        app:ntb_badged="true"
        app:ntb_typeface="fonts/agency.ttf"/>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_marginBottom="76dp"
        android:layout_marginRight="16dp"
        android:layout_marginEnd="16dp"
        android:tint="#9f90af"
        android:src="@drawable/ic_first"
        app:backgroundTint="#605271"/>

</android.support.design.widget.CoordinatorLayout>

Код в Activity немного отличается от предыдущего примера, за счет добавления новых компонентов.

package devlight.io.sample;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.support.design.widget.CollapsingToolbarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import devlight.io.library.ntb.NavigationTabBar;

import java.util.ArrayList;
import java.util.Random;

/**
 * Created by GIGAMOLE on 28.03.2016.
 */
public class HorizontalCoordinatorNtbActivity extends Activity {

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_horizontal_coordinator_ntb);
        initUI();
    }

    private void initUI() {
        final ViewPager viewPager = (ViewPager) findViewById(R.id.vp_horizontal_ntb);
        viewPager.setAdapter(new PagerAdapter() {
            @Override
            public int getCount() {
                return 5;
            }

            @Override
            public boolean isViewFromObject(final View view, final Object object) {
                return view.equals(object);
            }

            @Override
            public void destroyItem(final View container, final int position, final Object object) {
                ((ViewPager) container).removeView((View) object);
            }

            @Override
            public Object instantiateItem(final ViewGroup container, final int position) {
                final View view = LayoutInflater.from(
                        getBaseContext()).inflate(R.layout.item_vp_list, null, false);

                final RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.rv);
                recyclerView.setHasFixedSize(true);
                recyclerView.setLayoutManager(new LinearLayoutManager(
                                getBaseContext(), LinearLayoutManager.VERTICAL, false
                        )
                );
                recyclerView.setAdapter(new RecycleAdapter());

                container.addView(view);
                return view;
            }
        });

ViewPager здесь использует RecyclerView для реализации прокручиваемого списка.

 final String[] colors = getResources().getStringArray(R.array.default_preview);

        final NavigationTabBar navigationTabBar = (NavigationTabBar) findViewById(R.id.ntb_horizontal);
        final ArrayList<NavigationTabBar.Model> models = new ArrayList<>();
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_first),
                        Color.parseColor(colors[0]))
                        .title("Heart")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_second),
                        Color.parseColor(colors[1]))
                        .title("Cup")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_third),
                        Color.parseColor(colors[2]))
                        .title("Diploma")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fourth),
                        Color.parseColor(colors[3]))
                        .title("Flag")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fifth),
                        Color.parseColor(colors[4]))
                        .title("Medal")
                        .build()
        );

        navigationTabBar.setModels(models);
        navigationTabBar.setViewPager(viewPager, 2);

Реализация NavigationTabBar практически не отличается, за исключением того, что здесь используется только одна иконка для кнопки и выключены бейджи.

//IMPORTANT: ENABLE SCROLL BEHAVIOUR IN COORDINATOR LAYOUT
navigationTabBar.setBehaviorEnabled(true);

А вот и важные отличия. Метод navigationTabBar.setBehaviorEnabled включает синхронизацию при прокрутке с остальными виджетами в CoordinatorLayout.

navigationTabBar.setOnTabBarSelectedIndexListener(new NavigationTabBar.OnTabBarSelectedIndexListener() {
    @Override
    public void onStartTabSelected(final NavigationTabBar.Model model, final int index) {
    }

    @Override
    public void onEndTabSelected(final NavigationTabBar.Model model, final int index) {
        model.hideBadge();
    }
});
navigationTabBar.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(final int position) {

    }

    @Override
    public void onPageScrollStateChanged(final int state) {

    }
});

Далее видим новый слушатель, который определяет выделенную вкладку по индексу.

final CoordinatorLayout coordinatorLayout = (CoordinatorLayout) findViewById(R.id.parent);
findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(final View v) {
        for (int i = 0; i < navigationTabBar.getModels().size(); i++) {
            final NavigationTabBar.Model model = navigationTabBar.getModels().get(i);
            navigationTabBar.postDelayed(new Runnable() {
                @Override
                public void run() {
                    final String title = String.valueOf(new Random().nextInt(15));
                    if (!model.isBadgeShowed()) {
                        model.setBadgeTitle(title);
                        model.showBadge();
                    } else model.updateBadgeTitle(title);
                }
            }, i * 100);
        }

Еще ниже создается экземпляр CoordinatorLayout. Затем определяется FAB и по клику на ней над кнопками панели появляются бейджи, а в методе coordinatorLayout.postDelayed выводится Snackbar с сообщением.

 coordinatorLayout.postDelayed(new Runnable() {
            @Override
            public void run() {
                final Snackbar snackbar = Snackbar.make(navigationTabBar, "Coordinator NTB", Snackbar.LENGTH_SHORT);
                snackbar.getView().setBackgroundColor(Color.parseColor("#9b92b3"));
                ((TextView) snackbar.getView().findViewById(R.id.snackbar_text))
                        .setTextColor(Color.parseColor("#423752"));
                snackbar.show();
            }
        }, 1000);
    }
});

Далее создается CollapsingToolbarLayout — это обертка для тулбара, реализующая эффект коллапсинга — разрушения, или исчезновения тулбара при прокрутке. Здесь же устанавливается цвет текста заголовка при нормально положении тулбара и при коллапсинге.

final CollapsingToolbarLayout collapsingToolbarLayout =
            (CollapsingToolbarLayout) findViewById(R.id.toolbar);
    collapsingToolbarLayout.setExpandedTitleColor(Color.parseColor("#009F90AF"));
    collapsingToolbarLayout.setCollapsedTitleTextColor(Color.parseColor("#9f90af"));
}

И в конце реализация класса адаптера для RecyclerView, который просто создает список на 20 элементов.

public class RecycleAdapter extends RecyclerView.Adapter<RecycleAdapter.ViewHolder> {

        @Override
        public ViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
            final View view = LayoutInflater.from(getBaseContext()).inflate(R.layout.item_list, parent, false);
            return new ViewHolder(view);
        }

        @Override
        public void onBindViewHolder(final ViewHolder holder, final int position) {
            holder.txt.setText(String.format("Navigation Item #%d", position));
        }

        @Override
        public int getItemCount() {
            return 20;
        }

        public class ViewHolder extends RecyclerView.ViewHolder {

            public TextView txt;

            public ViewHolder(final View itemView) {
                super(itemView);
                txt = (TextView) itemView.findViewById(R.id.txt_vp_item_list);
            }
        }
    }
}

Следующий способ — расположение NavigationTabBar в верхней части экрана.


Для этого в файле разметки NavigationTabBar встроен в AppBarLayout.

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#423752"
    android:orientation="vertical">

    <android.support.v4.view.ViewPager
        android:id="@+id/vp_horizontal_ntb"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#00000000">

        <FrameLayout
            android:id="@+id/wrapper_ntb_horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|enterAlways">

            <devlight.io.library.ntb.NavigationTabBar
                android:id="@+id/ntb_horizontal"
                android:layout_width="match_parent"
                android:layout_height="60dp"
                app:ntb_bg_color="#605271"
                app:ntb_title_size="12sp"
                app:ntb_badge_bg_color="#ffff0000"
                app:ntb_badge_gravity="bottom"
                app:ntb_badge_position="left"
                app:ntb_badge_title_color="#ffffffff"
                app:ntb_badge_use_typeface="true"
                app:ntb_badged="true"
                app:ntb_title_mode="active"
                app:ntb_titled="true"
                app:ntb_scaled="false"
                app:ntb_typeface="fonts/agency.ttf"/>

        </FrameLayout>

    </android.support.design.widget.AppBarLayout>

    <View
        android:id="@+id/mask"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:layout_gravity="bottom"/>

</android.support.design.widget.CoordinatorLayout>

Реализация в классе Activity почти не отличается от предыдущего примера, за исключением отсутствия FAB и CollapsingToolbarLayout.

package devlight.io.sample;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import devlight.io.library.ntb.NavigationTabBar;

import java.util.ArrayList;
import java.util.Random;

/**
 * Created by GIGAMOLE on 28.03.2016.
 */
public class TopHorizontalNtbActivity extends Activity {

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_horizontal_top_ntb);
        initUI();
    }

    private void initUI() {
        final ViewPager viewPager = (ViewPager) findViewById(R.id.vp_horizontal_ntb);
        viewPager.setAdapter(new PagerAdapter() {
            @Override
            public int getCount() {
                return 5;
            }

            @Override
            public boolean isViewFromObject(final View view, final Object object) {
                return view.equals(object);
            }

            @Override
            public void destroyItem(final View container, final int position, final Object object) {
                ((ViewPager) container).removeView((View) object);
            }

            @Override
            public Object instantiateItem(final ViewGroup container, final int position) {
                final View view = LayoutInflater.from(
                        getBaseContext()).inflate(R.layout.item_vp_list, null, false);

                final RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.rv);
                recyclerView.setHasFixedSize(true);
                recyclerView.setLayoutManager(new LinearLayoutManager(
                                getBaseContext(), LinearLayoutManager.VERTICAL, false
                        )
                );
                recyclerView.setAdapter(new RecycleAdapter());

                container.addView(view);
                return view;
            }
        });

        final String[] colors = getResources().getStringArray(R.array.default_preview);

        final NavigationTabBar navigationTabBar = (NavigationTabBar) findViewById(R.id.ntb_horizontal);
        final ArrayList<NavigationTabBar.Model> models = new ArrayList<>();
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_first),
                        Color.parseColor(colors[0]))
                        .title("Heart")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_second),
                        Color.parseColor(colors[1]))
                        .title("Cup")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_third),
                        Color.parseColor(colors[2]))
                        .title("Diploma")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fourth),
                        Color.parseColor(colors[3]))
                        .title("Flag")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fifth),
                        Color.parseColor(colors[4]))
                        .title("Medal")
                        .build()
        );
        navigationTabBar.setModels(models);
        navigationTabBar.setViewPager(viewPager, 2);

        navigationTabBar.post(new Runnable() {
            @Override
            public void run() {
                final View viewPager = findViewById(R.id.vp_horizontal_ntb);
                ((ViewGroup.MarginLayoutParams) viewPager.getLayoutParams()).topMargin =
                        (int) -navigationTabBar.getBadgeMargin();
                viewPager.requestLayout();
            }
        });

        navigationTabBar.setOnTabBarSelectedIndexListener(new NavigationTabBar.OnTabBarSelectedIndexListener() {
            @Override
            public void onStartTabSelected(final NavigationTabBar.Model model, final int index) {

            }

            @Override
            public void onEndTabSelected(final NavigationTabBar.Model model, final int index) {
                model.hideBadge();
            }
        });

        findViewById(R.id.mask).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View v) {
                for (int i = 0; i < navigationTabBar.getModels().size(); i++) {
                    final NavigationTabBar.Model model = navigationTabBar.getModels().get(i);
                    navigationTabBar.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            final String title = String.valueOf(new Random().nextInt(15));
                            if (!model.isBadgeShowed()) {
                                model.setBadgeTitle(title);
                                model.showBadge();
                            } else model.updateBadgeTitle(title);
                        }
                    }, i * 100);
                }
            }
        });
    }

    public class RecycleAdapter extends RecyclerView.Adapter<RecycleAdapter.ViewHolder> {

        @Override
        public ViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
            final View view = LayoutInflater.from(getBaseContext()).inflate(R.layout.item_list, parent, false);
            return new ViewHolder(view);
        }

        @Override
        public void onBindViewHolder(final ViewHolder holder, final int position) {
            holder.txt.setText(String.format("Navigation Item #%d", position));
        }

        @Override
        public int getItemCount() {
            return 20;
        }

        public class ViewHolder extends RecyclerView.ViewHolder {

            public TextView txt;

            public ViewHolder(final View itemView) {
                super(itemView);
                txt = (TextView) itemView.findViewById(R.id.txt_vp_item_list);
            }
        }
    }
}

Следующий пример показывает вертикальную реализацию NavigationTabBar.

Файл разметки похож на самый первый пример, только корневой LinearLayout имеет горизонтальную ориентацию.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:background="#423752">

    <devlight.io.library.ntb.NavigationTabBar
        android:id="@+id/ntb_vertical"
        android:layout_width="50dp"
        android:layout_height="match_parent"
        app:ntb_preview_colors="@array/vertical_ntb"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/vp_vertical_ntb"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"/>

</LinearLayout>

Код класса Activity практически не отличается от первого примера.

package devlight.io.sample;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import devlight.io.library.ntb.NavigationTabBar;

import java.util.ArrayList;

/**
 * Created by GIGAMOLE on 28.03.2016.
 */
public class VerticalNtbActivity extends Activity {

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_vertical_ntb);
        initUI();
    }

    private void initUI() {
        final ViewPager viewPager = (ViewPager) findViewById(R.id.vp_vertical_ntb);
        viewPager.setAdapter(new PagerAdapter() {
            @Override
            public int getCount() {
                return 8;
            }

            @Override
            public boolean isViewFromObject(final View view, final Object object) {
                return view.equals(object);
            }

            @Override
            public void destroyItem(final View container, final int position, final Object object) {
                ((ViewPager) container).removeView((View) object);
            }

            @Override
            public Object instantiateItem(final ViewGroup container, final int position) {
                final View view = LayoutInflater.from(
                        getBaseContext()).inflate(R.layout.item_vp, null, false);

                final TextView txtPage = (TextView) view.findViewById(R.id.txt_vp_item_page);
                txtPage.setText(String.format("Page #%d", position));

                container.addView(view);
                return view;
            }
        });

        final String[] colors = getResources().getStringArray(R.array.vertical_ntb);

        final NavigationTabBar navigationTabBar = (NavigationTabBar) findViewById(R.id.ntb_vertical);
        final ArrayList<NavigationTabBar.Model> models = new ArrayList<>();
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_first),
                        Color.parseColor(colors[0]))
                        .selectedIcon(getResources().getDrawable(R.drawable.ic_eighth))
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_second),
                        Color.parseColor(colors[1]))
                        .selectedIcon(getResources().getDrawable(R.drawable.ic_eighth))
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_third),
                        Color.parseColor(colors[2]))
                        .selectedIcon(getResources().getDrawable(R.drawable.ic_eighth))
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fourth),
                        Color.parseColor(colors[3]))
                        .selectedIcon(getResources().getDrawable(R.drawable.ic_eighth))
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fifth),
                        Color.parseColor(colors[4]))
                        .selectedIcon(getResources().getDrawable(R.drawable.ic_eighth))
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_sixth),
                        Color.parseColor(colors[5]))
                        .selectedIcon(getResources().getDrawable(R.drawable.ic_eighth))
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_seventh),
                        Color.parseColor(colors[6]))
                        .selectedIcon(getResources().getDrawable(R.drawable.ic_eighth))
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_eighth),
                        Color.parseColor(colors[7]))
                        .selectedIcon(getResources().getDrawable(R.drawable.ic_eighth))
                        .build()
        );

        navigationTabBar.setModels(models);
        navigationTabBar.setViewPager(viewPager, 4);
    }
}

И наконец, последний пример.

В файле разметки несколько элементов NavigationTabBar во фреймах. Здесь наглядно можно посмотреть, как разные атрибуты влияют на отображение панели на экране.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#423752"
    android:orientation="vertical"
    android:weightSum="2">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal"
        android:weightSum="3">

        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:padding="10dp">

            <devlight.io.library.ntb.NavigationTabBar
                android:id="@+id/ntb_sample_1"
                android:layout_width="80dp"
                android:layout_height="match_parent"
                android:layout_gravity="center"
                app:ntb_bg_color="#605271"
                app:ntb_active_color="#000"
                app:ntb_scaled="false"
                app:ntb_inactive_color="#fff"
                app:ntb_animation_duration="1000"/>

        </FrameLayout>

        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:padding="10dp">

            <devlight.io.library.ntb.NavigationTabBar
                android:id="@+id/ntb_sample_2"
                android:layout_width="50dp"
                android:layout_height="match_parent"
                android:layout_gravity="center"
                app:ntb_bg_color="#d78cd3"
                app:ntb_active_color="#d78cd3"
                app:ntb_inactive_color="#d78cd3"/>

        </FrameLayout>

        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:padding="10dp">

            <devlight.io.library.ntb.NavigationTabBar
                android:id="@+id/ntb_sample_3"
                android:layout_width="60dp"
                android:layout_height="match_parent"
                android:layout_gravity="center"
                app:ntb_bg_color="#00000000"
                app:ntb_corners_radius="10dp"
                app:ntb_inactive_color="#000"
                app:ntb_preview_colors="@array/red_wine"/>

        </FrameLayout>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="vertical"
        android:weightSum="3">

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:padding="10dp">

            <devlight.io.library.ntb.NavigationTabBar
                android:id="@+id/ntb_sample_4"
                android:layout_width="match_parent"
                android:layout_height="80dp"
                android:layout_gravity="center"
                app:ntb_bg_color="#00FFFFFF"
                app:ntb_active_color="#be7818"
                app:ntb_inactive_color="#be7818"
                app:ntb_animation_duration="1000"/>

        </FrameLayout>

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:padding="10dp">

            <devlight.io.library.ntb.NavigationTabBar
                android:id="@+id/ntb_sample_5"
                android:layout_width="200dp"
                android:layout_height="50dp"
                android:layout_gravity="center"
                app:ntb_animation_duration="400"
                app:ntb_preview_colors="@array/red_wine"
                app:ntb_corners_radius="25dp"
                app:ntb_scaled="false"
                app:ntb_active_color="#8d88e4"
                app:ntb_inactive_color="#dddfec"
                app:ntb_bg_color="#8d88e4"/>

        </FrameLayout>

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:padding="10dp">

            <devlight.io.library.ntb.NavigationTabBar
                android:id="@+id/ntb_sample_6"
                android:layout_width="240dp"
                android:layout_height="60dp"
                android:layout_gravity="center"
                app:ntb_bg_color="#4b405c"
                app:ntb_corners_radius="4dp"
                app:ntb_preview_colors="@array/polluted_waves"/>

        </FrameLayout>

    </LinearLayout>

</LinearLayout>

В классе Activity можно увидеть код реализации каждого отдельного элемента NavigationTabBar.

package devlight.io.sample;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.graphics.ColorUtils;
import android.widget.Toast;

import devlight.io.library.ntb.NavigationTabBar;

import java.util.ArrayList;

/**
 * Created by GIGAMOLE on 28.03.2016.
 */
public class SamplesNtbActivity extends Activity {

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_samples_ntb);
        initUI();
    }

    private void initUI() {
        final NavigationTabBar ntbSample1 = (NavigationTabBar) findViewById(R.id.ntb_sample_1);
        final ArrayList<NavigationTabBar.Model> models1 = new ArrayList<>();
        models1.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_first), Color.WHITE
                ).build()
        );
        models1.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_second), Color.LTGRAY
                ).build()
        );
        models1.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_third), Color.GRAY
                ).build()
        );
        models1.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fourth), Color.DKGRAY
                ).build()
        );
        ntbSample1.setModels(models1);

        final NavigationTabBar ntbSample2 = (NavigationTabBar) findViewById(R.id.ntb_sample_2);
        final ArrayList<NavigationTabBar.Model> models2 = new ArrayList<>();
        models2.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_seventh), Color.YELLOW
                ).build()
        );
        models2.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_sixth), Color.YELLOW
                ).build()
        );
        models2.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fifth), Color.YELLOW
                ).build()
        );
        models2.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_eighth), Color.YELLOW
                ).build()
        );
        models2.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_second), Color.YELLOW
                ).build()
        );
        ntbSample2.setModels(models2);
        ntbSample2.setModelIndex(3, true);

        final NavigationTabBar ntbSample3 = (NavigationTabBar) findViewById(R.id.ntb_sample_3);
        final ArrayList<NavigationTabBar.Model> models3 = new ArrayList<>();
        models3.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_seventh), Color.RED
                ).build()
        );
        models3.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_seventh), Color.RED
                ).build()
        );
        models3.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_seventh), Color.RED
                ).build()
        );
        ntbSample3.setModels(models3);
        ntbSample3.setModelIndex(1, true);

        final NavigationTabBar ntbSample4 = (NavigationTabBar) findViewById(R.id.ntb_sample_4);
        final int bgColor = Color.parseColor("#423752");
        final ArrayList<NavigationTabBar.Model> models4 = new ArrayList<>();
        models4.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fifth), bgColor
                ).build()
        );
        models4.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_first), bgColor
                ).build()
        );
        models4.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fourth), bgColor
                ).build()
        );
        models4.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_sixth), bgColor
                ).build()
        );
        models4.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_third), bgColor
                ).build()
        );
        ntbSample4.setModels(models4);
        ntbSample4.setModelIndex(2, true);

        final NavigationTabBar ntbSample5 = (NavigationTabBar) findViewById(R.id.ntb_sample_5);
        final ArrayList<NavigationTabBar.Model> models5 = new ArrayList<>();
        models5.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fifth), Color.WHITE
                ).build()
        );
        models5.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_first), Color.WHITE
                ).build()
        );
        models5.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fourth), Color.WHITE
                ).build()
        );
        models5.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_sixth), Color.WHITE
                ).build()
        );
        ntbSample5.setModels(models5);
        ntbSample5.setModelIndex(2, true);
        ntbSample5.setOnTabBarSelectedIndexListener(new NavigationTabBar.OnTabBarSelectedIndexListener() {
            @Override
            public void onStartTabSelected(final NavigationTabBar.Model model, final int index) {

            }

            @Override
            public void onEndTabSelected(final NavigationTabBar.Model model, final int index) {
                Toast.makeText(SamplesNtbActivity.this, String.format("onEndTabSelected #%d", index), Toast.LENGTH_SHORT).show();
            }
        });

        final NavigationTabBar ntbSample6 = (NavigationTabBar) findViewById(R.id.ntb_sample_6);
        final ArrayList<NavigationTabBar.Model> models6 = new ArrayList<>();
        models6.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fifth), randomColor()
                ).build()
        );
        models6.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_first), randomColor()
                ).build()
        );
        models6.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fourth), randomColor()
                ).build()
        );
        models6.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_sixth), randomColor()
                ).build()
        );
        ntbSample6.setModels(models6);
    }

    private int randomColor() {
        float[] TEMP_HSL = new float[]{0, 0, 0};
        float[] hsl = TEMP_HSL;
        hsl[0] = (float) (Math.random() * 360);
        hsl[1] = (float) (40 + (Math.random() * 60));
        hsl[2] = (float) (40 + (Math.random() * 60));
        return ColorUtils.HSLToColor(hsl);
    }
}

Это был обзор способов реализации библиотеки NavigationTabBar от команды разработчиков Devlight.[:en]Today in the next release of the Design android application overview of an interesting library from the team DevLight. Who does not know, these are successful developers who started once with lessons on our channel. Now they have a big company and tough customers. Interviews with the guys can be viewed on the link. The guys talk about what they achieved and share the secrets of their success with the budding developers.

The repository of DevLight on Github contains many interesting libraries for application design. One of these we will consider today. This is the NavigationTabBar library. It allows you to create and place on the application screen the navigation bar — at the bottom, at the top or side. NavigationTabBar is supported with the SDK version 11 API, has many settings and is easily integrated with all standard components of the screen layout.

 

The library page in GitHub describes how to add a library to the project, lists the parameters, and shows an implementation example in the project.

Also, there is a link to the application code, which demonstrates several ways to use this library. I imported this example into Android Studio. Let’s examine it in more detail.

In the MainActivity, just the buttons for navigating between screens. For each screen there is a separate Activity.

package devlight.io.sample;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPropertyAnimatorListener;
import android.view.View;

public class MainActivity extends Activity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initUI();
    }

    private void initUI() {
        final View btnHorizontalNtb = findViewById(R.id.btn_horizontal_ntb);
        btnHorizontalNtb.setOnClickListener(this);
        final View btnHorizontalCoordinatorNtb = findViewById(R.id.btn_horizontal_coordinator_ntb);
        btnHorizontalCoordinatorNtb.setOnClickListener(this);
        final View btnTopHorizontalNtb = findViewById(R.id.btn_horizontal_top_ntb);
        btnTopHorizontalNtb.setOnClickListener(this);
        final View btnVerticalNtb = findViewById(R.id.btn_vertical_ntb);
        btnVerticalNtb.setOnClickListener(this);
        final View btnSamplesNtb = findViewById(R.id.btn_samples_ntb);
        btnSamplesNtb.setOnClickListener(this);
    }

    @Override
    public void onClick(final View v) {
        ViewCompat.animate(v)
                .setDuration(200)
                .scaleX(0.9f)
                .scaleY(0.9f)
                .setInterpolator(new CycleInterpolator())
                .setListener(new ViewPropertyAnimatorListener() {
                    @Override
                    public void onAnimationStart(final View view) {

                    }

                    @Override
                    public void onAnimationEnd(final View view) {
                        switch (v.getId()) {
                            case R.id.btn_horizontal_ntb:
                                startActivity(
                                        new Intent(MainActivity.this, HorizontalNtbActivity.class)
                                );
                                break;
                            case R.id.btn_horizontal_top_ntb:
                                startActivity(
                                        new Intent(MainActivity.this, TopHorizontalNtbActivity.class)
                                );
                                break;
                            case R.id.btn_horizontal_coordinator_ntb:
                                startActivity(
                                        new Intent(MainActivity.this, HorizontalCoordinatorNtbActivity.class)
                                );
                                break;
                            case R.id.btn_vertical_ntb:
                                startActivity(
                                        new Intent(MainActivity.this, VerticalNtbActivity.class)
                                );
                                break;
                            case R.id.btn_samples_ntb:
                                startActivity(
                                        new Intent(MainActivity.this, SamplesNtbActivity.class)
                                );
                                break;
                            default:
                                break;
                        }
                    }

                    @Override
                    public void onAnimationCancel(final View view) {

                    }
                })
                .withLayer()
                .start();
    }

    private class CycleInterpolator implements android.view.animation.Interpolator {

        private final float mCycles = 0.5f;

        @Override
        public float getInterpolation(final float input) {
            return (float) Math.sin(2.0f * mCycles * Math.PI * input);
        }
    }
}

The first screen implements the horizontal NavigationTabBar.

Its markup is in activity_horizontal_ntb.xml.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    android:background="#423752"
    android:orientation="vertical">

    <android.support.v4.view.ViewPager
        android:id="@+id/vp_horizontal_ntb"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>

    <devlight.io.library.ntb.NavigationTabBar
        android:id="@+id/ntb_horizontal"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        app:ntb_badge_gravity="top"
        app:ntb_badge_position="right"
        app:ntb_badged="true"
        app:ntb_scaled="true"
        app:ntb_tinted="true"
        app:ntb_title_mode="all"
        app:ntb_titled="true"
        app:ntb_swiped="true"/>

</LinearLayout>

Here in the LinearLayout root, the standard ViewPager for displaying and flipping through tabs.

Next is the NavigationTabBar from the Devlight library. In addition to the standard size attributes, here are the settings for the badge position relative to the button, turning on the badge display, turning on the scaling effect and rendering the active button, setting the header display method and last attribute ntb_swiped — I did not understand what it is responsible for. Who will understand — write in the comments.

The entire list of possible attributes of the NavigationTabBar component is here:

<devlight.io.library.ntb.NavigationTabBar
   android:id="@+id/ntb"
   android:layout_width="match_parent"
   android:layout_height="50dp"
   app:ntb_animation_duration="400"
   app:ntb_preview_colors="@array/colors"
   app:ntb_corners_radius="10dp"
   app:ntb_active_color="#fff"
   app:ntb_inactive_color="#000"
   app:ntb_badged="true"
   app:ntb_titled="true"
   app:ntb_scaled="true"
   app:ntb_tinted="true"
   app:ntb_title_mode="all"
   app:ntb_badge_position="right"
   app:ntb_badge_gravity="top"
   app:ntb_badge_bg_color="#ffff0000"
   app:ntb_badge_title_color="#ffffffff"
   app:ntb_typeface="fonts/custom_typeface.ttf"
   app:ntb_badge_use_typeface="true"
   app:ntb_swiped="true"
   app:ntb_bg_color="#000"
   app:ntb_icon_size_fraction="0.5"
   app:ntb_badge_size="10sp"
   app:ntb_title_size="10sp"/>

We are looking at the code HorisontalNtbActivity. In the initUI method, there is a viewPager and for it an adapter with five elements is installed. Next are the standard methods and tabs are created based on the layout with several TextView

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;

import devlight.io.library.ntb.NavigationTabBar;

/**
 * Created by GIGAMOLE on 28.03.2016.
 */
public class HorizontalNtbActivity extends Activity {

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_horizontal_ntb);
        initUI();
    }

    private void initUI() {
        final ViewPager viewPager = (ViewPager) findViewById(R.id.vp_horizontal_ntb);
        viewPager.setAdapter(new PagerAdapter() {
            @Override
            public int getCount() {
                return 5;
            }

            @Override
            public boolean isViewFromObject(final View view, final Object object) {
                return view.equals(object);
            }

            @Override
            public void destroyItem(final View container, final int position, final Object object) {
                ((ViewPager) container).removeView((View) object);
            }

            @Override
            public Object instantiateItem(final ViewGroup container, final int position) {
                final View view = LayoutInflater.from(
                        getBaseContext()).inflate(R.layout.item_vp, null, false);

                final TextView txtPage = (TextView) view.findViewById(R.id.txt_vp_item_page);
                txtPage.setText(String.format("Page #%d", position));

                container.addView(view);
                return view;
            }
        });

The most interesting happens below. Here you define an array of colors for the navigation bar buttons.

final String[] colors = getResources().getStringArray(R.array.default_preview);

Then, an instance of NavigationTabBar is created.
Next, a list of models is created for the buttons on the NavigationTabBar.

final NavigationTabBar navigationTabBar = (NavigationTabBar) findViewById(R.id.ntb_horizontal);
        final ArrayList<NavigationTabBar.Model> models = new ArrayList<>();
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_first),
                        Color.parseColor(colors[0]))
                        .selectedIcon(getResources().getDrawable(R.drawable.ic_sixth))
                        .title("Heart")
                        .badgeTitle("NTB")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_second),
                        Color.parseColor(colors[1]))
//                        .selectedIcon(getResources().getDrawable(R.drawable.ic_eighth))
                        .title("Cup")
                        .badgeTitle("with")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_third),
                        Color.parseColor(colors[2]))
                        .selectedIcon(getResources().getDrawable(R.drawable.ic_seventh))
                        .title("Diploma")
                        .badgeTitle("state")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fourth),
                        Color.parseColor(colors[3]))
//                        .selectedIcon(getResources().getDrawable(R.drawable.ic_eighth))
                        .title("Flag")
                        .badgeTitle("icon")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fifth),
                        Color.parseColor(colors[4]))
                        .selectedIcon(getResources().getDrawable(R.drawable.ic_eighth))
                        .title("Medal")
                        .badgeTitle("777")
                        .build()
        );

For each button, the icon is set, the color of the active icon (from the array of colors above), the icon for the active button, the text of the button, and the text of the badge.

Then the list of buttons is passed to the navigationTabBar instance using the setModels method. It is also passed to the ViewPager and the tabbed change listener is installed. Next are the empty methods of the listener. The onPageSelected method removes the badge for the selected tab.

navigationTabBar.setModels(models);
navigationTabBar.setViewPager(viewPager, 2);
navigationTabBar.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(final int position) {
        navigationTabBar.getModels().get(position).hideBadge();
    }

    @Override
    public void onPageScrollStateChanged(final int state) {

    }
});

Below we see the method navigationTabBar.postDelayed, where in a separate thread implemented a spectacular appearance of badges on the buttons at the start of Activity.

navigationTabBar.postDelayed(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < navigationTabBar.getModels().size(); i++) {
                    final NavigationTabBar.Model model = navigationTabBar.getModels().get(i);
                    navigationTabBar.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            model.showBadge();
                        }
                    }, i * 100);
                }
            }
        }, 500);
    }
}

Here is a relatively simple example of the implementation of the NavigationTabBar library.

The following implementation is not much more complicated, here NavigationTabBar is used in conjunction with standard widgets, such as AppBarLayout, CollapsingToolbarLayout, Toolbar and FloatingActionButton. For the coordinated work of all components, the root CoordinatorLayout answers.

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/parent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#423752"
    android:fitsSystemWindows="true"
    android:orientation="vertical">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="180dp"
        android:fitsSystemWindows="true"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:title="@string/app_name"
            app:expandedTitleTextAppearance="@null"
            app:contentScrim="#605271"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <ImageView
                android:id="@+id/backdrop"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                android:background="#605271"
                android:src="@drawable/ic_eighth"
                android:tint="#9f90af"
                android:padding="32dp"
                app:layout_collapseMode="pin"/>

            <android.support.v7.widget.Toolbar
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:fitsSystemWindows="true"
                app:layout_collapseMode="parallax"
                app:title="@string/app_name"
                app:popupTheme="@style/AppTheme.AppBarOverlay"/>

        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/vp_horizontal_ntb"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

    <devlight.io.library.ntb.NavigationTabBar
        android:id="@+id/ntb_horizontal"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_gravity="bottom"
        app:ntb_badge_size="12sp"
        app:ntb_badge_bg_color="#ffff0000"
        app:ntb_badge_gravity="top"
        app:ntb_badge_position="left"
        app:ntb_badge_title_color="#ffffffff"
        app:ntb_badge_use_typeface="true"
        app:ntb_badged="true"
        app:ntb_typeface="fonts/agency.ttf"/>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_marginBottom="76dp"
        android:layout_marginRight="16dp"
        android:layout_marginEnd="16dp"
        android:tint="#9f90af"
        android:src="@drawable/ic_first"
        app:backgroundTint="#605271"/>

</android.support.design.widget.CoordinatorLayout>

The code in Activity is slightly different from the previous example, by adding new components.

package devlight.io.sample;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.support.design.widget.CollapsingToolbarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import devlight.io.library.ntb.NavigationTabBar;

import java.util.ArrayList;
import java.util.Random;

/**
 * Created by GIGAMOLE on 28.03.2016.
 */
public class HorizontalCoordinatorNtbActivity extends Activity {

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_horizontal_coordinator_ntb);
        initUI();
    }

    private void initUI() {
        final ViewPager viewPager = (ViewPager) findViewById(R.id.vp_horizontal_ntb);
        viewPager.setAdapter(new PagerAdapter() {
            @Override
            public int getCount() {
                return 5;
            }

            @Override
            public boolean isViewFromObject(final View view, final Object object) {
                return view.equals(object);
            }

            @Override
            public void destroyItem(final View container, final int position, final Object object) {
                ((ViewPager) container).removeView((View) object);
            }

            @Override
            public Object instantiateItem(final ViewGroup container, final int position) {
                final View view = LayoutInflater.from(
                        getBaseContext()).inflate(R.layout.item_vp_list, null, false);

                final RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.rv);
                recyclerView.setHasFixedSize(true);
                recyclerView.setLayoutManager(new LinearLayoutManager(
                                getBaseContext(), LinearLayoutManager.VERTICAL, false
                        )
                );
                recyclerView.setAdapter(new RecycleAdapter());

                container.addView(view);
                return view;
            }
        });

ViewPager here uses RecyclerView to implement a scrolling list.

 final String[] colors = getResources().getStringArray(R.array.default_preview);

        final NavigationTabBar navigationTabBar = (NavigationTabBar) findViewById(R.id.ntb_horizontal);
        final ArrayList<NavigationTabBar.Model> models = new ArrayList<>();
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_first),
                        Color.parseColor(colors[0]))
                        .title("Heart")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_second),
                        Color.parseColor(colors[1]))
                        .title("Cup")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_third),
                        Color.parseColor(colors[2]))
                        .title("Diploma")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fourth),
                        Color.parseColor(colors[3]))
                        .title("Flag")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fifth),
                        Color.parseColor(colors[4]))
                        .title("Medal")
                        .build()
        );

        navigationTabBar.setModels(models);
        navigationTabBar.setViewPager(viewPager, 2);

The implementation of NavigationTabBar is practically the same, except that only one icon for the button is used here and the badges are disabled.

//IMPORTANT: ENABLE SCROLL BEHAVIOUR IN COORDINATOR LAYOUT
navigationTabBar.setBehaviorEnabled(true);

And here are the important differences. The navigationTabBar.setBehaviorEnabled method enables synchronization when scrolling with the rest of the widgets in the CoordinatorLayout.

navigationTabBar.setOnTabBarSelectedIndexListener(new NavigationTabBar.OnTabBarSelectedIndexListener() {
    @Override
    public void onStartTabSelected(final NavigationTabBar.Model model, final int index) {
    }

    @Override
    public void onEndTabSelected(final NavigationTabBar.Model model, final int index) {
        model.hideBadge();
    }
});
navigationTabBar.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(final int position) {

    }

    @Override
    public void onPageScrollStateChanged(final int state) {

    }
});

Next, we see a new listener, which defines the highlighted tab by index.

final CoordinatorLayout coordinatorLayout = (CoordinatorLayout) findViewById(R.id.parent);
findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(final View v) {
        for (int i = 0; i < navigationTabBar.getModels().size(); i++) {
            final NavigationTabBar.Model model = navigationTabBar.getModels().get(i);
            navigationTabBar.postDelayed(new Runnable() {
                @Override
                public void run() {
                    final String title = String.valueOf(new Random().nextInt(15));
                    if (!model.isBadgeShowed()) {
                        model.setBadgeTitle(title);
                        model.showBadge();
                    } else model.updateBadgeTitle(title);
                }
            }, i * 100);
        }

Below is an instance of CoordinatorLayout. Then the FAB is determined and by clicking on it on the panel buttons there are badges, and in the coordinatorLayout.postDelayed method Snackbar with a message is displayed.

 coordinatorLayout.postDelayed(new Runnable() {
            @Override
            public void run() {
                final Snackbar snackbar = Snackbar.make(navigationTabBar, "Coordinator NTB", Snackbar.LENGTH_SHORT);
                snackbar.getView().setBackgroundColor(Color.parseColor("#9b92b3"));
                ((TextView) snackbar.getView().findViewById(R.id.snackbar_text))
                        .setTextColor(Color.parseColor("#423752"));
                snackbar.show();
            }
        }, 1000);
    }
});

Next, CollapsingToolbarLayout is created — this is a toolbar wrapper that implements the collapsing effect — destruction, or the disappearance of the toolbar when scrolling. Here, the header text color is set when the toolbar is in the normal position and when collapsing.

final CollapsingToolbarLayout collapsingToolbarLayout =
            (CollapsingToolbarLayout) findViewById(R.id.toolbar);
    collapsingToolbarLayout.setExpandedTitleColor(Color.parseColor("#009F90AF"));
    collapsingToolbarLayout.setCollapsedTitleTextColor(Color.parseColor("#9f90af"));
}

And at the end is the implementation of the adapter class for RecyclerView, which simply creates a list of 20 items.

public class RecycleAdapter extends RecyclerView.Adapter<RecycleAdapter.ViewHolder> {

        @Override
        public ViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
            final View view = LayoutInflater.from(getBaseContext()).inflate(R.layout.item_list, parent, false);
            return new ViewHolder(view);
        }

        @Override
        public void onBindViewHolder(final ViewHolder holder, final int position) {
            holder.txt.setText(String.format("Navigation Item #%d", position));
        }

        @Override
        public int getItemCount() {
            return 20;
        }

        public class ViewHolder extends RecyclerView.ViewHolder {

            public TextView txt;

            public ViewHolder(final View itemView) {
                super(itemView);
                txt = (TextView) itemView.findViewById(R.id.txt_vp_item_list);
            }
        }
    }
}

The next method is the NavigationTabBar location at the top of the screen.


To do this, the NavigationTabBar is built into AppBarLayout in the markup file.

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#423752"
    android:orientation="vertical">

    <android.support.v4.view.ViewPager
        android:id="@+id/vp_horizontal_ntb"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#00000000">

        <FrameLayout
            android:id="@+id/wrapper_ntb_horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|enterAlways">

            <devlight.io.library.ntb.NavigationTabBar
                android:id="@+id/ntb_horizontal"
                android:layout_width="match_parent"
                android:layout_height="60dp"
                app:ntb_bg_color="#605271"
                app:ntb_title_size="12sp"
                app:ntb_badge_bg_color="#ffff0000"
                app:ntb_badge_gravity="bottom"
                app:ntb_badge_position="left"
                app:ntb_badge_title_color="#ffffffff"
                app:ntb_badge_use_typeface="true"
                app:ntb_badged="true"
                app:ntb_title_mode="active"
                app:ntb_titled="true"
                app:ntb_scaled="false"
                app:ntb_typeface="fonts/agency.ttf"/>

        </FrameLayout>

    </android.support.design.widget.AppBarLayout>

    <View
        android:id="@+id/mask"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:layout_gravity="bottom"/>

</android.support.design.widget.CoordinatorLayout>

The implementation in the Activity class almost does not differ from the previous example, except for the absence of FAB and CollapsingToolbarLayout.

package devlight.io.sample;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import devlight.io.library.ntb.NavigationTabBar;

import java.util.ArrayList;
import java.util.Random;

/**
 * Created by GIGAMOLE on 28.03.2016.
 */
public class TopHorizontalNtbActivity extends Activity {

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_horizontal_top_ntb);
        initUI();
    }

    private void initUI() {
        final ViewPager viewPager = (ViewPager) findViewById(R.id.vp_horizontal_ntb);
        viewPager.setAdapter(new PagerAdapter() {
            @Override
            public int getCount() {
                return 5;
            }

            @Override
            public boolean isViewFromObject(final View view, final Object object) {
                return view.equals(object);
            }

            @Override
            public void destroyItem(final View container, final int position, final Object object) {
                ((ViewPager) container).removeView((View) object);
            }

            @Override
            public Object instantiateItem(final ViewGroup container, final int position) {
                final View view = LayoutInflater.from(
                        getBaseContext()).inflate(R.layout.item_vp_list, null, false);

                final RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.rv);
                recyclerView.setHasFixedSize(true);
                recyclerView.setLayoutManager(new LinearLayoutManager(
                                getBaseContext(), LinearLayoutManager.VERTICAL, false
                        )
                );
                recyclerView.setAdapter(new RecycleAdapter());

                container.addView(view);
                return view;
            }
        });

        final String[] colors = getResources().getStringArray(R.array.default_preview);

        final NavigationTabBar navigationTabBar = (NavigationTabBar) findViewById(R.id.ntb_horizontal);
        final ArrayList<NavigationTabBar.Model> models = new ArrayList<>();
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_first),
                        Color.parseColor(colors[0]))
                        .title("Heart")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_second),
                        Color.parseColor(colors[1]))
                        .title("Cup")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_third),
                        Color.parseColor(colors[2]))
                        .title("Diploma")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fourth),
                        Color.parseColor(colors[3]))
                        .title("Flag")
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fifth),
                        Color.parseColor(colors[4]))
                        .title("Medal")
                        .build()
        );
        navigationTabBar.setModels(models);
        navigationTabBar.setViewPager(viewPager, 2);

        navigationTabBar.post(new Runnable() {
            @Override
            public void run() {
                final View viewPager = findViewById(R.id.vp_horizontal_ntb);
                ((ViewGroup.MarginLayoutParams) viewPager.getLayoutParams()).topMargin =
                        (int) -navigationTabBar.getBadgeMargin();
                viewPager.requestLayout();
            }
        });

        navigationTabBar.setOnTabBarSelectedIndexListener(new NavigationTabBar.OnTabBarSelectedIndexListener() {
            @Override
            public void onStartTabSelected(final NavigationTabBar.Model model, final int index) {

            }

            @Override
            public void onEndTabSelected(final NavigationTabBar.Model model, final int index) {
                model.hideBadge();
            }
        });

        findViewById(R.id.mask).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View v) {
                for (int i = 0; i < navigationTabBar.getModels().size(); i++) {
                    final NavigationTabBar.Model model = navigationTabBar.getModels().get(i);
                    navigationTabBar.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            final String title = String.valueOf(new Random().nextInt(15));
                            if (!model.isBadgeShowed()) {
                                model.setBadgeTitle(title);
                                model.showBadge();
                            } else model.updateBadgeTitle(title);
                        }
                    }, i * 100);
                }
            }
        });
    }

    public class RecycleAdapter extends RecyclerView.Adapter<RecycleAdapter.ViewHolder> {

        @Override
        public ViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
            final View view = LayoutInflater.from(getBaseContext()).inflate(R.layout.item_list, parent, false);
            return new ViewHolder(view);
        }

        @Override
        public void onBindViewHolder(final ViewHolder holder, final int position) {
            holder.txt.setText(String.format("Navigation Item #%d", position));
        }

        @Override
        public int getItemCount() {
            return 20;
        }

        public class ViewHolder extends RecyclerView.ViewHolder {

            public TextView txt;

            public ViewHolder(final View itemView) {
                super(itemView);
                txt = (TextView) itemView.findViewById(R.id.txt_vp_item_list);
            }
        }
    }
}

The following example shows the vertical implementation of NavigationTabBar.

The markup file is similar to the very first example, only the LinearLayout root has a horizontal orientation.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:background="#423752">

    <devlight.io.library.ntb.NavigationTabBar
        android:id="@+id/ntb_vertical"
        android:layout_width="50dp"
        android:layout_height="match_parent"
        app:ntb_preview_colors="@array/vertical_ntb"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/vp_vertical_ntb"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"/>

</LinearLayout>

The Activity class code is practically the same as the first example.

package devlight.io.sample;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import devlight.io.library.ntb.NavigationTabBar;

import java.util.ArrayList;

/**
 * Created by GIGAMOLE on 28.03.2016.
 */
public class VerticalNtbActivity extends Activity {

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_vertical_ntb);
        initUI();
    }

    private void initUI() {
        final ViewPager viewPager = (ViewPager) findViewById(R.id.vp_vertical_ntb);
        viewPager.setAdapter(new PagerAdapter() {
            @Override
            public int getCount() {
                return 8;
            }

            @Override
            public boolean isViewFromObject(final View view, final Object object) {
                return view.equals(object);
            }

            @Override
            public void destroyItem(final View container, final int position, final Object object) {
                ((ViewPager) container).removeView((View) object);
            }

            @Override
            public Object instantiateItem(final ViewGroup container, final int position) {
                final View view = LayoutInflater.from(
                        getBaseContext()).inflate(R.layout.item_vp, null, false);

                final TextView txtPage = (TextView) view.findViewById(R.id.txt_vp_item_page);
                txtPage.setText(String.format("Page #%d", position));

                container.addView(view);
                return view;
            }
        });

        final String[] colors = getResources().getStringArray(R.array.vertical_ntb);

        final NavigationTabBar navigationTabBar = (NavigationTabBar) findViewById(R.id.ntb_vertical);
        final ArrayList<NavigationTabBar.Model> models = new ArrayList<>();
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_first),
                        Color.parseColor(colors[0]))
                        .selectedIcon(getResources().getDrawable(R.drawable.ic_eighth))
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_second),
                        Color.parseColor(colors[1]))
                        .selectedIcon(getResources().getDrawable(R.drawable.ic_eighth))
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_third),
                        Color.parseColor(colors[2]))
                        .selectedIcon(getResources().getDrawable(R.drawable.ic_eighth))
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fourth),
                        Color.parseColor(colors[3]))
                        .selectedIcon(getResources().getDrawable(R.drawable.ic_eighth))
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fifth),
                        Color.parseColor(colors[4]))
                        .selectedIcon(getResources().getDrawable(R.drawable.ic_eighth))
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_sixth),
                        Color.parseColor(colors[5]))
                        .selectedIcon(getResources().getDrawable(R.drawable.ic_eighth))
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_seventh),
                        Color.parseColor(colors[6]))
                        .selectedIcon(getResources().getDrawable(R.drawable.ic_eighth))
                        .build()
        );
        models.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_eighth),
                        Color.parseColor(colors[7]))
                        .selectedIcon(getResources().getDrawable(R.drawable.ic_eighth))
                        .build()
        );

        navigationTabBar.setModels(models);
        navigationTabBar.setViewPager(viewPager, 4);
    }
}

And finally, the last example.

There are several NavigationTabBar elements in frames in the markup file. Here you can visually see how different attributes affect the display of the panel on the screen.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#423752"
    android:orientation="vertical"
    android:weightSum="2">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal"
        android:weightSum="3">

        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:padding="10dp">

            <devlight.io.library.ntb.NavigationTabBar
                android:id="@+id/ntb_sample_1"
                android:layout_width="80dp"
                android:layout_height="match_parent"
                android:layout_gravity="center"
                app:ntb_bg_color="#605271"
                app:ntb_active_color="#000"
                app:ntb_scaled="false"
                app:ntb_inactive_color="#fff"
                app:ntb_animation_duration="1000"/>

        </FrameLayout>

        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:padding="10dp">

            <devlight.io.library.ntb.NavigationTabBar
                android:id="@+id/ntb_sample_2"
                android:layout_width="50dp"
                android:layout_height="match_parent"
                android:layout_gravity="center"
                app:ntb_bg_color="#d78cd3"
                app:ntb_active_color="#d78cd3"
                app:ntb_inactive_color="#d78cd3"/>

        </FrameLayout>

        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:padding="10dp">

            <devlight.io.library.ntb.NavigationTabBar
                android:id="@+id/ntb_sample_3"
                android:layout_width="60dp"
                android:layout_height="match_parent"
                android:layout_gravity="center"
                app:ntb_bg_color="#00000000"
                app:ntb_corners_radius="10dp"
                app:ntb_inactive_color="#000"
                app:ntb_preview_colors="@array/red_wine"/>

        </FrameLayout>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="vertical"
        android:weightSum="3">

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:padding="10dp">

            <devlight.io.library.ntb.NavigationTabBar
                android:id="@+id/ntb_sample_4"
                android:layout_width="match_parent"
                android:layout_height="80dp"
                android:layout_gravity="center"
                app:ntb_bg_color="#00FFFFFF"
                app:ntb_active_color="#be7818"
                app:ntb_inactive_color="#be7818"
                app:ntb_animation_duration="1000"/>

        </FrameLayout>

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:padding="10dp">

            <devlight.io.library.ntb.NavigationTabBar
                android:id="@+id/ntb_sample_5"
                android:layout_width="200dp"
                android:layout_height="50dp"
                android:layout_gravity="center"
                app:ntb_animation_duration="400"
                app:ntb_preview_colors="@array/red_wine"
                app:ntb_corners_radius="25dp"
                app:ntb_scaled="false"
                app:ntb_active_color="#8d88e4"
                app:ntb_inactive_color="#dddfec"
                app:ntb_bg_color="#8d88e4"/>

        </FrameLayout>

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:padding="10dp">

            <devlight.io.library.ntb.NavigationTabBar
                android:id="@+id/ntb_sample_6"
                android:layout_width="240dp"
                android:layout_height="60dp"
                android:layout_gravity="center"
                app:ntb_bg_color="#4b405c"
                app:ntb_corners_radius="4dp"
                app:ntb_preview_colors="@array/polluted_waves"/>

        </FrameLayout>

    </LinearLayout>

</LinearLayout>

In the Activity class, you can see the implementation code for each individual NavigationTabBar element.

package devlight.io.sample;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.graphics.ColorUtils;
import android.widget.Toast;

import devlight.io.library.ntb.NavigationTabBar;

import java.util.ArrayList;

/**
 * Created by GIGAMOLE on 28.03.2016.
 */
public class SamplesNtbActivity extends Activity {

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_samples_ntb);
        initUI();
    }

    private void initUI() {
        final NavigationTabBar ntbSample1 = (NavigationTabBar) findViewById(R.id.ntb_sample_1);
        final ArrayList<NavigationTabBar.Model> models1 = new ArrayList<>();
        models1.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_first), Color.WHITE
                ).build()
        );
        models1.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_second), Color.LTGRAY
                ).build()
        );
        models1.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_third), Color.GRAY
                ).build()
        );
        models1.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fourth), Color.DKGRAY
                ).build()
        );
        ntbSample1.setModels(models1);

        final NavigationTabBar ntbSample2 = (NavigationTabBar) findViewById(R.id.ntb_sample_2);
        final ArrayList<NavigationTabBar.Model> models2 = new ArrayList<>();
        models2.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_seventh), Color.YELLOW
                ).build()
        );
        models2.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_sixth), Color.YELLOW
                ).build()
        );
        models2.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fifth), Color.YELLOW
                ).build()
        );
        models2.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_eighth), Color.YELLOW
                ).build()
        );
        models2.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_second), Color.YELLOW
                ).build()
        );
        ntbSample2.setModels(models2);
        ntbSample2.setModelIndex(3, true);

        final NavigationTabBar ntbSample3 = (NavigationTabBar) findViewById(R.id.ntb_sample_3);
        final ArrayList<NavigationTabBar.Model> models3 = new ArrayList<>();
        models3.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_seventh), Color.RED
                ).build()
        );
        models3.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_seventh), Color.RED
                ).build()
        );
        models3.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_seventh), Color.RED
                ).build()
        );
        ntbSample3.setModels(models3);
        ntbSample3.setModelIndex(1, true);

        final NavigationTabBar ntbSample4 = (NavigationTabBar) findViewById(R.id.ntb_sample_4);
        final int bgColor = Color.parseColor("#423752");
        final ArrayList<NavigationTabBar.Model> models4 = new ArrayList<>();
        models4.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fifth), bgColor
                ).build()
        );
        models4.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_first), bgColor
                ).build()
        );
        models4.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fourth), bgColor
                ).build()
        );
        models4.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_sixth), bgColor
                ).build()
        );
        models4.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_third), bgColor
                ).build()
        );
        ntbSample4.setModels(models4);
        ntbSample4.setModelIndex(2, true);

        final NavigationTabBar ntbSample5 = (NavigationTabBar) findViewById(R.id.ntb_sample_5);
        final ArrayList<NavigationTabBar.Model> models5 = new ArrayList<>();
        models5.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fifth), Color.WHITE
                ).build()
        );
        models5.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_first), Color.WHITE
                ).build()
        );
        models5.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fourth), Color.WHITE
                ).build()
        );
        models5.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_sixth), Color.WHITE
                ).build()
        );
        ntbSample5.setModels(models5);
        ntbSample5.setModelIndex(2, true);
        ntbSample5.setOnTabBarSelectedIndexListener(new NavigationTabBar.OnTabBarSelectedIndexListener() {
            @Override
            public void onStartTabSelected(final NavigationTabBar.Model model, final int index) {

            }

            @Override
            public void onEndTabSelected(final NavigationTabBar.Model model, final int index) {
                Toast.makeText(SamplesNtbActivity.this, String.format("onEndTabSelected #%d", index), Toast.LENGTH_SHORT).show();
            }
        });

        final NavigationTabBar ntbSample6 = (NavigationTabBar) findViewById(R.id.ntb_sample_6);
        final ArrayList<NavigationTabBar.Model> models6 = new ArrayList<>();
        models6.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fifth), randomColor()
                ).build()
        );
        models6.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_first), randomColor()
                ).build()
        );
        models6.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_fourth), randomColor()
                ).build()
        );
        models6.add(
                new NavigationTabBar.Model.Builder(
                        getResources().getDrawable(R.drawable.ic_sixth), randomColor()
                ).build()
        );
        ntbSample6.setModels(models6);
    }

    private int randomColor() {
        float[] TEMP_HSL = new float[]{0, 0, 0};
        float[] hsl = TEMP_HSL;
        hsl[0] = (float) (Math.random() * 360);
        hsl[1] = (float) (40 + (Math.random() * 60));
        hsl[2] = (float) (40 + (Math.random() * 60));
        return ColorUtils.HSLToColor(hsl);
    }
}

This was an overview of how to implement the NavigationTabBar library from the Devlight development team.[:]

Понравилась статья? Поделиться с друзьями:
Комментарии: 2
  1. Максим

    Все, сростил…!

  2. Максим

    Всем привет, а как добавить модуль ‘navigationtabbar’ ???

Добавить комментарий