Android TabLayout實現(xiàn)京東詳情效果
Google在2015的IO大會上,給我們帶來了更加詳細(xì)的Material Design設(shè)計規(guī)范,同時,也給我們帶來了全新的Android Design Support Library,在這個support庫里面,Google給我們提供了更加規(guī)范的MD設(shè)計風(fēng)格的控件。最重要的是,Android Design Support Library的兼容性更廣,直接可以向下兼容到Android 2.2。
這兩天需要做一個仿京東詳情的頁面,上面的Tab切換,以前都是自己寫Viewpager+fragment,或者Indicator的深度定制,一直想嘗試一下TabLayout,于是就有了下面的坑。

然后下面是我簡單的實現(xiàn)效果(個人覺得很坑,還不如自己自定義的導(dǎo)航器)

添加引用庫
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:24.2.0'
compile 'com.android.support:design:24.2.0'
compile 'com.android.support:recyclerview-v7:24.2.0'
compile 'com.android.support:cardview-v7:24.2.0'
}
Toolbar與TabLayout
我們來看一下實現(xiàn)的布局:
<?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="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/c12"
android:gravity="center_vertical"
android:minHeight="45dp"
android:orientation="horizontal"
android:paddingLeft="15dp"
android:paddingRight="15dp">
<ImageView
android:id="@+id/back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/back_icon" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="horizontal">
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:tabTextAppearance="@style/TabLayoutTextStyle"
app:tabGravity="center"
app:tabMode="fixed"
app:tabTextColor="@color/c7"
app:tabSelectedTextColor="@color/c8"/>
</LinearLayout>
<ImageView
android:id="@+id/toolbar_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:background="@drawable/more_icon" />
</LinearLayout>
<View style="@style/horizontal_line" />
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<View style="@style/horizontal_line" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="@color/c12"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="收藏"
android:textSize="10sp" />
<View style="@style/vertical_line" />
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="購物車"
android:textSize="10sp" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1.5"
android:background="@color/c8"
android:gravity="center">
<TextView
style="@style/style_c12_s16"
android:gravity="center"
android:text="加入購物車" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
這布局文件最關(guān)鍵的一點就是android.support.design.widget.TabLayout 標(biāo)簽中的app:tabMode=”scrollable”,他設(shè)置tab的模式為“可滑動的”。
其他的用法和Indicator的用法差不多,都需要設(shè)置適配器,然后通過數(shù)據(jù)實現(xiàn)頁面的適配。直接上代碼
Adapter
public class ProductDetailPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> mFragments=null;
private List<String> mTitles=null;
public ProductDetailPagerAdapter(FragmentManager fm, List<Fragment> mFragments,List<String> mTitles) {
super(fm);
this.mFragments =mFragments;
this.mTitles=mTitles;
}
public ProductDetailPagerAdapter(FragmentManager fm, Fragment... fragments) {
super(fm);
this.mFragments = Arrays.asList(fragments);
}
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
@Override
public int getCount() {
return mFragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
return mTitles.get(position);
}
}
主頁面的相關(guān)邏輯,這里的Fragment就是簡單的Fragment。
public class ProductDetailsActivity extends BaseActivity {
@BindView(R.id.viewPager)
ViewPager viewPager;
@BindView(R.id.toolbar_more)
ImageView toolbarMore;
@BindView(R.id.tabLayout)
TabLayout tabLayout;
private List<Fragment> mFragments;
private String[] titles = new String[]{"商品", "詳情"};
private ProductDetailPagerAdapter productPagerAdapter = null;
private MorePopupWindow popupWindow = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_product_details);
ButterKnife.bind(this);
init();
}
private void init() {
initViewPager();
}
private void initViewPager() {
mFragments = new ArrayList<>();
mFragments.add(new ProductFragment());
mFragments.add(new ProductDetailFragment());
productPagerAdapter = new ProductDetailPagerAdapter(getSupportFragmentManager(), mFragments, Arrays.asList(titles));
viewPager.setOffscreenPageLimit(2);
viewPager.setAdapter(productPagerAdapter);
viewPager.setCurrentItem(1);
tabLayout.setupWithViewPager(viewPager);
}
@OnClick(R.id.back)
public void backClick() {
finish();
}
@OnClick(R.id.toolbar_more)
public void moreClick() {
}
private AdapterView.OnItemClickListener onItemClickListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
popupWindow.dismiss();
}
};
public static void open(Context context) {
Intent intent = new Intent(context, ProductDetailsActivity.class);
context.startActivity(intent);
}
}
上面的代碼都比較簡單不做過多的解釋,在使用TabLayout的時候需要注意一點:
tabmode有兩個屬性值:
MODE_FIXED:Fixed tabs display all tabs concurrently and are best used with content that benefits from quick pivots between tabs.
MODE_SCROLLABLE:Scrollable tabs display a subset of tabs at any given moment, and can contain longer tab labels and a larger number of tabs.
MODE_SCROLLABLE適合很多tabs的情況,是可以滾動的,如果你要實現(xiàn)京東的那種擠在一起的效果就需要MODE_FIXED了。
為了更好的滿足開發(fā)需要,TabLayout實現(xiàn)了自定義TabLayout的樣式,然后通過引入
app:tabTextAppearance=""
自定義icon添加到tab
當(dāng)前的TabLayout沒有方法讓我們?nèi)ヌ砑觟con,我們可以使用SpannableString結(jié)合ImageSpan來實現(xiàn)
private int[] imageResId = {
R.drawable.ic_one,
R.drawable.ic_two,
R.drawable.ic_three
};
// ...
@Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
// return tabTitles[position];
Drawable image = context.getResources().getDrawable(imageResId[position]);
image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
SpannableString sb = new SpannableString(" ");
ImageSpan imageSpan = new ImageSpan(image, ImageSpan.ALIGN_BOTTOM);
sb.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return sb;
}
運(yùn)行,發(fā)現(xiàn)沒有顯示,這是因為TabLayout創(chuàng)建的tab默認(rèn)設(shè)置textAllCaps屬性為true,這阻止了ImageSpan被渲染出來,可以通過下面的樣式文件定義來改變:
<style name="MyCustomTabLayout" parent="Widget.Design.TabLayout"> <item name="tabTextAppearance">@style/MyCustomTextAppearance</item> </style> <style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab"> <item name="textAllCaps">false</item> </style>
然后在getPageTitle方法中設(shè)置上有標(biāo)題的tab
@Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
Drawable image = context.getResources().getDrawable(imageResId[position]);
image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
// Replace blank spaces with image icon
SpannableString sb = new SpannableString(" " + tabTitles[position]);
ImageSpan imageSpan = new ImageSpan(image, ImageSpan.ALIGN_BOTTOM);
sb.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return sb;
}
TabLayout還支持自定義View,通過getTabView來設(shè)置,這里就不講怎么實現(xiàn)了,有興趣的可以自行研究。

部分代碼:https://github.com/xiangzhihong/jingdongApp
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android TabLayout(選項卡布局)簡單用法實例分析
- android TabLayout使用方法詳解
- Android 中TabLayout自定義選擇背景滑塊的實例代碼
- Android中TabLayout結(jié)合ViewPager實現(xiàn)頁面切換效果
- Android design包自定義tablayout的底部導(dǎo)航欄的實現(xiàn)方法
- Android中TabLayout+ViewPager 簡單實現(xiàn)app底部Tab導(dǎo)航欄
- Android自定義TabLayout效果
- AndroidUI組件SlidingTabLayout實現(xiàn)ViewPager頁滑動效果
- Android中TabLayout結(jié)合ViewPager實現(xiàn)頁面切換
- TabLayout使用方法詳解
相關(guān)文章
Android中給fragment寫入?yún)?shù)的輕量開發(fā)包FragmentArgs簡介
這篇文章主要介紹了Android中給fragment寫入?yún)?shù)的輕量開發(fā)包FragmentArgs簡介,需要的朋友可以參考下2014-10-10
Android實現(xiàn)帶有指示器的自定義底部導(dǎo)航欄
這篇文章主要為大家詳細(xì)介紹了Android實現(xiàn)帶有指示器的自定義底部導(dǎo)航欄,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-04-04
Android 中使用ExpandableListView 實現(xiàn)分組的實例
這篇文章主要介紹了Android 中使用ExpandableListView 實現(xiàn)分組的實例的相關(guān)資料,這里提供實例代碼及實現(xiàn)效果圖,需要的朋友可以參考下2016-12-12
Android_RecyclerView實現(xiàn)上下滾動廣告條實例(帶圖片)
本篇文章主要介紹了Android_RecyclerView實現(xiàn)上下滾動廣告條實例(帶圖片),具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06
Android自定義View實現(xiàn)炫酷進(jìn)度條
這篇文章主要為大家詳細(xì)介紹了Android自定義View實現(xiàn)炫酷進(jìn)度條,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-11-11
Android設(shè)置PreferenceCategory背景顏色的方法
這篇文章主要介紹了Android設(shè)置PreferenceCategory背景顏色的方法,涉及Android設(shè)置背景色的技巧,需要的朋友可以參考下2015-05-05

