Android TabLayout實(shí)現(xiàn)京東詳情效果
Google在2015的IO大會(huì)上,給我們帶來(lái)了更加詳細(xì)的Material Design設(shè)計(jì)規(guī)范,同時(shí),也給我們帶來(lái)了全新的Android Design Support Library,在這個(gè)support庫(kù)里面,Google給我們提供了更加規(guī)范的MD設(shè)計(jì)風(fēng)格的控件。最重要的是,Android Design Support Library的兼容性更廣,直接可以向下兼容到Android 2.2。
這兩天需要做一個(gè)仿京東詳情的頁(yè)面,上面的Tab切換,以前都是自己寫(xiě)Viewpager+fragment,或者Indicator的深度定制,一直想嘗試一下TabLayout,于是就有了下面的坑。
然后下面是我簡(jiǎn)單的實(shí)現(xiàn)效果(個(gè)人覺(jué)得很坑,還不如自己自定義的導(dǎo)航器)
添加引用庫(kù)
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
我們來(lái)看一下實(shí)現(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="購(gòu)物車(chē)" 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="加入購(gòu)物車(chē)" /> </LinearLayout> </LinearLayout> </LinearLayout>
這布局文件最關(guān)鍵的一點(diǎn)就是android.support.design.widget.TabLayout 標(biāo)簽中的app:tabMode=”scrollable”,他設(shè)置tab的模式為“可滑動(dòng)的”。
其他的用法和Indicator的用法差不多,都需要設(shè)置適配器,然后通過(guò)數(shù)據(jù)實(shí)現(xiàn)頁(yè)面的適配。直接上代碼
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); } }
主頁(yè)面的相關(guān)邏輯,這里的Fragment就是簡(jiǎn)單的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); } }
上面的代碼都比較簡(jiǎn)單不做過(guò)多的解釋,在使用TabLayout的時(shí)候需要注意一點(diǎn):
tabmode有兩個(gè)屬性值:
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的情況,是可以滾動(dòng)的,如果你要實(shí)現(xiàn)京東的那種擠在一起的效果就需要MODE_FIXED了。
為了更好的滿足開(kāi)發(fā)需要,TabLayout實(shí)現(xiàn)了自定義TabLayout的樣式,然后通過(guò)引入
app:tabTextAppearance=""
自定義icon添加到tab
當(dāng)前的TabLayout沒(méi)有方法讓我們?nèi)ヌ砑觟con,我們可以使用SpannableString結(jié)合ImageSpan來(lái)實(shí)現(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)沒(méi)有顯示,這是因?yàn)門(mén)abLayout創(chuàng)建的tab默認(rèn)設(shè)置textAllCaps屬性為true,這阻止了ImageSpan被渲染出來(lái),可以通過(guò)下面的樣式文件定義來(lái)改變:
<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,通過(guò)getTabView來(lái)設(shè)置,這里就不講怎么實(shí)現(xiàn)了,有興趣的可以自行研究。
部分代碼:https://github.com/xiangzhihong/jingdongApp
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android TabLayout(選項(xiàng)卡布局)簡(jiǎn)單用法實(shí)例分析
- android TabLayout使用方法詳解
- Android 中TabLayout自定義選擇背景滑塊的實(shí)例代碼
- Android中TabLayout結(jié)合ViewPager實(shí)現(xiàn)頁(yè)面切換效果
- Android design包自定義tablayout的底部導(dǎo)航欄的實(shí)現(xiàn)方法
- Android中TabLayout+ViewPager 簡(jiǎn)單實(shí)現(xiàn)app底部Tab導(dǎo)航欄
- Android自定義TabLayout效果
- AndroidUI組件SlidingTabLayout實(shí)現(xiàn)ViewPager頁(yè)滑動(dòng)效果
- Android中TabLayout結(jié)合ViewPager實(shí)現(xiàn)頁(yè)面切換
- TabLayout使用方法詳解
相關(guān)文章
Android使用Handler實(shí)現(xiàn)打地鼠游戲
這篇文章主要為大家詳細(xì)介紹了Android使用Handler實(shí)現(xiàn)打地鼠游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06Android中給fragment寫(xiě)入?yún)?shù)的輕量開(kāi)發(fā)包FragmentArgs簡(jiǎn)介
這篇文章主要介紹了Android中給fragment寫(xiě)入?yún)?shù)的輕量開(kāi)發(fā)包FragmentArgs簡(jiǎn)介,需要的朋友可以參考下2014-10-10Android實(shí)現(xiàn)帶有指示器的自定義底部導(dǎo)航欄
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)帶有指示器的自定義底部導(dǎo)航欄,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04Android 中使用ExpandableListView 實(shí)現(xiàn)分組的實(shí)例
這篇文章主要介紹了Android 中使用ExpandableListView 實(shí)現(xiàn)分組的實(shí)例的相關(guān)資料,這里提供實(shí)例代碼及實(shí)現(xiàn)效果圖,需要的朋友可以參考下2016-12-12Android_RecyclerView實(shí)現(xiàn)上下滾動(dòng)廣告條實(shí)例(帶圖片)
本篇文章主要介紹了Android_RecyclerView實(shí)現(xiàn)上下滾動(dòng)廣告條實(shí)例(帶圖片),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06Android實(shí)現(xiàn)為T(mén)ab添加Menu的方法
這篇文章主要介紹了Android實(shí)現(xiàn)為T(mén)ab添加Menu的方法,分析了兩種解決方法的思路并對(duì)比分析了相應(yīng)的優(yōu)缺點(diǎn),具有一定參考借鑒價(jià)值,需要的朋友可以參考下2016-10-10Android自定義View實(shí)現(xiàn)炫酷進(jìn)度條
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)炫酷進(jìn)度條,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11Android設(shè)置PreferenceCategory背景顏色的方法
這篇文章主要介紹了Android設(shè)置PreferenceCategory背景顏色的方法,涉及Android設(shè)置背景色的技巧,需要的朋友可以參考下2015-05-05