Как вы могли заметить, Google обновил многие из своих приложений в стиле Material Design. Одним из основных визуальных изменений в обновления является обновленные раздвижные вкладки. Google дает хорошие руководящие принципы по разработке приложений с вкладками (узнать больше), но не спешит обновлять документацию. В этом учебном пособии я покажу вам, как создать Android приложение с табами — раздвижными вкладками в материальном стиле.
Приступая к работе
1. Добавьте библиотеки appcompat-v7.21.0.+ и appcompat-v4.21.0.+ в файл сборки build.gradle вашего проекта:
[pastacode lang=»java» message=» build.gradle» highlight=»» provider=»manual»]
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.1"
defaultConfig {
applicationId "samples.exoguru.materialtabs"
minSdkVersion 16
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
compile 'com.android.support:support-v4:21.0.3'
}
[/pastacode]
2. Так как Google не обновил их документацию, нам придется украсть два java-файла из открытого исходного кода приложения Google I/O и вставим его в наш пакет java, чтобы наши вкладки выглядели так же, как в обновленных приложениях Google apps. Вы можете получить эти файлы с ссылке ниже:
SlidingTabLayout.java
SlidingTabStrip.java
3. Создайте новый файл с именем colors.xml в папке ресурсов и добавьте следующий код:
[pastacode lang=»bash» message=»colors.xml» highlight=»» provider=»manual»]
#00897B
#00695C
#004D40
[/pastacode]
4. Создайте новый файл в вашей папке res/color/ и присвойте ему имя selector.xml. После этого добавьте следующий код в него. Этот XML-код изменяет цвет текста активной вкладки, позже мы увидим связанный код стороне Java.
[pastacode lang=»java» message=»selector.xml» highlight=»» provider=»manual»]
[/pastacode]
Файлы макетов
5. Вставьте следующий код в файл styles.xml:
[pastacode lang=»php» message=»styles.xml» highlight=»» provider=»manual»]
[/pastacode]
6. Создайте новый файл с именем tool_bar.xml в папке макетов и вставьте следующий код в него:
[pastacode lang=»php» message=»tool_bar.xml » highlight=»» provider=»manual»]
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="@color/ColorPrimary"
android:elevation="2dp"
android:theme="@style/Base.ThemeOverlay.AppCompat.Dark"
xmlns:android="http://schemas.android.com/apk/res/android" />
[/pastacode]
7. Теперь нам нужно добавить Toolbar, SlidingTabLayout и ViewPager в наше Main Activity, поэтому добавьте следующий код в ваш файл activity_main.xml в папке макетов:
[pastacode lang=»php» message=»activity_main.xml» highlight=»» provider=»manual»]
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<include
android:id="@+id/tool_bar"
layout="@layout/tool_bar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
/>
<samples.exoguru.materialtabs.SlidingTabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="2dp"
android:background="@color/ColorPrimary"/>
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_weight="1">
</android.support.v4.view.ViewPager>
</LinearLayout>
[/pastacode]
8. Создадим файлы макетов для вкладок. В моем случае я использую 2 вкладки, и я их называл, tab_1.xml и tab_2.xml:
[pastacode lang=»php» message=»tab_1.xml» highlight=»» provider=»manual»]
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Tab 1 says Hello :D"
android:id="@+id/textView"
android:textColor="@color/tabsScrollColor"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
[/pastacode]
[pastacode lang=»php» message=»tab_2.xml» highlight=»» provider=»manual»]
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Tab 2 says Hello :D"
android:id="@+id/textView"
android:textColor="@color/tabsScrollColor"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
[/pastacode]
Java-файлы
9. Теперь нам нужно сделать два фрагмента для вкладок и макетов, которые мы создали раньше. Нужно создать два java-файла в каталоге Java и добавить следующий код в них, в моем случае я назвал файлы Tab1.java и Tab2.java:
[pastacode lang=»java» message=»Tab1.java» highlight=»» provider=»manual»]
package samples.exoguru.materialtabs;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by Edwin on 15/02/2015.
*/
public class Tab1 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v =inflater.inflate(R.layout.tab_1,container,false);
return v;
}
}
[/pastacode]
[pastacode lang=»java» message=»Tab2.java» highlight=»» provider=»manual»]
package samples.exoguru.materialtabs;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by Edwin on 15/02/2015.
*/
public class Tab2 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v =inflater.inflate(R.layout.tab_2,container,false);
return v;
}
}
[/pastacode]
10. Для обеспечения представления для каждой вкладки, нам нужен ViewPagerAdpater. Создаем новый файл java с именем ViewPagerAdpater.java и добавим в него следующий код:
[pastacode lang=»java» message=»ViewPagerAdpater.java » highlight=»» provider=»manual»]
package samples.exoguru.materialtabs;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
/**
* Created by Edwin on 15/02/2015.
*/
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
CharSequence Titles[]; // This will Store the Titles of the Tabs which are Going to be passed when ViewPagerAdapter is created
int NumbOfTabs; // Store the number of tabs, this will also be passed when the ViewPagerAdapter is created
// Build a Constructor and assign the passed Values to appropriate values in the class
public ViewPagerAdapter(FragmentManager fm,CharSequence mTitles[], int mNumbOfTabsumb) {
super(fm);
this.Titles = mTitles;
this.NumbOfTabs = mNumbOfTabsumb;
}
//This method return the fragment for the every position in the View Pager
@Override
public Fragment getItem(int position) {
if(position == 0) // if the position is 0 we are returning the First tab
{
Tab1 tab1 = new Tab1();
return tab1;
}
else // As we are having 2 tabs if the position is now 0 it must be 1 so we are returning second tab
{
Tab2 tab2 = new Tab2();
return tab2;
}
}
// This method return the titles for the Tabs in the Tab Strip
@Override
public CharSequence getPageTitle(int position) {
return Titles[position];
}
// This method return the Number of tabs for the tabs Strip
@Override
public int getCount() {
return NumbOfTabs;
}
}
[/pastacode]
11. Теперь вам нужно обновить класс populateTabStrip() в файле SlidingTabLayout.Java, просто замените его следующим кодом:
[pastacode lang=»java» message=»SlidingTabLayout.Java» highlight=»» provider=»manual»]
private void populateTabStrip() {
final PagerAdapter adapter = mViewPager.getAdapter();
final View.OnClickListener tabClickListener = new TabClickListener();
for (int i = 0; i < adapter.getCount(); i++) {
View tabView = null;
TextView tabTitleView = null;
if (mTabViewLayoutId != 0) {
// If there is a custom tab view layout id set, try and inflate it
tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip,
false);
tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId);
}
if (tabView == null) {
tabView = createDefaultTabView(getContext());
}
if (tabTitleView == null && TextView.class.isInstance(tabView)) {
tabTitleView = (TextView) tabView;
}
if (mDistributeEvenly) {
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) tabView.getLayoutParams();
lp.width = 0;
lp.weight = 1;
}
tabTitleView.setText(adapter.getPageTitle(i));
tabView.setOnClickListener(tabClickListener);
String desc = mContentDescriptions.get(i, null);
if (desc != null) {
tabView.setContentDescription(desc);
}
mTabStrip.addView(tabView);
if (i == mViewPager.getCurrentItem()) {
tabView.setSelected(true);
}
tabTitleView.setTextColor(getResources().getColorStateList(R.color.selector));
tabTitleView.setTextSize(14);
}
}
[/pastacode]
12. И наконец, обновим класс MainActivity.java путем добавления кода ниже:
[pastacode lang=»java» message=»MainActivity.java» highlight=»» provider=»manual»]
package samples.exoguru.materialtabs;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
/**
* Created by Edwin on 15/02/2015.
*/
public class MainActivity extends ActionBarActivity {
// Declaring Your View and Variables
Toolbar toolbar;
ViewPager pager;
ViewPagerAdapter adapter;
SlidingTabLayout tabs;
CharSequence Titles[]={"Home","Events"};
int Numboftabs =2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Creating The Toolbar and setting it as the Toolbar for the activity
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
// Creating The ViewPagerAdapter and Passing Fragment Manager, Titles fot the Tabs and Number Of Tabs.
adapter = new ViewPagerAdapter(getSupportFragmentManager(),Titles,Numboftabs);
// Assigning ViewPager View and setting the adapter
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(adapter);
// Assiging the Sliding Tab Layout View
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
tabs.setDistributeEvenly(true); // To make the Tabs Fixed set this true, This makes the tabs Space Evenly in Available width
// Setting Custom Color for the Scroll bar indicator of the Tab View
tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
@Override
public int getIndicatorColor(int position) {
return getResources().getColor(R.color.tabsScrollColor);
}
});
// Setting the ViewPager For the SlidingTabsLayout
tabs.setViewPager(pager);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
[/pastacode]
Теперь можно запустить приложение и вы должны получить работающие вкладки в стиле Material Design.
Более наглядно весь процесс смотрите в видео:
Ссылка на исходный код проекта.
Перевод источника.
Продвинутый пример создания вкладок в курсе уроков по созданию реального приложения.
А так же не понятно. Я нашел эти два файла.
SlidingTabLayout.java
SlidingTabStrip.java
Что я должен с ними сделать?
Не могу скачать исходный код проекта. Помогите.
В десятом пункте ошибка «ViewPagerAdpater»
сложнаааааа
Подскажите, как можно разместить на вкладке иконку вместо текста, заранее спасибо