再此之前我有用过较老的PagerTabStrip与ViewPager实现类似的效果,此篇我使用的是TabLayout与Viewpager的搭配~
关联文章
Tablyout属于Design库下的一款优秀控件,貌似在5.0之后应用的场景才慢慢增多
在Android中的每个APP,几乎都有使用这个控件,可谓非常之频繁,所以这次我为大家带来一个简单的Demo,代码逻辑都非常简单,大家很容易上手
实现效果
- Effect 1 - 基础版
Effect 2 -2019/01/12
基础认知
适合自己的才是最好的,请关注以下的注意点~
建议使用AndroidStudio
进行开发,因为使用起来确实比我们之前的Eclipse
方便挺多!如果还在用Eclipse
的话,那么从网上找一下jar包进行使用吧,下面我用的的As - -!
- bulid-gradle添加一下配置:
//版本多少,适配当前项目既可
compile 'com.android.support:design:24.2.1'
- Xml中的命名控件引用:
xmlns:app="http://schemas.android.com/apk/res-auto"
- 注意:自定义控件的自定义属性,要想使用需要如上方配置,方可使用,可在Xml中与代码中使用,均看自己习惯
指针颜色
app:tabIndicatorColor="@color/white"
当前选取的文本颜色
app:tabSelectedTextColor="@color/gray"
默认的文本颜色
app:tabTextColor="@color/white"
第3点有待考察
1.scrollable 滚动类型
2.fixed平分类型
3.其中的fixed模式需要和tabGravity属性配合使用,此时tabGravity属性值为fill.
app:tabMode="fixed"
API | 含义 |
---|---|
app:tabSelectedTextColor =”@android:color/holo_orange_light” | 改变选中字体 的颜色 |
app:tabTextColor =”@color/colorPrimary” | 改变未选中字体 的颜色 |
app:tabIndicatorColor =”@android:color/holo_orange_light” | 改变指示器下标 的颜色 |
app:tabBackground =”color” | 改变整个TabLayout的颜色 |
app:tabTextAppearanc e=”@android:style/TextAppearance.Holo.Large” | 改变TabLayout内部字体大小 |
app:tabIndicatorHeight =”4dp” | 改变指示器下标的高度 |
app:tabMode=”scrollable” | 设置模式,默认fixed |
app:paddingStart=”xxdp” app:paddingEnd=”xxdp” | 设置整个TabLayout的Padding |
app:tabPadding、app:tabPaddingTop、app:tabPaddingStart、app:tabPaddingEnd、- - app:tabPaddingBottom | 设置Tab内部的子控件的Padding |
app:tabGravity=”center” | 内容的显示模式,center 居中,如果是fill,则是充满 |
app:tabMaxWidth=”xxdp” 设置最大的tab宽度;app:tabMinWidth 设置最小的tab宽度 | Tab的宽度限制 |
app:tabContentStart=”100dp” | TabLayout开始位置的偏移量 |
常用方法 - 涵盖部分重载方法
API | 含义 |
---|---|
addTab (TabLayout.Tab tab, int position, boolean setSelected) | 增加选项卡到 layout 中 |
addTab(TabLayout.Tab tab, boolean setSelected) | 同上 |
addTab(TabLayout.Tab tab) | 同上 |
getTabAt(int index) | 得到选项卡 |
getTabCount() | 得到选项卡的总个数 |
getTabGravity() | 得到 tab 的 Gravity |
getTabMode() | 得到 tab 的模式 |
getTabTextColors() | 得到 tab 中文本的颜色 |
newTab() | 新建个 tab |
removeAllTabs() | 移除所有的 tab |
removeTab(TabLayout.Tab tab) | 移除指定的 tab |
removeTabAt(int position) | 移除指定位置的 tab |
setOnTabSelectedListener(TabLayout.OnTabSelectedListener onTabSelectedListener) | 为每个 tab 增加选择监听器 |
setScrollPosition(int position, float positionOffset, boolean updateSelectedText) | 设置滚动位置 |
setTabGravity(int gravity) | 设置 Gravity |
setTabMode(int mode) | 设置 Mode,有两种值:TabLayout.MODE_SCROLLABLE和TabLayout.MODE_FIXED分别表示当tab的内容超过屏幕宽度是否支持横向水平滑动,第一种支持滑动,第二种不支持,默认不支持水平滑动。 |
setTabTextColors(ColorStateList textColor) | 设置 tab 中文本的颜色 |
setTabTextColors(int normalColor, int selectedColor) | 设置 tab 中文本的颜色 默认 选中 |
setTabsFromPagerAdapter(PagerAdapter adapter) | 设置 PagerAdapter |
setupWithViewPager(ViewPager viewPager) | 和 ViewPager 联动 |
代码实践
MainActivity
package com.example.dow.tablayout;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.ListFragment;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private TabLayout mTab;
private ViewPager mVp;
List<String> tabLists = new ArrayList<String>();
List<Fragment>viewpagerLists = new ArrayList<Fragment>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//视图查找
initView();
//数据填充
initData();
//俩者关联
initOhters();
}
private void initView() {
mVp = (ViewPager) findViewById(R.id.vp);
mTab = (TabLayout) findViewById(R.id.tab);
}
private void initData() {
tabLists.add("Life");
tabLists.add("Work");
tabLists.add("Play");
LifeFragment mLife = new LifeFragment();
WorkFragment mWork = new WorkFragment();
PlayFragment mPlay = new PlayFragment();
viewpagerLists.add(mLife);
viewpagerLists.add(mWork);
viewpagerLists.add(mPlay);
}
private void initOhters() {
//Adapter简单非常封装一下,传入储存tab的list和储存fragment的list就好
mVp.setAdapter(new OursAdapter(getSupportFragmentManager(), tabLists, viewpagerLists));
//俩者的关联方法
mTab.setupWithViewPager(mVp);
//tablayout有俩者模式,但是我觉得大多数还是我们现在使用的这一种-相当于权重当前空间
mTab.setTabMode(TabLayout.MODE_FIXED);
}
public class OursAdapter extends FragmentPagerAdapter {
List<String> tabLists = new ArrayList<String>();
List<Fragment> pageLists = new ArrayList<Fragment>();
public OursAdapter(FragmentManager fm, List tabLists, List pageLists) {
super(fm);
this.tabLists = tabLists;
this.pageLists = pageLists;
}
@Override
public Fragment getItem(int position) {
return pageLists.get(position);
}
@Override
public int getCount() {
return pageLists.size();
}
@Override
public CharSequence getPageTitle(int position) {
return tabLists.get(position % tabLists.size());
}
}
}
- activity_main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.dow.tablayout.MainActivity">
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
app:tabTextColor="#159"
app:tabIndicatorColor="#147"
app:tabSelectedTextColor="#111"
android:layout_height="wrap_content"
android:id="@+id/tab" />
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/vp"
/>
</LinearLayout>
LifeFragment(填充的itemFragment,这个大家可以根据自己项目写,此处只写一个用于示例)
package com.example.dow.tablayout;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class LifeFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_life,null);
}
}
- fragment_life
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="生活"
android:gravity="center"
android:textColor="#f00"
android:textSize="20sp"
/>
</LinearLayout>
常见问题
1.用此adapter替换我们之前的adapter
public class MPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> mFragmentList;
private List<String> mTitles;
public MPagerAdapter(FragmentManager fm, List<String> titles, List<Fragment> fragList) {
super(fm);
mFragmentList = fragList;
mTitles = titles;
}
@Override
public Fragment getItem(int arg0) {
return mFragmentList.size() != 0 ? mFragmentList.get(arg0) : null;
}
@Override
public int getCount() {
return mFragmentList == null ? 0 : mFragmentList.size();
}
@Override
public CharSequence getPageTitle(int position) {
return mTitles.size() != 0 ? mTitles.get(position) : "";
}
// 动态设置我们标题的方法
public void setPageTitle(int position, String title)
{
if(position >= 0 && position < mTitles.size())
{
mTitles.set(position, title);
notifyDataSetChanged();
}
}
}
2.在对应的fragment下找到我们使用的adapter,通过adapter内的setPageTitle动态替换tab 的标题值就可以~
mAdapter.setPageTitle("开心就好~");
效果 2 - 2019/01/12 补入
Effect 2 的效果
因为用tabLayout不太好实现,故没有使用TabLayout+ViewPager
! 而是采用平常布局 + ViewPager搭配使用
!
- shape_msg_red_dot (未读标志: 小红点)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/red1"/>
<stroke
android:width="@dimen/d1"
android:color="@color/white"/>
</shape>
- MsgVpAdapter
package com.bakheet.garage.home.adapter;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import java.util.List;
/**
* author
* date 2018/5/8.
* desc:
*/
public class MsgVpAdapter extends FragmentPagerAdapter {
private List<Fragment> fragmentList;
public MsgVpAdapter(FragmentManager fm, List<Fragment> fList) {
super(fm);
this.fragmentList = fList;
}
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public int getCount() {
return fragmentList.size();
}
}
- AskPriceManageActivity
package com.bakheet.garage.mine.askprice.activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.bakheet.garage.R;
import com.bakheet.garage.base.BaseActivity;
import com.bakheet.garage.home.adapter.MsgVpAdapter;
import com.bakheet.garage.mine.askprice.fragment.AskendFragment;
import com.bakheet.garage.mine.askprice.fragment.AskingFragment;
import com.bakheet.garage.utils.DeviceUtils;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
/**
* author Liu
* date 2019/1/10.
* desc:询价管理
*/
public class AskPriceManageActivity extends BaseActivity {
@BindView(R.id.vp_state)
ViewPager mPager;
@BindView(R.id.tv_create)
TextView mCreate;
@BindView(R.id.indicator_line)
View indicatorLine;
@BindView(R.id.tv_dot_notification)
public View tvDotIng;
@BindView(R.id.tv_dot_announcement)
public View tvDotEnd;
@Override
protected int getLayoutId() {
return R.layout.activity_ask_manage;
}
@Override
protected void init(Bundle savedInstanceState) {
initData();
initIndicatorLine();
setListener();
}
private void initData() {
//title设置不用管
setToolBarTitle("询价管理");
List<Fragment> pageLists = new ArrayList<>();
//这里的Fragment替换为你需要的Fragment就好
AskingFragment askingFragment = new AskingFragment();
AskendFragment askendFragment = new AskendFragment();
pageLists.add(askingFragment);
pageLists.add(askendFragment);
MsgVpAdapter adapter = new MsgVpAdapter(this.getSupportFragmentManager(), pageLists);
mPager.setOffscreenPageLimit(2);
mPager.setAdapter(adapter);
//红点设置,一般在接口进行动态设置的
tvDotIng.setVisibility(View.VISIBLE);
tvDotEnd.setVisibility(View.VISIBLE);
mCreate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(AskPriceManageActivity.this,InquiryCreateActivity.class);
}
});
}
//初始化设置蓝色横线为前半边
private void initIndicatorLine() {
int width = DeviceUtils.deviceWidth(this) / 2;
ViewGroup.LayoutParams layoutParams = indicatorLine.getLayoutParams();
layoutParams.width = width;
indicatorLine.setLayoutParams(layoutParams);
}
//动态监听ViewPager的滑动,然后设置底部蓝色的横线,因为二等分所以使用的是屏幕宽度的一半
private void setListener() {
mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
ViewCompat.setTranslationX(indicatorLine, DeviceUtils.deviceWidth(AskPriceManageActivity.this) * position / 2);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
@OnClick({R.id.rl_notification, R.id.rl_announcement})
public void clickEvent(View view) {
switch (view.getId()) {
case R.id.rl_notification:
mPager.setCurrentItem(0);
ViewCompat.setTranslationX(indicatorLine, 0);
break;
case R.id.rl_announcement:
mPager.setCurrentItem(1);
ViewCompat.setTranslationX(indicatorLine, DeviceUtils.deviceWidth(this) / 2);
break;
default:
}
}
/**
* 获取设备宽度(px)
* @param context context
* @return int
*/
public static int deviceWidth(Context context) {
return context.getResources().getDisplayMetrics().widthPixels;
}
}
- activity_ask_manage
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_height="match_parent">
<include layout="@layout/toolbar_layout"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/d40"
android:background="@color/white"
android:orientation="horizontal">
<RelativeLayout
android:id="@+id/rl_notification"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<TextView
android:id="@+id/tv_msg_tab_notification"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="询价中"
android:textColor="@color/black1"
android:textSize="@dimen/s14"/>
<TextView
android:id="@+id/tv_dot_notification"
android:layout_width="@dimen/d8"
android:layout_height="@dimen/d8"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/d4"
android:layout_toRightOf="@+id/tv_msg_tab_notification"
android:background="@drawable/shape_msg_red_dot"
android:visibility="gone"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_announcement"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<TextView
android:id="@+id/tv_msg_tab_announcement"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="已结束"
android:textColor="@color/black1"
android:textSize="@dimen/s14"/>
<TextView
android:id="@+id/tv_dot_announcement"
android:layout_width="@dimen/d8"
android:layout_height="@dimen/d8"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/d4"
android:layout_toRightOf="@+id/tv_msg_tab_announcement"
android:background="@drawable/shape_msg_red_dot"
android:visibility="gone"/>
</RelativeLayout>
</LinearLayout>
<View
android:id="@+id/indicator_line"
android:layout_width="match_parent"
android:layout_height="@dimen/d2"
android:background="@color/blue1"/>
<View
android:layout_width="match_parent"
android:layout_height="@dimen/d05"
android:background="@color/gray4"/>
<android.support.v4.view.ViewPager
android:id="@+id/vp_state"
android:layout_marginTop="@dimen/d1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@color/white"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
<TextView
android:id="@+id/tv_create"
android:layout_width="match_parent"
android:layout_height="@dimen/d49"
android:gravity="center"
android:background="@color/blue1"
style="@style/s16_white"
android:text="新建询价"
/>
</LinearLayout>
常见场景
如何设置TabLayout标题居中显示?
Hint:默认效果为等比横线显示效果
app:tabGravity="center"
app:tabIndicatorFullWidth="false"
app:tabMode="fixed"