横向滑动导航条可点击滑动

横向滑动导航条示例 先看效果如下:可滑动,标题可点击 

  附下载地址  http://download.csdn.net/detail/qiushuiduren/9600760


利用 HorizontalScrollView 和 Fragment 实现以上横向导航栏滑动效果


MainActivity 类代码

public class MainActivity extends FragmentActivity {

 private PagerSlidingTabStrip pagerSlidingTabStrip;
 private ViewPager viewPager;
 private String[] TITLE_NAMES;
 private ArrayList<Fragment> mFragments = new ArrayList<Fragment>();
 private FragmentManager mFragmentManager;
 private MyFragmentPagerAdapter mPagerAdapter;
 private List<Integer> ImageIds;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  // 获取 Fragment 管理器
  mFragmentManager = getSupportFragmentManager();
  
  pagerSlidingTabStrip = (PagerSlidingTabStrip) findViewById(R.id.tabsView);
  viewPager = (ViewPager) findViewById(R.id.viewPager);
  initTabsValue();

  // 设置标题和 Fragment 布局
  TITLE_NAMES = new String[3];
  ImageIds = new ArrayList<Integer>();
  for (int i = 0; i < 3; i++) {
   TITLE_NAMES[i] = "标题" + i;
   MyFragment f = MyFragment.newInstance(i);
   mFragments.add(f);
   ImageIds.add(R.drawable.ic_launcher);
  }
  
  // 为 ViewPager 添加适配器,为 PagerSlidingTabStrip 配置滑动界面
  mPagerAdapter = new MyFragmentPagerAdapter(mFragmentManager);
  viewPager.setAdapter(mPagerAdapter);
  mPagerAdapter.notifyDataSetChanged();
  pagerSlidingTabStrip.setViewPager(viewPager);
  
  // 页面改变监听
  pagerSlidingTabStrip.setOnPageChangeListener(new OnPageChangeListener() {
   @Override
   public void onPageSelected(int arg0) {
    // 页面发生改变时,更新 Fragment 中数据
    ((MyFragment)mFragments.get(arg0)).onRefresh(); 
   }

   @Override
   public void onPageScrolled(int arg0, float arg1, int arg2) {
   }

   @Override
   public void onPageScrollStateChanged(int arg0) {
   }
  });
 }



 /**
  * mPagerSlidingTabStrip默认值配置
  *
  */
 private void initTabsValue() {
  int color_tab_text = getResources().getColor(R.color.tab_text);
  int color_tab_text_selected = getResources().getColor(R.color.tab_text_selected);
  // 底部游标颜色
  pagerSlidingTabStrip.setIndicatorColor(color_tab_text_selected);
  // tab的分割线颜色
  pagerSlidingTabStrip.setDividerColor(Color.TRANSPARENT);
  // tab背景
  pagerSlidingTabStrip.setBackgroundColor(Color.WHITE);
  // tab底线高度
  pagerSlidingTabStrip.setUnderlineHeight((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources()
    .getDisplayMetrics()));
  // 游标高度
  pagerSlidingTabStrip.setIndicatorHeight((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, getResources()
    .getDisplayMetrics()));
  // 选中的文字颜色
  pagerSlidingTabStrip.setSelectedTextColor(color_tab_text_selected);
  // 正常文字颜色
  pagerSlidingTabStrip.setTextColor(color_tab_text);
 }
 
 /**
  * 文字的 Fragment 适配器
  */
 class MyFragmentPagerAdapter extends FragmentPagerAdapter {
  public MyFragmentPagerAdapter(FragmentManager fm) {
   super(fm);
  }
  
  @Override
  public CharSequence getPageTitle(int position) {
   return TITLE_NAMES[position];
  }
  
  @Override
  public int getCount() {
   return mFragments.size();
  }
  
  @Override
  public Fragment getItem(int position) {
   return mFragments.get(position);
  }
 }

/**
 *
 * 官网上的 demo 的 Fragment 示例
 *
 */
public class MyFragment extends Fragment {
 
 private static final String ARG_POSITION = "position";

 private int position;

 public static MyFragment newInstance(int position) {
  MyFragment fragment = new MyFragment();
  Bundle bundle = new Bundle();
  bundle.putInt(ARG_POSITION, position);
  fragment.setArguments(bundle);
  return fragment;
 }
 
 
 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  View view = inflater.inflate(R.layout.fragment, null);
  position = getArguments().getInt(ARG_POSITION);
  
  TextView textView = (TextView) view.findViewById(R.id.tv_text);
  textView.setText("Fragment\n" + position);
  return view;
 }

 /**
  * 刷新方法,用于更新数据等
  */
 public void onRefresh() {
  Log.e("hi", "onStart" + position);
 }
}


/**
 * @Descriptioon 横向滑动条类,在布局中引用,继承 HorizontalScrollView
 *
 */
public class PagerSlidingTabStrip extends HorizontalScrollView {

 public interface IconTabProvider {
  public int getPageIconResId(int position);
 }

 // @formatter:off
 private static final int[] ATTRS = new int[] { android.R.attr.textSize, android.R.attr.textColor };
 // @formatter:on

 private LinearLayout.LayoutParams defaultTabLayoutParams;
 private LinearLayout.LayoutParams expandedTabLayoutParams;

 private final PageListener pageListener = new PageListener();
 public OnPageChangeListener delegatePageListener;

 private LinearLayout tabsContainer;
 private ViewPager pager;

 private int tabCount;

 private int currentPosition = 0;
 private int selectedPosition = 0;
 private float currentPositionOffset = 0f;

 private Paint rectPaint;
 private Paint dividerPaint;

 private int indicatorColor = 0xFF666666;
 private int underlineColor = 0x1A000000;
 private int dividerColor = 0x1A000000;

 private boolean shouldExpand = false;
 private boolean textAllCaps = true;

 private int scrollOffset = 52;
 private int indicatorHeight = 8;
 private int underlineHeight = 2;
 private int dividerPadding = 12;
 private int tabPadding = 24;
 private int dividerWidth = 1;

 private int tabTextSize = 13;
 private int tabTextColor = 0xFF666666;
 private int selectedTabTextColor = 0xFF666666;
 private Typeface tabTypeface = null;
 private int tabTypefaceStyle = Typeface.NORMAL;

 private int lastScrollX = 0;

 private int tabBackgroundResId = R.drawable.background_tab;

 private Locale locale;
 private int mLocaleX;
 private Context context;

 public PagerSlidingTabStrip(Context context) {
  this(context, null);
  this.context = context;
 }

 public PagerSlidingTabStrip(Context context, AttributeSet attrs) {
  this(context, attrs, 0);
  this.context = context;
 }

 public PagerSlidingTabStrip(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);
  this.context = context;

  setFillViewport(true);
  setWillNotDraw(false);

  tabsContainer = new LinearLayout(context);
  tabsContainer.setOrientation(LinearLayout.HORIZONTAL);
  tabsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
  addView(tabsContainer);

  DisplayMetrics dm = getResources().getDisplayMetrics();

  scrollOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, scrollOffset, dm);
  indicatorHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, indicatorHeight, dm);
  underlineHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, underlineHeight, dm);
  dividerPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerPadding, dm);
  tabPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, tabPadding, dm);
  dividerWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm);
  tabTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, tabTextSize, dm);

  // get system attrs (android:textSize and android:textColor)
  TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);

  tabTextSize = a.getDimensionPixelSize(0, tabTextSize);
  tabTextColor = a.getColor(1, tabTextColor);

  a.recycle();

  // get custom attrs
  a = context.obtainStyledAttributes(attrs, R.styleable.PagerSlidingTabStrip);

  indicatorColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsIndicatorColor, indicatorColor);
  underlineColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsUnderlineColor, underlineColor);
  dividerColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsDividerColor, dividerColor);
  indicatorHeight = a
    .getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsIndicatorHeight, indicatorHeight);
  underlineHeight = a
    .getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsUnderlineHeight, underlineHeight);
  dividerPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsDividerPadding, dividerPadding);
  tabPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsTabPaddingLeftRight, tabPadding);
  tabBackgroundResId = a.getResourceId(R.styleable.PagerSlidingTabStrip_pstsTabBackground, tabBackgroundResId);
  shouldExpand = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsShouldExpand, shouldExpand);
  scrollOffset = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsScrollOffset, scrollOffset);
  textAllCaps = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsTextAllCaps, textAllCaps);

  a.recycle();

  rectPaint = new Paint();
  rectPaint.setAntiAlias(true);
  rectPaint.setStyle(Style.FILL);

  dividerPaint = new Paint();
  dividerPaint.setAntiAlias(true);
  dividerPaint.setStrokeWidth(dividerWidth);

  defaultTabLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
  expandedTabLayoutParams = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f);

  if (locale == null) {
   locale = getResources().getConfiguration().locale;
  }
 }

 public void setViewPager(ViewPager pager) {
  this.pager = pager;

  if (pager.getAdapter() == null) {
   throw new IllegalStateException("ViewPager does not have adapter instance.");
  }
  pager.setOnPageChangeListener(pageListener);

  notifyDataSetChanged();
 }

 public void setOnPageChangeListener(OnPageChangeListener listener) {
  this.delegatePageListener = listener;
 }

 public void notifyDataSetChanged() {

  tabsContainer.removeAllViews();

  tabCount = pager.getAdapter().getCount();

  for (int i = 0; i < tabCount; i++) {

   // 判断是加载图片标题还是文字标题
   if (pager.getAdapter() instanceof IconTabProvider) {
    addIconTab(i, ((IconTabProvider) pager.getAdapter()).getPageIconResId(i));
   } else {
    addTextTab(i, pager.getAdapter().getPageTitle(i).toString());
   }
  }

  updateTabStyles();

  getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

   @Override
   public void onGlobalLayout() {
    getViewTreeObserver().removeGlobalOnLayoutListener(this);
    currentPosition = pager.getCurrentItem();
    scrollToChild(currentPosition, 0);
   }
  });

 }

 private void addTextTab(final int position, String title) {

  TextView tab = new TextView(getContext());
  tab.setText(title);
  tab.setGravity(Gravity.CENTER);
  tab.setSingleLine();

  tab.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {
    pager.setCurrentItem(position);
   }
  });
  addTab(position, tab, title.length());
 }

 private void addIconTab(final int position, int resId) {

  ImageButton tab = new ImageButton(getContext());
  tab.setImageResource(resId);
  // 给图片标题添加点击事件
  tab.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {
    pager.setCurrentItem(position);
   }
  });
  addTab(position, tab);

 }

 private void addTab(final int position, View tab) {
  tab.setFocusable(true);
  WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
  DisplayMetrics dm = new DisplayMetrics();
  wm.getDefaultDisplay().getMetrics(dm);
  int w = dm.widthPixels / tabCount; // 获取图片宽度
  if (tabCount >= 5) {
   w = dm.widthPixels / 5;
  }
  LinearLayout.LayoutParams ll_lp_tab_item = new LinearLayout.LayoutParams(w,
    LinearLayout.LayoutParams.MATCH_PARENT);
  tabsContainer.addView(tab, position, ll_lp_tab_item);

 }

 private void addTab(final int position, View tab, int length) {
  WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
  DisplayMetrics dm = new DisplayMetrics();
  wm.getDefaultDisplay().getMetrics(dm);
  int widthPixels = dm.widthPixels;
  int w = widthPixels / tabCount; // 获取图片宽度
  if (widthPixels > 0) {
   if (tabCount >= 5) {
    w = widthPixels / 5;
    if (length > 5) {
     w = w + (length - 4) * widthPixels / 30;
    }
   }
   LinearLayout.LayoutParams ll_lp_tab_item = new LinearLayout.LayoutParams(w,
     LinearLayout.LayoutParams.MATCH_PARENT);
   tabsContainer.addView(tab, position, ll_lp_tab_item);
  } else {
   tab.setPadding(tabPadding, 0, tabPadding, 0);
   tabsContainer.addView(tab, position, defaultTabLayoutParams);
  }
 }

 private void updateTabStyles() {

  for (int i = 0; i < tabCount; i++) {

   View v = tabsContainer.getChildAt(i);

   // v.setBackgroundResource(tabBackgroundResId);
   if (v instanceof TextView) {

    TextView tab = (TextView) v;
    tab.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabTextSize);
    tab.setTypeface(tabTypeface, tabTypefaceStyle);
    tab.setTextColor(tabTextColor);

    // setAllCaps() is only available from API 14, so the upper case
    // is made manually if we are on a
    // pre-ICS-build
    if (textAllCaps) {
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
      tab.setAllCaps(true);
     } else {
      tab.setText(tab.getText().toString().toUpperCase(locale));
     }
    }
    if (i == selectedPosition) {
     tab.setTextColor(selectedTabTextColor);
    }
   }
  }

 }

 private void scrollToChild(int position, int offset) {

  if (tabCount == 0) {
   return;
  }

  int newScrollX = tabsContainer.getChildAt(position).getLeft() + offset;

  if (position > 0 || offset > 0) {
   newScrollX -= scrollOffset;
  }

  if (newScrollX != lastScrollX) {
   lastScrollX = newScrollX;
   scrollTo(newScrollX, 0);
  }
  mLocaleX = newScrollX;
 }

 public int getLocaleX() {
  return mLocaleX;
 }

 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);

  if (isInEditMode() || tabCount == 0) {
   return;
  }

  final int height = getHeight();

  // draw underline
  rectPaint.setColor(underlineColor);
  canvas.drawRect(0, height - underlineHeight, tabsContainer.getWidth(), height, rectPaint);

  // draw indicator line
  rectPaint.setColor(indicatorColor);

  // default: line below current tab
  View currentTab = tabsContainer.getChildAt(currentPosition);
  if (currentTab == null) {
   return;
  }
  float lineLeft = currentTab.getLeft();
  float lineRight = currentTab.getRight();

  // if there is an offset, start interpolating left and right coordinates
  // between current and next tab
  if (currentPositionOffset > 0f && currentPosition < tabCount - 1) {

   View nextTab = tabsContainer.getChildAt(currentPosition + 1);
   final float nextTabLeft = nextTab.getLeft();
   final float nextTabRight = nextTab.getRight();

   lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset) * lineLeft);
   lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset) * lineRight);
  }

  canvas.drawRect(lineLeft, height - indicatorHeight, lineRight, height, rectPaint);

  // draw divider

  dividerPaint.setColor(dividerColor);
  for (int i = 0; i < tabCount - 1; i++) {
   View tab = tabsContainer.getChildAt(i);
   canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint);
  }
 }

 private class PageListener implements OnPageChangeListener {

  @Override
  public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
   currentPosition = position;
   currentPositionOffset = positionOffset;

   scrollToChild(position, (int) (positionOffset * tabsContainer.getChildAt(position).getWidth()));

   invalidate();

   if (delegatePageListener != null) {
    delegatePageListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
   }
  }

  @Override
  public void onPageScrollStateChanged(int state) {
   if (state == ViewPager.SCROLL_STATE_IDLE) {
    scrollToChild(pager.getCurrentItem(), 0);
   }

   if (delegatePageListener != null) {
    delegatePageListener.onPageScrollStateChanged(state);
   }
  }

  @Override
  public void onPageSelected(int position) {
   selectedPosition = position;
   updateTabStyles();
   if (delegatePageListener != null) {
    delegatePageListener.onPageSelected(position);
   }
  }
 }

 public void setIndicatorColor(int indicatorColor) {
  this.indicatorColor = indicatorColor;
  invalidate();
 }

 public void setIndicatorColorResource(int resId) {
  this.indicatorColor = getResources().getColor(resId);
  invalidate();
 }

 public int getIndicatorColor() {
  return this.indicatorColor;
 }

 public void setIndicatorHeight(int indicatorLineHeightPx) {
  this.indicatorHeight = indicatorLineHeightPx;
  invalidate();
 }

 public int getIndicatorHeight() {
  return indicatorHeight;
 }

 public void setUnderlineColor(int underlineColor) {
  this.underlineColor = underlineColor;
  invalidate();
 }

 public void setUnderlineColorResource(int resId) {
  this.underlineColor = getResources().getColor(resId);
  invalidate();
 }

 public int getUnderlineColor() {
  return underlineColor;
 }

 public void setDividerColor(int dividerColor) {
  this.dividerColor = dividerColor;
  invalidate();
 }

 public void setDividerColorResource(int resId) {
  this.dividerColor = getResources().getColor(resId);
  invalidate();
 }

 public int getDividerColor() {
  return dividerColor;
 }

 public void setUnderlineHeight(int underlineHeightPx) {
  this.underlineHeight = underlineHeightPx;
  invalidate();
 }

 public int getUnderlineHeight() {
  return underlineHeight;
 }

 public void setDividerPadding(int dividerPaddingPx) {
  this.dividerPadding = dividerPaddingPx;
  invalidate();
 }

 public int getDividerPadding() {
  return dividerPadding;
 }

 public void setScrollOffset(int scrollOffsetPx) {
  this.scrollOffset = scrollOffsetPx;
  invalidate();
 }

 public int getScrollOffset() {
  return scrollOffset;
 }

 public void setShouldExpand(boolean shouldExpand) {
  this.shouldExpand = shouldExpand;
  notifyDataSetChanged();
 }

 public boolean getShouldExpand() {
  return shouldExpand;
 }

 public boolean isTextAllCaps() {
  return textAllCaps;
 }

 public void setAllCaps(boolean textAllCaps) {
  this.textAllCaps = textAllCaps;
 }

 public void setTextSize(int textSizePx) {
  this.tabTextSize = textSizePx;
  updateTabStyles();
 }

 public int getTextSize() {
  return tabTextSize;
 }

 public void setTextColor(int textColor) {
  this.tabTextColor = textColor;
  updateTabStyles();
 }

 public void setTextColorResource(int resId) {
  this.tabTextColor = getResources().getColor(resId);
  updateTabStyles();
 }

 public int getTextColor() {
  return tabTextColor;
 }

 public void setSelectedTextColor(int textColor) {
  this.selectedTabTextColor = textColor;
  updateTabStyles();
 }

 public void setSelectedTextColorResource(int resId) {
  this.selectedTabTextColor = getResources().getColor(resId);
  updateTabStyles();
 }

 public int getSelectedTextColor() {
  return selectedTabTextColor;
 }

 public void setTypeface(Typeface typeface, int style) {
  this.tabTypeface = typeface;
  this.tabTypefaceStyle = style;
  updateTabStyles();
 }

 public void setTabBackground(int resId) {
  this.tabBackgroundResId = resId;
  updateTabStyles();
 }

 public int getTabBackground() {
  return tabBackgroundResId;
 }

 public void setTabPaddingLeftRight(int paddingPx) {
  this.tabPadding = paddingPx;
  updateTabStyles();
 }

 public int getTabPaddingLeftRight() {
  return tabPadding;
 }

 @Override
 public void onRestoreInstanceState(Parcelable state) {
  SavedState savedState = (SavedState) state;
  super.onRestoreInstanceState(savedState.getSuperState());
  currentPosition = savedState.currentPosition;
  requestLayout();
 }

 @Override
 public Parcelable onSaveInstanceState() {
  Parcelable superState = super.onSaveInstanceState();
  SavedState savedState = new SavedState(superState);
  savedState.currentPosition = currentPosition;
  return savedState;
 }

 static class SavedState extends BaseSavedState {
  int currentPosition;

  public SavedState(Parcelable superState) {
   super(superState);
  }

  private SavedState(Parcel in) {
   super(in);
   currentPosition = in.readInt();
  }

  @Override
  public void writeToParcel(Parcel dest, int flags) {
   super.writeToParcel(dest, flags);
   dest.writeInt(currentPosition);
  }

  public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
   @Override
   public SavedState createFromParcel(Parcel in) {
    return new SavedState(in);
   }

   @Override
   public SavedState[] newArray(int size) {
    return new SavedState[size];
   }
  };
 }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值