Advertisement
Guest User

Untitled

a guest
Nov 21st, 2014
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.95 KB | None | 0 0
  1. /*
  2. * Copyright (C) 2013 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16.  
  17. package com.example.android.common.view;
  18.  
  19. import android.content.Context;
  20. import android.content.res.Resources;
  21. import android.graphics.Typeface;
  22. import android.os.Build;
  23. import android.support.v4.view.PagerAdapter;
  24. import android.support.v4.view.ViewPager;
  25. import android.util.AttributeSet;
  26. import android.util.DisplayMetrics;
  27. import android.util.TypedValue;
  28. import android.view.Gravity;
  29. import android.view.LayoutInflater;
  30. import android.view.View;
  31. import android.view.ViewGroup;
  32. import android.widget.HorizontalScrollView;
  33. import android.widget.TextView;
  34.  
  35. /**
  36. * To be used with ViewPager to provide a tab indicator component which give constant feedback as to
  37. * the user's scroll progress.
  38. * <p>
  39. * To use the component, simply add it to your view hierarchy. Then in your
  40. * {@link android.app.Activity} or {@link android.support.v4.app.Fragment} call
  41. * {@link #setViewPager(ViewPager)} providing it the ViewPager this layout is being used for.
  42. * <p>
  43. * The colors can be customized in two ways. The first and simplest is to provide an array of colors
  44. * via {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)}. The
  45. * alternative is via the {@link TabColorizer} interface which provides you complete control over
  46. * which color is used for any individual position.
  47. * <p>
  48. * The views used as tabs can be customized by calling {@link #setCustomTabView(int, int)},
  49. * providing the layout ID of your custom layout.
  50. */
  51. public class SlidingTabLayout extends HorizontalScrollView {
  52.  
  53.  
  54.  
  55. /**
  56. * Allows complete control over the colors drawn in the tab layout. Set with
  57. * {@link #setCustomTabColorizer(TabColorizer)}.
  58. *
  59. *
  60. */
  61.  
  62.  
  63. public interface TabColorizer {
  64.  
  65. /**
  66. * @return return the color of the indicator used when {@code position} is selected.
  67. */
  68. int getIndicatorColor(int position);
  69.  
  70. /**
  71. * @return return the color of the divider drawn to the right of {@code position}.
  72. */
  73. int getDividerColor(int position);
  74.  
  75. }
  76.  
  77. private static final int TITLE_OFFSET_DIPS = 24;
  78. private static final int TAB_VIEW_PADDING_DIPS = 16;
  79. private static final int TAB_VIEW_TEXT_SIZE_SP = 12;
  80.  
  81.  
  82. private static final DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
  83.  
  84. private int mTitleOffset;
  85.  
  86. private int mTabViewLayoutId;
  87. private int mTabViewTextViewId;
  88.  
  89. private ViewPager mViewPager;
  90. private ViewPager.OnPageChangeListener mViewPagerPageChangeListener;
  91.  
  92. private final SlidingTabStrip mTabStrip;
  93.  
  94. public SlidingTabLayout(Context context) {
  95. this(context, null);
  96. }
  97.  
  98. public SlidingTabLayout(Context context, AttributeSet attrs) {
  99. this(context, attrs, 0);
  100. }
  101.  
  102. public SlidingTabLayout(Context context, AttributeSet attrs, int defStyle) {
  103. super(context, attrs, defStyle);
  104.  
  105. // Disable the Scroll Bar
  106. setHorizontalScrollBarEnabled(false);
  107. // Make sure that the Tab Strips fills this View
  108. setFillViewport(true);
  109.  
  110. mTitleOffset = (int) (TITLE_OFFSET_DIPS * getResources().getDisplayMetrics().density);
  111.  
  112. mTabStrip = new SlidingTabStrip(context);
  113. // screen dimenssion
  114. DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();;
  115.  
  116. addView(mTabStrip, 1, LayoutParams.WRAP_CONTENT);
  117. }
  118.  
  119. /**
  120. * Set the custom {@link TabColorizer} to be used.
  121. *
  122. * If you only require simple custmisation then you can use
  123. * {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)} to achieve
  124. * similar effects.
  125. */
  126. public void setCustomTabColorizer(TabColorizer tabColorizer) {
  127. mTabStrip.setCustomTabColorizer(tabColorizer);
  128. }
  129.  
  130. /**
  131. * Sets the colors to be used for indicating the selected tab. These colors are treated as a
  132. * circular array. Providing one color will mean that all tabs are indicated with the same color.
  133. */
  134. public void setSelectedIndicatorColors(int... colors) {
  135. mTabStrip.setSelectedIndicatorColors(colors);
  136. }
  137.  
  138. /**
  139. * Sets the colors to be used for tab dividers. These colors are treated as a circular array.
  140. * Providing one color will mean that all tabs are indicated with the same color.
  141. */
  142. public void setDividerColors(int... colors) {
  143. mTabStrip.setDividerColors(colors);
  144. }
  145.  
  146. /**
  147. * Set the {@link ViewPager.OnPageChangeListener}. When using {@link SlidingTabLayout} you are
  148. * required to set any {@link ViewPager.OnPageChangeListener} through this method. This is so
  149. * that the layout can update it's scroll position correctly.
  150. *
  151. * @see ViewPager#setOnPageChangeListener(ViewPager.OnPageChangeListener)
  152. */
  153. public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
  154. mViewPagerPageChangeListener = listener;
  155. }
  156.  
  157. /**
  158. * Set the custom layout to be inflated for the tab views.
  159. *
  160. * @param layoutResId Layout id to be inflated
  161. * @param textViewId id of the {@link TextView} in the inflated view
  162. */
  163. public void setCustomTabView(int layoutResId, int textViewId) {
  164. mTabViewLayoutId = layoutResId;
  165. mTabViewTextViewId = textViewId;
  166. }
  167.  
  168. /**
  169. * Sets the associated view pager. Note that the assumption here is that the pager content
  170. * (number of tabs and tab titles) does not change after this call has been made.
  171. */
  172. public void setViewPager(ViewPager viewPager) {
  173. mTabStrip.removeAllViews();
  174.  
  175. mViewPager = viewPager;
  176. if (viewPager != null) {
  177. viewPager.setOnPageChangeListener(new InternalViewPagerListener());
  178. populateTabStrip();
  179. }
  180. }
  181.  
  182. /**
  183. * Create a default view to be used for tabs. This is called if a custom tab view is not set via
  184. * {@link #setCustomTabView(int, int)}.
  185. */
  186. protected TextView createDefaultTabView(Context context) {
  187. TextView textView = new TextView(context);
  188. textView.setGravity(Gravity.CENTER);
  189. textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);
  190. textView.setTypeface(Typeface.DEFAULT_BOLD);
  191.  
  192. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
  193. // If we're running on Honeycomb or newer, then we can use the Theme's
  194. // selectableItemBackground to ensure that the View has a pressed state
  195. TypedValue outValue = new TypedValue();
  196. getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
  197. outValue, true);
  198. textView.setBackgroundResource(outValue.resourceId);
  199. }
  200.  
  201. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
  202. // If we're running on ICS or newer, enable all-caps to match the Action Bar tab style
  203. textView.setAllCaps(true);
  204. }
  205.  
  206. int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
  207. textView.setPadding(padding, padding, padding, padding);
  208.  
  209. return textView;
  210. }
  211.  
  212. private void populateTabStrip() {
  213. final PagerAdapter adapter = mViewPager.getAdapter();
  214. final View.OnClickListener tabClickListener = new TabClickListener();
  215.  
  216. for (int i = 0; i < adapter.getCount(); i++) {
  217. View tabView = null;
  218. TextView tabTitleView = null;
  219.  
  220. if (mTabViewLayoutId != 0) {
  221. // If there is a custom tab view layout id set, try and inflate it
  222. tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip,
  223. false);
  224. tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId);
  225. }
  226.  
  227. if (tabView == null) {
  228. tabView = createDefaultTabView(getContext());
  229. }
  230.  
  231. if (tabTitleView == null && TextView.class.isInstance(tabView)) {
  232. tabTitleView = (TextView) tabView;
  233. }
  234.  
  235. tabTitleView.setText(adapter.getPageTitle(i));
  236. tabView.setOnClickListener(tabClickListener);
  237. tabView.setLayoutParams(new ViewGroup.LayoutParams(metrics.widthPixels/3, ViewGroup.LayoutParams.WRAP_CONTENT));
  238. mTabStrip.addView(tabView);
  239. }
  240. }
  241.  
  242. @Override
  243. protected void onAttachedToWindow() {
  244. super.onAttachedToWindow();
  245.  
  246. if (mViewPager != null) {
  247. scrollToTab(mViewPager.getCurrentItem(), 0);
  248. }
  249. }
  250.  
  251. private void scrollToTab(int tabIndex, int positionOffset) {
  252. final int tabStripChildCount = mTabStrip.getChildCount();
  253. if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) {
  254. return;
  255. }
  256.  
  257. View selectedChild = mTabStrip.getChildAt(tabIndex);
  258. if (selectedChild != null) {
  259. int targetScrollX = selectedChild.getLeft() + positionOffset;
  260.  
  261. if (tabIndex > 0 || positionOffset > 0) {
  262. // If we're not at the first child and are mid-scroll, make sure we obey the offset
  263. targetScrollX -= mTitleOffset;
  264. }
  265.  
  266. scrollTo(targetScrollX, 0);
  267. }
  268. }
  269.  
  270. private class InternalViewPagerListener implements ViewPager.OnPageChangeListener {
  271. private int mScrollState;
  272.  
  273. @Override
  274. public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
  275. int tabStripChildCount = mTabStrip.getChildCount();
  276. if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
  277. return;
  278. }
  279.  
  280. mTabStrip.onViewPagerPageChanged(position, positionOffset);
  281.  
  282. View selectedTitle = mTabStrip.getChildAt(position);
  283. int extraOffset = (selectedTitle != null)
  284. ? (int) (positionOffset * selectedTitle.getWidth())
  285. : 0;
  286. scrollToTab(position, extraOffset);
  287.  
  288. if (mViewPagerPageChangeListener != null) {
  289. mViewPagerPageChangeListener.onPageScrolled(position, positionOffset,
  290. positionOffsetPixels);
  291. }
  292. }
  293.  
  294. @Override
  295. public void onPageScrollStateChanged(int state) {
  296. mScrollState = state;
  297.  
  298. if (mViewPagerPageChangeListener != null) {
  299. mViewPagerPageChangeListener.onPageScrollStateChanged(state);
  300. }
  301. }
  302.  
  303. @Override
  304. public void onPageSelected(int position) {
  305. if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
  306. mTabStrip.onViewPagerPageChanged(position, 0f);
  307. scrollToTab(position, 0);
  308. }
  309.  
  310. if (mViewPagerPageChangeListener != null) {
  311. mViewPagerPageChangeListener.onPageSelected(position);
  312. }
  313. }
  314.  
  315. }
  316.  
  317. private class TabClickListener implements View.OnClickListener {
  318. @Override
  319. public void onClick(View v) {
  320. for (int i = 0; i < mTabStrip.getChildCount(); i++) {
  321. if (v == mTabStrip.getChildAt(i)) {
  322. mViewPager.setCurrentItem(i);
  323. return;
  324. }
  325. }
  326. }
  327. }
  328.  
  329. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement