1、效果图
第二个菜单TAB1,TAB2,TAB3是参照网上的例子,第一个菜单是在它的基础之上改变而来。
2、菜单
这里的菜单是通过两种方式来实现,一种是通过布局文件,一种是通过自定义组件LinearLayout。自定义只需要传入菜单的名字即可,切换时需要监听事件。下面是一个viewpager+fragment实现,在滑动时改变tab的选中项。
自定义tab底部线是采用TranslateAnimation动画来实现滚动,布局文件采用viewpager的方法onPageScrolled和onPageScrollStateChanged来实现。
2.1 自定义LinearLayout
<span style="font-size:14px;">package com.example.actionbar;
import java.util.List;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.widget.LinearLayout;
import android.widget.TextView;
public class TabView extends LinearLayout {
private int screenWidth;
private String[] tabNames;
private int fontSize;
private TextView[] mTextViews;
private int lineHight;
private View sliderLine;
private int tabWidth;
private int selectedPage;
public TabView(Context context) {
super(context);
init(context);
}
public TabView(Context context, String[] tabNames, DisplayMetrics displayMetrics, int fontSize) {
super(context);
this.tabNames = tabNames;
screenWidth = displayMetrics.widthPixels;
this.fontSize = fontSize;
init(context);
}
public TabView(Context context, List<String> names, DisplayMetrics displayMetrics, int fontSize) {
super(context);
if (names != null) {
tabNames = new String[names.size()];
for (int i = 0; i < tabNames.length; i++) {
this.tabNames[i] = names.get(i);
}
}
screenWidth = displayMetrics.widthPixels;
this.fontSize = fontSize;
init(context);
}
public TabView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
@SuppressLint("NewApi")
public TabView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context) {
if (tabNames==null || tabNames.length == 0) {
return;
}
lineHight = (int) getResources().getDimension(R.dimen.cursor_height);
tabWidth = screenWidth / tabNames.length;
mTextViews = new TextView[tabNames.length];
setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
new LayoutParams(screenWidth / tabNames.length,
LayoutParams.MATCH_PARENT));
LinearLayout linearLayout = new LinearLayout(context);
int height = (int) getResources().getDimension(R.dimen.tab_height);
linearLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,height));
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
for (int i = 0; i < tabNames.length; i++) {
TextView textView = new TextView(context);
textView.setText(tabNames[i] + "");
textView.setLayoutParams(layoutParams);
textView.setTextSize(fontSize);
textView.setTextColor(Color.BLACK);
textView.setGravity(Gravity.CENTER);
mTextViews[i] = textView;
final int pos = i;
textView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(selectedPage!=pos){
isHidden(pos);
}
if (tabViewListener != null) {
tabViewListener.currentPos(pos);
}
}
});
linearLayout.addView(textView);
}
addView(linearLayout);
if (tabNames.length>1) {
LinearLayout.LayoutParams lineLayoutParams = new LinearLayout.LayoutParams(tabWidth, lineHight);
TextView textView = new TextView(context);
textView.setBackgroundColor(Color.parseColor("#FA8653"));
textView.setLayoutParams(lineLayoutParams);
sliderLine=textView;
addView(textView);
}
isHidden(0);
}
private TabViewListener tabViewListener;
public void setTabViewListener(TabViewListener linListener) {
this.tabViewListener = linListener;
}
public TabViewListener getTabViewListener(){
return tabViewListener;
}
public interface TabViewListener {
public void currentPos(int pos);
}
/*
* 切换字体颜色
*/
public void isHidden(int pos) {
if (pos >= 0 || pos < tabNames.length) {
tabScroll(pos);
mTextViews[selectedPage].setTextColor(Color.BLACK);
mTextViews[pos].setTextColor(Color.parseColor("#FA8653"));
selectedPage=pos;
}
}
/*
* 滚动动画
*/
private void tabScroll(int index){
if (selectedPage==index) {
return;
}
sliderLine.setTranslationX(0);
TranslateAnimation animation = new TranslateAnimation(selectedPage
* tabWidth, index * tabWidth, 0, 0);
animation.setInterpolator(new AccelerateInterpolator());
animation.setDuration(100);
animation.setFillEnabled(true);
animation.setFillAfter(true);
sliderLine.startAnimation(animation);
animation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
sliderLine.clearAnimation();
sliderLine.setTranslationX(selectedPage * tabWidth);
}
});
}
}
</span>
2.2 使用布局文件
<span style="font-size:14px;">package com.example.actionbar;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.widget.LinearLayout;
import android.widget.TextView;
public class TabFragmentIndicator extends LinearLayout implements
ViewPager.OnPageChangeListener, OnClickListener {
OnTabClickListener onTabClickListener;
Context mContext;
ViewPager mViewPager;
View container;
private View slider;
private int tabNum;
private int selectedPage = 0;
private int preSelectedPage = 0;
private int scrollState;
private final int SCROLL_STATE_PRESS = 1;
private final int SCROLL_STATE_UP = 2;
private float unitWidth;
private float currentPositionPix;
private boolean isClick = false;
SectionsPagerAdapter mSectionsPagerAdapter;
private ArrayList<Class<?>> fragmentList = new ArrayList<Class<?>>();
public TabFragmentIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
}
public void setViewPager(ViewPager viewPager) {
viewPager.setOffscreenPageLimit(3);
mViewPager = viewPager;
mViewPager.setOnPageChangeListener(this);
mSectionsPagerAdapter = new SectionsPagerAdapter(
((FragmentActivity) mContext).getSupportFragmentManager());
mViewPager.setAdapter(mSectionsPagerAdapter);
}
/**
* 添加fragment
*
* @param index
* @param claz
*/
public void addFragment(int index, Class<?> claz) {
fragmentList.add(index, claz);
if (mSectionsPagerAdapter != null)
mSectionsPagerAdapter.notifyDataSetChanged();
}
/**
* 设置Tab布局
*
* @param layoutId
*/
public void setTabContainerView(int layoutId) {
container = LayoutInflater.from(mContext).inflate(layoutId, null);
this.addView(container, 0);
int height = (int) getResources().getDimension(R.dimen.tab_height);
ViewGroup.LayoutParams params = container.getLayoutParams();
params.height = height;
container.setLayoutParams(params);
if (container instanceof ViewGroup) {
tabNum = ((ViewGroup) container).getChildCount();
for (int i = 0; i < tabNum; i++) {
((ViewGroup) container).getChildAt(i).setTag(i);
((ViewGroup) container).getChildAt(i).setOnClickListener(this);
}
}
}
/**
* 设置下划线
*
* @param layoutId
*/
public void setTabSliderView(int layoutId) {
slider = LayoutInflater.from(mContext).inflate(layoutId, null);
this.addView(slider, 1);
setCursorWidth();
}
public View getIndicatorView() {
return container;
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int index) {
return Fragment.instantiate(mContext, fragmentList.get(index)
.getName(), null);
}
@Override
public int getCount() {
return fragmentList.size();
}
}
@Override
public void onPageSelected(int position) {
((TextView) ((ViewGroup) container).getChildAt(selectedPage))
.setTextColor(this.getResources().getColor(
android.R.color.black));
((TextView) ((ViewGroup) container).getChildAt(position))
.setTextColor(this.getResources().getColor(R.color.orange));
selectedPage = position;
}
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
//不是点击tab选项
if (!isClick && positionOffsetPixels != 0) {
if (scrollState == SCROLL_STATE_PRESS) {// 手指按下的状态
if (selectedPage == position) {// 表示往左拉,相应的tab往右走
slider.setTranslationX(currentPositionPix
+ positionOffsetPixels / tabNum);
} else {// 表示往右拉
slider.setTranslationX(currentPositionPix
- (unitWidth - positionOffsetPixels / tabNum));
}
} else if (scrollState == SCROLL_STATE_UP) {// 手指抬起的状态
System.out.println("preSelectedPage---" + preSelectedPage +" position---" + position+" offset "+positionOffsetPixels);
if (preSelectedPage == position) {// 往左拉
slider.setTranslationX(currentPositionPix + positionOffsetPixels / tabNum);
} else {// 表示往右拉
slider.setTranslationX(currentPositionPix - (unitWidth - positionOffsetPixels / tabNum));
}
}
}
}
// 其中state这个参数有三种状态(0,1,2)。state
// ==1的时辰默示正在滑动,state==2的时辰默示滑动完毕了,state==0的时辰默示什么都没做。
@Override
public void onPageScrollStateChanged(int state) {
System.out.println("onPageScrollStateChanged------state" + state);
if (!isClick) {
currentPositionPix = selectedPage * unitWidth;
scrollState = state;
preSelectedPage = selectedPage;
}
}
/**
*
* 点击tab页时移动下划线
*/
@Override
public void onClick(View v) {
final int index = (Integer) v.getTag();
onTabClickListener.onTabClick(v);
if (selectedPage == index) {
return;
}
isClick = true;
slider.setTranslationX(0);
TranslateAnimation animation = new TranslateAnimation(selectedPage
* unitWidth, index * unitWidth, 0, 0);
animation.setInterpolator(new AccelerateInterpolator());
animation.setDuration(100);
animation.setFillEnabled(true);
animation.setFillAfter(true);
slider.startAnimation(animation);
animation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
mViewPager.setCurrentItem(index, true);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
slider.clearAnimation();
slider.setTranslationX(selectedPage * unitWidth);
isClick = false;
}
});
}
/** 设置cursor的宽度,并获取移动的单位长度float **/
private void setCursorWidth() {
int cursorWidth = getWindowWidth() / tabNum;
unitWidth = (float) getWindowWidth() / tabNum;
int cursorHeight = (int) getResources().getDimension(
R.dimen.cursor_height);
ViewGroup.LayoutParams params = slider.getLayoutParams();
params.height = cursorHeight;
params.width = cursorWidth;
slider.setLayoutParams(params);
}
/** 获取屏幕宽度 **/
private int getWindowWidth() {
DisplayMetrics dm = new DisplayMetrics();
((Activity) mContext).getWindowManager().getDefaultDisplay()
.getMetrics(dm);
return dm.widthPixels;
}
public void setOnTabClickListener(OnTabClickListener onTabClickListener) {
this.onTabClickListener = onTabClickListener;
}
public interface OnTabClickListener {
public void onTabClick(View v);
}
}
</span>
<span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal" >
<TextView
android:id="@+id/tab1_text"
android:layout_width="0dp"
android:layout_weight="1.0"
android:gravity="center"
android:layout_height="@dimen/tab_height"
android:textColor="@color/orange"
style="@style/Style.ActionBarTabTextStyle"
android:text="tab1" />
<TextView
android:id="@+id/tab2_text"
android:layout_width="0dp"
android:layout_height="@dimen/tab_height"
android:layout_weight="1.0"
android:gravity="center"
style="@style/Style.ActionBarTabTextStyle"
android:text="tab2" />
<TextView
android:id="@+id/tab3_text"
android:layout_width="0dp"
android:layout_height="@dimen/tab_height"
android:layout_weight="1.0"
android:gravity="center"
style="@style/Style.ActionBarTabTextStyle"
android:text="tab3" />
</LinearLayout></span>
3、测试调用
<span style="font-family: 'Comic Sans MS';"><span style="font-size:14px;">public class HomeActivity extends FragmentActivity implements
OnTabClickListener, OnCategorySelectedListener {
private ViewPager mViewPager;
private TabFragmentIndicator tabFragmentIndicator;
private View categoryTab;
private CategoryWindow categoryWindow;
private SettingMenuWindow menuWindow;
private LinearLayout ll_tab;
private TabView tabView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
menuWindow = new SettingMenuWindow(this);
mViewPager = (ViewPager) findViewById(R.id.viewPager);
ll_tab = (LinearLayout) findViewById(R.id.ll_tab);
tabFragmentIndicator = (TabFragmentIndicator) findViewById(R.id.tabFragmentIndicator);
tabFragmentIndicator.addFragment(0, CountingFragment.class);
tabFragmentIndicator.addFragment(1, CountingFragment.class);
tabFragmentIndicator.addFragment(2, CountingFragment.class);
tabFragmentIndicator
.setTabContainerView(R.layout.layout_home_tabindicator);
tabFragmentIndicator.setTabSliderView(R.layout.layout_home_tab_slider);
tabFragmentIndicator.setOnTabClickListener(this);
tabFragmentIndicator.setViewPager(mViewPager);
categoryWindow = new CategoryWindow(this, this);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
tabView = new TabView(this, new String[] { "菜单", "发现", "设置" },
dm, 20);
ll_tab.addView(tabView);
tabView.setTabViewListener(new TabViewListener() {
@Override
public void currentPos(int pos) {
tabView.isHidden(pos);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_more:
menuWindow.showAsDropDown(findViewById(R.id.anchorView), 1800, -25);
break;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onTabClick(View v) {
int pos = (Integer) v.getTag();
if (pos == 0) {
categoryWindow.showAsDropDown(tabFragmentIndicator, -20, 0);
}
tabView.getTabViewListener().currentPos(pos);
}
@Override
public void onCategorySelected(String name, String id) {
((TextView) categoryTab).setText(name);
categoryWindow.dismiss();
}
}</span></span>
源码下载