Last active
August 22, 2016 10:12
-
-
Save SebastianEngel/9099e004e8b2c3b4c364 to your computer and use it in GitHub Desktop.
Implementation of fixed tabs - Stackoverflow question. Note that these classes must be placed into a package "android.support.v4.view" as ViewPager.DecorView is not public.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent"> | |
<com.example.app.ui.NonSwipeableViewPager | |
android:id="@+id/view_pager" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent"> | |
<android.support.v4.view.PagerTwoTabsStrip | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:layout_gravity="top" | |
android:orientation="horizontal" | |
style="@style/LocationsTabViewPagerIndicator" /> | |
</com.example.app.ui.NonSwipeableViewPager> | |
</FrameLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Subclass of {@link PagerTwoTitlesStrip} and so implementation of a {@link android.widget.LinearLayout} | |
* used as a {@link android.support.v4.view.ViewPager} indicator. This view holds two {@link android.widget.TextView}s, each being | |
* the title of the two pages. The title of the 'current' tab is underlined by a tab indicator. | |
* | |
* <p>Inspired by Google's {@link PagerTabStrip}</p> | |
*/ | |
public class PagerTwoTabsStrip extends PagerTwoTitlesStrip { | |
@SuppressWarnings("unused") | |
private static final String LOG_TAG = PagerTwoTabsStrip.class.getName(); | |
private static final int INDICATOR_HEIGHT = 4; // dp | |
private final Paint tabPaint = new Paint(); | |
private int indicatorHeight; | |
public PagerTwoTabsStrip(Context context) { | |
this(context, null); | |
} | |
public PagerTwoTabsStrip(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
// Note: this follows the rules for Resources#getDimensionPixelOffset/Size: | |
// sizes round up, offsets round down. | |
final float density = context.getResources().getDisplayMetrics().density; | |
indicatorHeight = (int) (INDICATOR_HEIGHT * density + 0.5f); | |
tabPaint.setColor(getResources().getColor(R.color.white)); | |
setWillNotDraw(false); | |
} | |
@Override | |
protected void onDraw(Canvas canvas) { | |
super.onDraw(canvas); | |
final int bottom = getHeight(); | |
final int left = activeTabTextView.getLeft(); | |
final int right = activeTabTextView.getRight(); | |
final int top = bottom - indicatorHeight; | |
canvas.drawRect(left, top, right, bottom, tabPaint); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Implementation of a {@link android.widget.LinearLayout} used as a {@link android.support.v4.view.ViewPager} indicator. | |
* This view holds two {@link android.widget.TextView}s, each being the title of the two pages. | |
* | |
* <p>Inspired by Google's {@link PagerTitleStrip}</p> | |
*/ | |
public class PagerTwoTitlesStrip extends LinearLayout implements ViewPager.Decor { | |
@SuppressWarnings("unused") | |
private static final String LOG_TAG = PagerTwoTitlesStrip.class.getName(); | |
private static final int[] ATTRS = new int[] { | |
android.R.attr.textAppearance, | |
android.R.attr.textSize, | |
android.R.attr.textColor, | |
android.R.attr.gravity | |
}; | |
/** | |
* The currently active (selected) tab's TextView. | |
*/ | |
TextView activeTabTextView; | |
/** | |
* TextView holding the text of the first tab. | |
*/ | |
private TextView tab1TextView; | |
/** | |
* TextView holding the text of the second tab. | |
*/ | |
private TextView tab2TextView; | |
private ViewPager viewPager; | |
public PagerTwoTitlesStrip(Context context) { | |
super(context); | |
} | |
public PagerTwoTitlesStrip(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
LayoutParams linearLayoutParams = new LayoutParams( | |
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1); | |
// Setup tab 1 | |
tab1TextView = new TextView(context); | |
tab1TextView.setText(R.string.view_tab_locations_mapview); | |
tab1TextView.setSingleLine(); | |
tab1TextView.setGravity(Gravity.CENTER); | |
tab1TextView.setPadding(0, 18, 0, 19); | |
tab1TextView.setOnTouchListener(new TabOnTouchListener(tab1TextView, 0)); | |
// Setup tab 2 | |
tab2TextView = new TextView(context); | |
tab2TextView.setText(R.string.view_tab_locations_listview); | |
tab2TextView.setSingleLine(); | |
tab2TextView.setGravity(Gravity.CENTER); | |
tab2TextView.setPadding(0, 18, 0, 19); | |
tab2TextView.setOnTouchListener(new TabOnTouchListener(tab2TextView, 1)); | |
// Style the text | |
final TypedArray attributes = context.obtainStyledAttributes(attrs, ATTRS); | |
final int textAppearance = attributes.getResourceId(0, 0); | |
if (textAppearance != 0) { | |
tab1TextView.setTextAppearance(context, textAppearance); | |
tab2TextView.setTextAppearance(context, textAppearance); | |
} | |
final int textSize = attributes.getDimensionPixelSize(1, 0); | |
if (textSize != 0) { | |
tab1TextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); | |
tab2TextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); | |
} | |
if (attributes.hasValue(2)) { | |
final int textColor = attributes.getColor(2, 0); | |
tab1TextView.setTextColor(textColor); | |
tab2TextView.setTextColor(textColor); | |
} | |
attributes.recycle(); | |
setActiveTab(tab1TextView); | |
addView(tab1TextView, linearLayoutParams); | |
addView(tab2TextView, linearLayoutParams); | |
} | |
private class TabOnTouchListener implements OnTouchListener { | |
private int itemId; | |
private TabOnTouchListener(TextView textView, int itemId) { | |
this.itemId = itemId; | |
} | |
@Override | |
public boolean onTouch(View view, MotionEvent event) { | |
TextView textView = ((TextView) view); | |
setActiveTab(textView); | |
viewPager.setCurrentItem(itemId); | |
return true; | |
} | |
} | |
private void setActiveTab(TextView activeTabTextView) { | |
tab1TextView.setTextColor(getResources().getColor(R.color.bsr_orange)); | |
tab2TextView.setTextColor(getResources().getColor(R.color.bsr_orange)); | |
this.activeTabTextView = activeTabTextView; | |
activeTabTextView.setTextColor(getResources().getColor(R.color.white)); | |
invalidate(); | |
} | |
@Override | |
protected void onAttachedToWindow() { | |
super.onAttachedToWindow(); | |
final ViewParent parent = getParent(); | |
if (!(parent instanceof ViewPager)) { | |
throw new IllegalStateException( | |
"PagerTwoTitlesStrip must be a direct child of a ViewPager."); | |
} | |
viewPager = (ViewPager) parent; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
... | |
<style name="LocationsTabViewPagerIndicator"> | |
<item name="android:background">@color/anthracite</item> | |
<item name="android:textColor">@color/white</item> | |
</style> | |
... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment