欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android TabLayout实现京东详情效果

程序员文章站 2024-03-05 21:21:31
google在2015的io大会上,给我们带来了更加详细的material design设计规范,同时,也给我们带来了全新的android design support l...

google在2015的io大会上,给我们带来了更加详细的material design设计规范,同时,也给我们带来了全新的android design support library,在这个support库里面,google给我们提供了更加规范的md设计风格的控件。最重要的是,android design support library的兼容性更广,直接可以向下兼容到android 2.2。

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

Android TabLayout实现京东详情效果

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

Android 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来设置,这里就不讲怎么实现了,有兴趣的可以自行研究。

Android TabLayout实现京东详情效果

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

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