[: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.[:]
Все, сростил…!
Всем привет, а как добавить модуль ‘navigationtabbar’ ???