package com.mobidev.newsapp.materialtabhost; /** * Created by lawrence on 2/23/15. */ import java.util.LinkedList; import java.util.List; import android.annotation.SuppressLint; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Color; import android.util.AttributeSet; import android.view.View; import android.widget.HorizontalScrollView; import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.RelativeLayout; import com.mobidev.newsapp.R; /** * A Toolbar that contains multiple tabs * @author neokree * */ @SuppressLint("InflateParams") public class MaterialTabHost extends RelativeLayout implements View.OnClickListener { private int primaryColor; private int accentColor; private int textColor; private int iconColor; private List<MaterialTab> tabs; private boolean hasIcons; private boolean isTablet; private float density; private boolean scrollable; private HorizontalScrollView scrollView; private LinearLayout layout; private ImageButton left; private ImageButton right; private static int tabSelected; public MaterialTabHost(Context context) { this(context, null); } public MaterialTabHost(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MaterialTabHost(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); scrollView = new HorizontalScrollView(context); // scrollView.setOverScrollMode(HorizontalScrollView.OVER_SCROLL_NEVER); scrollView.setHorizontalScrollBarEnabled(false); layout = new LinearLayout(context); scrollView.addView(layout); // get attributes if(attrs != null) { TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MaterialTabHost, 0, 0); try { // custom attributes hasIcons = a.getBoolean(R.styleable.MaterialTabHost_hasIcons, false); primaryColor = a.getColor(R.styleable.MaterialTabHost_materialTabsPrimaryColor, Color.parseColor("#03a9f4")); accentColor = a.getColor(R.styleable.MaterialTabHost_accentColor,Color.parseColor("#fafafa")); iconColor = a.getColor(R.styleable.MaterialTabHost_iconColor,Color.WHITE); textColor = a.getColor(R.styleable.MaterialTabHost_textColor,Color.WHITE); } finally { a.recycle(); } } else { hasIcons = false; } this.isInEditMode(); scrollable = false; isTablet = this.getResources().getBoolean(R.bool.isTablet); density = this.getResources().getDisplayMetrics().density; tabSelected = 0; // initialize tabs list tabs = new LinkedList<MaterialTab>(); // set background color super.setBackgroundColor(primaryColor); } public void setPrimaryColor(int color) { this.primaryColor = color; this.setBackgroundColor(primaryColor); for(MaterialTab tab : tabs) { tab.setPrimaryColor(color); } } public void setAccentColor(int color) { this.accentColor = color; for(MaterialTab tab : tabs) { tab.setAccentColor(color); } } public void setTextColor(int color) { this.textColor = color; for(MaterialTab tab : tabs) { tab.setTextColor(color); } } public void setIconColor(int color) { this.iconColor = color; for(MaterialTab tab : tabs) { tab.setIconColor(color); } } public void addTab(MaterialTab tab) { // add properties to tab tab.setAccentColor(accentColor); tab.setPrimaryColor(primaryColor); tab.setTextColor(textColor); tab.setIconColor(iconColor); tab.setPosition(tabs.size()); // insert new tab in list tabs.add(tab); if(tabs.size() == 4 && !hasIcons) { // switch tabs to scrollable before its draw scrollable = true; } if(tabs.size() == 6 && hasIcons) { scrollable = true; } } public MaterialTab newTab() { return new MaterialTab(this.getContext(),hasIcons); } public void setSelectedNavigationItem(int position) { if(position < 0 || position > tabs.size()) { throw new RuntimeException("Index overflow"); } else { // tab at position will select, other will deselect for(int i = 0; i < tabs.size(); i++) { MaterialTab tab = tabs.get(i); if(i == position) { tab.activateTab(); } else { tabs.get(i).disableTab(); } } // move the tab if it is slidable if(scrollable) { scrollTo(position); } tabSelected = position; } } private void scrollTo(int position) { int totalWidth = 0;//(int) ( 60 * density); for (int i = 0; i < position; i++) { int width = tabs.get(i).getView().getWidth(); if(width == 0) { if(!isTablet) width = (int) (tabs.get(i).getTabMinWidth() + (24 * density)); else width = (int) (tabs.get(i).getTabMinWidth() + (48 * density)); } totalWidth += width; } scrollView.smoothScrollTo(totalWidth, 0); } @Override public void removeAllViews() { for(int i = 0; i<tabs.size();i++) { tabs.remove(i); } layout.removeAllViews(); super.removeAllViews(); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); if(this.getWidth() != 0 && tabs.size() != 0) notifyDataSetChanged(); } public void notifyDataSetChanged() { super.removeAllViews(); layout.removeAllViews(); if (!scrollable) { // not scrollable tabs int tabWidth = this.getWidth() / tabs.size(); // set params for resizing tabs width LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(tabWidth, HorizontalScrollView.LayoutParams.MATCH_PARENT); for (MaterialTab t : tabs) { layout.addView(t.getView(), params); } } else { //scrollable tabs if(!isTablet) { for (int i = 0; i < tabs.size(); i++) { LinearLayout.LayoutParams params; MaterialTab tab = tabs.get(i); int tabWidth = (int) (tab.getTabMinWidth() + (24 * density)); // 12dp + text/icon width + 12dp if (i == 0) { // first tab View view = new View(layout.getContext()); view.setMinimumWidth((int) (60 * density)); layout.addView(view); } params = new LinearLayout.LayoutParams(tabWidth, HorizontalScrollView.LayoutParams.MATCH_PARENT); layout.addView(tab.getView(), params); if (i == tabs.size() - 1) { // last tab View view = new View(layout.getContext()); view.setMinimumWidth((int) (60 * density)); layout.addView(view); } } } else { // is a tablet for (int i = 0; i < tabs.size(); i++) { LinearLayout.LayoutParams params; MaterialTab tab = tabs.get(i); int tabWidth = (int) (tab.getTabMinWidth() + (48 * density)); // 24dp + text/icon width + 24dp params = new LinearLayout.LayoutParams(tabWidth, HorizontalScrollView.LayoutParams.MATCH_PARENT); layout.addView(tab.getView(), params); } } } if (isTablet && scrollable) { // if device is a tablet and have scrollable tabs add right and left arrows Resources res = getResources(); left = new ImageButton(this.getContext()); left.setId(R.id.left); left.setImageDrawable(res.getDrawable(R.mipmap.left_arrow)); left.setBackgroundColor(Color.TRANSPARENT); left.setOnClickListener(this); // set 56 dp width and 48 dp height LayoutParams paramsLeft = new LayoutParams((int)( 56 * density),(int) (48 * density)); paramsLeft.addRule(RelativeLayout.ALIGN_PARENT_LEFT); paramsLeft.addRule(RelativeLayout.ALIGN_PARENT_TOP); paramsLeft.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); this.addView(left,paramsLeft); right = new ImageButton(this.getContext()); right.setId(R.id.right); right.setImageDrawable(res.getDrawable(R.mipmap.right_arrow)); right.setBackgroundColor(Color.TRANSPARENT); right.setOnClickListener(this); LayoutParams paramsRight = new LayoutParams((int)( 56 * density),(int) (48 * density)); paramsRight.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); paramsRight.addRule(RelativeLayout.ALIGN_PARENT_TOP); paramsRight.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); this.addView(right,paramsRight); LayoutParams paramsScroll = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); paramsScroll.addRule(RelativeLayout.LEFT_OF, R.id.right); paramsScroll.addRule(RelativeLayout.RIGHT_OF,R.id.left); this.addView(scrollView,paramsScroll); } else { // if is not a tablet add only scrollable content LayoutParams paramsScroll = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); this.addView(scrollView,paramsScroll); } this.setSelectedNavigationItem(tabSelected); } public MaterialTab getCurrentTab() { for(MaterialTab tab : tabs) { if (tab.isSelected()) return tab; } return null; } @Override public void onClick(View v) { // on tablet left/right button clicked int currentPosition = this.getCurrentTab().getPosition(); if (v.getId() == R.id.right && currentPosition < tabs.size() -1) { currentPosition++; // set next tab selected this.setSelectedNavigationItem(currentPosition); // change fragment tabs.get(currentPosition).getTabListener().onTabSelected(tabs.get(currentPosition)); return; } if(v.getId() == R.id.left && currentPosition > 0) { currentPosition--; // set previous tab selected this.setSelectedNavigationItem(currentPosition); // change fragment tabs.get(currentPosition).getTabListener().onTabSelected(tabs.get(currentPosition)); return; } } }