Android TabLayout实现京东详情效果

Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的Android Design Support Library,在这个support库里面,Google给我们提供了更加规范的MD设计风格的控件。最重要的是,Android Design Support Library的兼容性更广,直接可以向下兼容到Android 2.2。

这两天需要做一个仿京东详情的页面,上面的Tab切换,以前都是自己写Viewpager+fragment,或者Indicator的深度定制,一直想尝试一下TabLayout,于是就有了下面的坑。

然后下面是我简单的实现效果(个人觉得很坑,还不如自己自定义的导航器)

添加引用库

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

我们来看一下实现的布局:

<?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>

这布局文件最关键的一点就是android.support.design.widget.TabLayout 标签中的app:tabMode=”scrollable”,他设置tab的模式为“可滑动的”。

其他的用法和Indicator的用法差不多,都需要设置适配器,然后通过数据实现页面的适配。直接上代码

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);
 }
}

主页面的相关逻辑,这里的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的情况,是可以滚动的,如果你要实现京东的那种挤在一起的效果就需要MODE_FIXED了。

为了更好的满足开发需要,TabLayout实现了自定义TabLayout的样式,然后通过引入

app:tabTextAppearance=""

自定义icon添加到tab

当前的TabLayout没有方法让我们去添加icon,我们可以使用SpannableString结合ImageSpan来实现

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;
}

运行,发现没有显示,这是因为TabLayout创建的tab默认设置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方法中设置上有标题的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来设置,这里就不讲怎么实现了,有兴趣的可以自行研究。

部分代码:https://github.com/xiangzhihong/jingdongApp

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android自定义TabLayout效果

    周末就要到了,今天项目中遇到这样一个Tab,选中tab的背景是个圆角矩形,方向指向器没有了,这样普通的TabLayout不能满足我的要求,可能会想到动态的去设置选中Tab的背景不就可以了,但是那样的话太生硬了,没有动画效果,其实想想也还比较简单,今天就简单的说一说这个YzzTab.效果如下图: 这里是四个Tab,一版只显示3个,这里假设有num个Tab,当滑动到第3个时,这里就需要考虑如何让TabLayout和指示器一起移动呢? @Override public void onPageScrol

  • AndroidUI组件SlidingTabLayout实现ViewPager页滑动效果

    使用SlidingTabLayout需要准备2个类,分别是 SlidingTabLayout,与SlidingTabStrip,,放进项目中时只用修改下包名即可. 效果制作的不是很好. 这篇文章,也是在网上搜了很多资源参考,对 SlidingTabLayout.java和SlidingTabStrip.java进行了修改.大家可以更改他的格式字体大小.选中状态,分割线调整等等.先上传这两个文件,改动支出都做了注释. SlidingTabLayout.java /* * Copyright (C)

  • Android中TabLayout结合ViewPager实现页面切换

    一.实现思路 1.在build.gradle中添加依赖,例如: compile 'com.android.support:support-v4:23.4.0' compile 'com.android.support:design:23.4.0' 也可以将support-v4替换为appcompat-v7,例如: compile 'com.android.support:appcompat-v7:23.4.0' 因为appcompat-v7是依赖于support-v4的. 更多说明可参考官方文档

  • Android中TabLayout结合ViewPager实现页面切换效果

    先看看效果,如图: 1.因为TabLayout是Android Design Support Library官方库的一个控件,所以使用TabLayout时候需要先添加对该库的依赖 compile 'com.android.support:design:22.2.0' 2.下面是TabLayout和ViewPager配合使用的布局 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns

  • android TabLayout使用方法详解

    Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的Android Design Support Library,在这个support库里面,Google给我们提供了更加规范的MD设计风格的控件.最重要的是,Android Design Support Library的兼容性更广,直接可以向下兼容到Android 2.2. 这两天需要做一个仿京东详情的页面,上面的Tab切换,以前都是自己写Viewpager+fragment

  • Android design包自定义tablayout的底部导航栏的实现方法

    以前做项目大多用的radiobutton,今天用tablayout来做一个tab切换页面的的效果. 实现的效果就是类似QQ.微信的页面间(也就是Fragment间)的切换.如图: 布局只要一个tablayout <android.support.design.widget.TabLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:id=&

  • Android中TabLayout+ViewPager 简单实现app底部Tab导航栏

    前言 在谷歌发布Android Design Support Library之前,app底部tab布局的实现方法就有很多种,其中有RadioGroup+FrameLayout.TabHost+Fragment.FragmentPagerAdapter+ViewPager等方法,虽然这些方法虽然能达到同样的效果,但我个人总觉得有些繁琐.然而,Google在2015的IO大会上,给开发者们带来了全新的Android Design Support Library,里面包含了许多新控件,这些新控件有许多

  • TabLayout使用方法详解

    TabLayout是design库提供的控件,可以方便的使用指示器,功能类似ViewPagerIndicator. 使用非常方便,Android Studio只需要在gradle中引入即可使用 . compile 'com.android.support:design:23.3.0' TabLayout即可以单独使用,也可以配合ViewPager来使用. 先来看看单独使用的Demo,实现如下图的效果: 代码如下: package blog.csdn.net.mchenys.tablayoudem

  • Android TabLayout(选项卡布局)简单用法实例分析

    本文实例讲述了Android TabLayout(选项卡布局)简单用法.分享给大家供大家参考,具体如下: 我们在应用viewpager的时候,经常会使用TabPageIndicator来与其配合.达到很漂亮的效果.但是TabPageIndicator是第三方的,而且比较老了,当然了现在很多大神都已经开始自己写TabPageIndicator来满足自己的需求,在2015年的google大会上,google发布了新的Android Support Design库,里面包含了几个新的控件,其中就有一个

  • Android 中TabLayout自定义选择背景滑块的实例代码

    TabLayout是Android 的Material Design包中的一个控件,可以和V4包中的ViewPager搭配产生一个联动的效果.这里我自定义了一个滑块能够跟随TabLayout进行滑动选择的SliderLayout.效果见下图(白色方框): 下面是SliderLayout的源码: import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawabl

随机推荐