I have a very simple task (at least I thought so) - make a 5 non-scrollable static tabs with icons and fragments within
As I promised I made some demo project for you.
The most simple solution for you problem seemed LinearLayout and that is what I used and also the android's images.
First you need to create a file in values folder named attrs.xml. If you already have it then just add the stylable
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="SimpleTabIndicator">
<attr name="numberOfTabs" format="integer"/>
<attr name="indicatorColor" format="color"/>
</declare-styleable>
</resources>
Then create a class named SimpleTabIndicator
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
public class SimpleTabIndicator extends View {
private static final String TAG = SimpleTabIndicator.class.getSimpleName();
private float density;
private int measuredHeight, measuredWidth;
private int mNumberOfTabs;
private Paint mIndicatorPaint;
private int mIndicatorColor = 0xFFFDE992;
private int currentTab = 1;
public SimpleTabIndicator(Context context) {
super(context);
init(null, 0);
}
public SimpleTabIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs, 0);
}
public SimpleTabIndicator(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs, defStyleAttr);
}
private void init(AttributeSet attrs, int style) {
if (!isInEditMode() && Build.VERSION.SDK_INT >= 11) {
setLayerType(View.LAYER_TYPE_NONE, null);
}
Resources res = getResources();
density = res.getDisplayMetrics().density;
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.SimpleTabIndicator, style, 0);
mIndicatorColor = typedArray.getColor(R.styleable.SimpleTabIndicator_indicatorColor, mIndicatorColor);
mNumberOfTabs = typedArray.getInt(R.styleable.SimpleTabIndicator_numberOfTabs, 1);
typedArray.recycle();
mIndicatorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mIndicatorPaint.setStyle(Paint.Style.FILL);
mIndicatorPaint.setColor(mIndicatorColor);
}
public int getNumberOfTabs() {
return mNumberOfTabs;
}
public void setNumberOfTabs(int mNumberOfTabs) {
this.mNumberOfTabs = mNumberOfTabs;
invalidate();
}
public int getCurrentTab() {
return currentTab;
}
public void setCurrentTab(int currentTab) {
this.currentTab = currentTab;
invalidate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
measuredHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
measuredWidth = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
setMeasuredDimension(measuredWidth, measuredHeight);
}
@Override
protected void onDraw(Canvas canvas) {
if (measuredHeight <= 0 || measuredWidth <= 0 || mNumberOfTabs == 0) {
return; // Not much we can draw :(
}
int length = measuredWidth / mNumberOfTabs;
int startX = (currentTab - 1) * length;
canvas.drawRect(startX, 0, startX + length, measuredHeight, mIndicatorPaint);
}
}
Next up is the ZoomOutPageTransformer. This guy is "borrowed" from Google.
import android.support.v4.view.ViewPager;
import android.view.View;
public class ZoomOutPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.85f;
private static final float MIN_ALPHA = 0.5f;
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
int pageHeight = view.getHeight();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
}
else if (position <= 1) { // [-1,1]
// Modify the default slide transition to shrink the page as well
float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
float vertMargin = pageHeight * (1 - scaleFactor) / 2;
float horzMargin = pageWidth * (1 - scaleFactor) / 2;
if (position < 0) {
view.setTranslationX(horzMargin - vertMargin / 2);
}
else {
view.setTranslationX(-horzMargin + vertMargin / 2);
}
// Scale the page down (between MIN_SCALE and 1)
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
// Fade the page relative to its size.
view.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA));
}
else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
Next make a layout named dummy_fragment_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/fragmentNumber"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:gravity="center_horizontal"
android:text="1"
android:textSize="50sp"
android:textStyle="bold"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@id/fragmentNumber"
android:gravity="center_horizontal"
android:text="Fragment"
android:textSize="30sp"/>
</RelativeLayout>
Now the main activity activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#808080"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:background="#26292E"
android:orientation="horizontal">
<ImageView
android:id="@+id/tab1"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:adjustViewBounds="true"
android:onClick="onTabSelected"
android:padding="10dp"
android:src="@android:drawable/btn_radio"
android:tag="1"/>
<ImageView
android:id="@+id/tab2"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:adjustViewBounds="true"
android:onClick="onTabSelected"
android:padding="10dp"
android:src="@android:drawable/btn_star"
android:tag="2"/>
<ImageView
android:id="@+id/tab3"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:adjustViewBounds="true"
android:onClick="onTabSelected"
android:padding="10dp"
android:src="@android:drawable/btn_star"
android:tag="3"/>
<ImageView
android:id="@+id/tab4"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:adjustViewBounds="true"
android:onClick="onTabSelected"
android:padding="10dp"
android:src="@android:drawable/btn_star"
android:tag="4"/>
<ImageView
android:id="@+id/tab5"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:adjustViewBounds="true"
android:onClick="onTabSelected"
android:padding="10dp"
android:src="@android:drawable/btn_star"
android:tag="5"/>
</LinearLayout>
<test.kseneman.si.test.SimpleTabIndicator
android:id="@+id/tabIndicator"
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#26292E"
app:indicatorColor="#FFFDE992"
app:numberOfTabs="5"/>
<android.support.v4.view.ViewPager
android:id="@+id/pager"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
And finally the MainActivity
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
public class MainActivity extends ActionBarActivity {
private ViewPager mPager;
private DummyFragmentsAdapter mPagerAdapter;
private SimpleTabIndicator tabIndicator;
private ImageView selectedImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPagerAdapter = new DummyFragmentsAdapter(getSupportFragmentManager());
tabIndicator = (SimpleTabIndicator) findViewById(R.id.tabIndicator);
// Default state
selectedImageView = (ImageView) findViewById(R.id.tab1);
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(mPagerAdapter);
mPager.setPageTransformer(false, new ZoomOutPageTransformer());
}
public void onTabSelected(View v) {
// Sanity check
if (v == null || !(v instanceof ImageView) || v.getTag() == null) {
return;
}
int postion = Integer.valueOf((String) v.getTag());
Log.d("onTabSelected", "postion: " + postion);
if (postion == mPager.getCurrentItem() + 1) {
// The same selected, do nothing?
return;
}
// Change selected images
selectedImageView.setImageResource(android.R.drawable.btn_star);
selectedImageView = (ImageView) v;
selectedImageView.setImageResource(android.R.drawable.btn_radio);
mPager.setCurrentItem(postion - 1); // They start at 0
tabIndicator.setCurrentTab(postion);
}
private class DummyFragmentsAdapter extends FragmentStatePagerAdapter {
public DummyFragmentsAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
DummyFragment fragment = new DummyFragment();
Bundle b = new Bundle();
b.putInt(DummyFragment.EXTRA_FRAGMENT_NUMBER, position);
fragment.setArguments(b);
return fragment;
}
@Override
public int getCount() {
return 5;
}
}
}
A complete project zip is available here
Here is what it looks like
use the new Tool alternatine to actionbar (toolbar) https://developer.android.com/reference/android/widget/Toolbar.html