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

android TabLayout实现京东详情效果的更多相关文章

  1. 【京东详情页】——原生js爬坑之放大镜

    一.引言 在商城的详情页中,放大镜的功能是很常见的.这里京东详情页就要做一个仿放大镜的效果,预览如下: 二.实现原理 实际上,放大镜的实现是单纯用几个div,鼠标移入其中一个小图div,触发事件显示另 ...

  2. 【京东详情页】——原生js爬坑之二级菜单

    一.引言 做京东详情页仿写的时候,要用原生js实现顶部菜单的二级菜单显示与隐藏事件的触发. 过程中遇到了一个坑,在这里与大家分享.要实现的效果如下: 二.坑 谁触发事件?显示.隐藏二级菜单       ...

  3. android银行卡匹配、详情展开动画、仿爱奇艺视频拖拽、扫码识别手机号等源码

    Android精选源码 android实现银行卡匹配信息源码 android实现可以展开查看详情的卡片 下拉刷新,上拉加载,侧滑显示菜单等效果RefreshSwipeRecyclerview andr ...

  4. Android 滑动定位+吸附悬停效果实现

    在前两篇文章中,分别介绍了tablayout+scrollview 和 tablayout+recyclerview 实现的滑动定位的功能,文章链接: Android 实现锚点定位 Android t ...

  5. Android RecyclerView 实现支付宝首页效果

    Android RecyclerView 实现支付宝首页效果 [TOC] 虽然我本人不喜欢支付宝的,但是这个网格本身其实还是不错的,项目更新中更改了一个布局为网格模式,类似支付宝.(估计是产品抄袭的= ...

  6. 在android中用跑马灯的效果显示textview

    大家好,在我们通常的android project中,通常需要用到textview这一个布局文件,并且对于这一个显示布局所需要的文本文字内容. 下面我们就来介绍一种方法来实现在android中用跑马灯 ...

  7. 50个Android开发人员必备UI效果源码[转载]

    50个Android开发人员必备UI效果源码[转载] http://blog.csdn.net/qq1059458376/article/details/8145497 Android 仿微信之主页面 ...

  8. android中设置Animation 动画效果

    在 Android 中, Animation 动画效果的实现可以通过两种方式进行实现,一种是 tweened animation 渐变动画,另一种是 frame by frame animation ...

  9. Android 实现书籍翻页效果----升级篇

    自从之前发布了<Android 实现书籍翻页效果----完结篇 >之后,收到了很多朋友给我留言,前段时间由于事情较多,博客写得太匆忙很多细节地方没有描述清楚.所以不少人对其中的地方有不少不 ...

随机推荐

  1. map函数用法详解

    map函数是Python内置的高阶函数,它是一个典型的函数式编程例子.它的参数为: 一个函数function.一个或多个sequence.通过把函数function依次作用在sequence的每个元素 ...

  2. 记录一些移动端H5,小程序视觉还原问题及方法

    前端,特别是移动端如果对视觉还原要求比较高的时候.功能测试和性能测试完成之后.UI真的是一个像素一个像素的给你抠出来哪里还原不到位 之前项目要求还原度要达到98%以上.所以每到视觉还原的时候真的是挺痛 ...

  3. 第一次作业:基于Linux操作系统深入源码进程模型分析

    1.Linux操作系统的简易介绍 Linux系统一般有4个主要部分:内核.shell.文件系统和应用程序.内核.shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序.管理文件并使 ...

  4. PHP 实例 - AJAX 实时搜索

    AJAX Live Search 在下面的实例中,我们将演示一个实时的搜索,在您键入数据的同时即可得到搜索结果. 实时的搜索与传统的搜索相比,具有很多优势: 当键入数据时,就会显示出匹配的结果 当继续 ...

  5. Docker实例:创建一个点到点连接

    默认情况下,Docker 会将所有容器连接到由 docker0 提供的虚拟子网中. 用户有时候需要两个容器之间可以直连通信,而不用通过主机网桥进行桥接. 解决办法很简单:创建一对 peer 接口,分别 ...

  6. Python 3.3.2 round函数并非"四舍五入"

    对于一些貌似很简单常见的函数,最好还是去读一下Python文档,否则当你被某个BUG折磨得死去活来时,还不知根源所在.尤其是Python这种不断更新的语言.(python 2.7 的round和3.3 ...

  7. Ubuntu环境下Anaconda安装TensorFlow并配置Jupyter远程访问

    本文主要讲解在Ubuntu系统中,如何在Anaconda下安装TensorFlow以及配置Jupyter Notebook远程访问的过程. 在官方文档中提到,TensorFlow的安装主要有以下五种形 ...

  8. Oracle 11g客户端及PLSQL Developer配置|Instant Client Setup-64位|OraClientLite11g_x86

    转载自:http://blog.csdn.net/xiaoyw71/article/details/45311589 Oracle 11g客户端 资源 下载资源,直接解压进行配置 Oracle官方资源 ...

  9. Java学习之控制跳转语句

    控制跳转语句 控制跳转语句: (1)break:中断的意思 A:用在循环和switch语句中,离开此应用场景无意义. B:作用 a:跳出单层循环 b:跳出多层循环,需要标签语句的配合 (2)conti ...

  10. Hadoop与分布式数据处理 Spark VS Hadoop有哪些异同点?

    Spark是一个开源的通用并行分布式计算框架,由加州大学伯克利分校的AMP实验室开发,支持内存计算.多迭代批量处理.即席查询.流处理和图计算等多种范式.Spark内存计算框架适合各种迭代算法和交互式数 ...