Tenho guias de instalação como ATUALIZAÇÃO 29/05/2015 nesta postagem. As guias têm largura total no meu celular Nexus 4, mas no tablet do nexus 7 ele fica no centro e não cobre a largura da tela inteira.
Captura de tela do Nexus 7
Tenho guias de instalação como ATUALIZAÇÃO 29/05/2015 nesta postagem. As guias têm largura total no meu celular Nexus 4, mas no tablet do nexus 7 ele fica no centro e não cobre a largura da tela inteira.
Captura de tela do Nexus 7
Respostas:
Uma resposta "mais simples" emprestada do Kaizie estaria apenas adicionando app:tabMaxWidth="0dp"
no seu TabLayout
xml:
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMaxWidth="0dp"
app:tabGravity="fill"
app:tabMode="fixed" />
Eu tive o mesmo problema e verifiquei o estilo TabLayout, e descobri que seu estilo padrão é o de Widget.Design.TabLayout
implementações diferentes (normal, paisagem e sw600dp).
O que precisamos é o de tablets (sw600dp), que possui a seguinte implementação:
<style name="Widget.Design.TabLayout" parent="Base.Widget.Design.TabLayout">
<item name="tabGravity">center</item>
<item name="tabMode">fixed</item>
</style>
Nesse estilo, usaremos " tabGravity " (cujos valores possíveis são "centro" ou "preenchimento") usando o valor "preenchimento".
Mas precisamos ir mais fundo e, em seguida, vemos que este se estende de Base.Widget.Design.TabLayout
qual implementação é:
<style name="Base.Widget.Design.TabLayout" parent="android:Widget">
<item name="tabMaxWidth">@dimen/tab_max_width</item>
<item name="tabIndicatorColor">?attr/colorAccent</item>
<item name="tabIndicatorHeight">2dp</item>
<item name="tabPaddingStart">12dp</item>
<item name="tabPaddingEnd">12dp</item>
<item name="tabBackground">?attr/selectableItemBackground</item>
<item name="tabTextAppearance">@style/TextAppearance.Design.Tab</item>
<item name="tabSelectedTextColor">?android:textColorPrimary</item>
</style>
Portanto, a partir deste estilo, precisaremos substituir " tabMaxWidth ". No meu caso, defino-o para 0dp
que ele não tenha limites.
E meu estilo ficou assim:
<style name="MyTabLayout" parent="Widget.Design.TabLayout">
<item name="tabGravity">fill</item>
<item name="tabMaxWidth">0dp</item>
</style>
E então a barra de guias preencherá a tela inteira de um lado para o outro.
Solução para rolagem: (TabLayout.MODE_SCROLLABLE), ou seja, sempre que você precisar de mais de 2 guias (guias dinâmicas)
Etapa 1: style.xml
<style name="tabCustomStyle" parent="Widget.Design.TabLayout">
<item name="tabGravity">fill</item>
<item name="tabMaxWidth">0dp</item>
<item name="tabIndicatorColor">#FFFEEFC4</item>
<item name="tabIndicatorHeight">2dp</item>
<item name="tabTextAppearance">@style/MyCustomTabTextAppearance</item>
<item name="tabSelectedTextColor">#FFFEEFC4</item>
</style>
<style name="MyCustomTabTextAppearance" parent="TextAppearance.Design.Tab">
<item name="android:textSize">@dimen/tab_text_size</item>
<item name="android:textAppearance">@style/TextAppearance.roboto_medium</item>
<item name="textAllCaps">true</item>
</style>
<style name="TextAppearance.roboto_medium" parent="android:TextAppearance">
<item name="android:fontFamily">sans-serif-medium</item>
</style>
Etapa 2: seu layout xml
<android.support.design.widget.TabLayout
android:id="@+id/sliding_tabs"
style="@style/tabCustomStyle"
android:layout_width="match_parent"
android:layout_height="@dimen/tab_strip_height"
android:background="@color/your_color"
app:tabMode="scrollable"
app:tabTextColor="@color/your_color" />
Etapa 3: em sua Atividade / Fragmento, sempre que houver guias.
/**
* To allow equal width for each tab, while (TabLayout.MODE_SCROLLABLE)
*/
private void allotEachTabWithEqualWidth() {
ViewGroup slidingTabStrip = (ViewGroup) mTabLayout.getChildAt(0);
for (int i = 0; i < mTabLayout.getTabCount(); i++) {
View tab = slidingTabStrip.getChildAt(i);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) tab.getLayoutParams();
layoutParams.weight = 1;
tab.setLayoutParams(layoutParams);
}
}
addTab
e defino o peso de cada guia conforme ela foi adicionada. override fun addTab(tab: Tab, position: Int, setSelected: Boolean) { super.addTab(tab, position, setSelected) allotEachTabWithEqualWidth() }
Para forçar as guias a ocuparem toda a largura (divididas em tamanhos iguais), aplique o seguinte à TabLayout
exibição:
TabLayout tabLayout = (TabLayout) findViewById(R.id.your_tab_layout);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
TabLayout
estiver definido app:tabMode=“scrollable”
, resultará no comprimento fixo das guias (as palavras longas serão quebradas) e as guias não serão mais deslizadas, essencialmente tornando as guias "fixas" novamente.
Isso é útil, você deve tentar
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMaxWidth="0dp"
app:tabGravity="fill"
app:tabMode="fixed"
app:tabIndicatorColor="@color/white"
app:tabSelectedTextColor="@color/white"
app:tabTextColor="@color/orange" />
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMaxWidth="0dp"
app:tabGravity="fill"
app:tabMode="fixed" />
trabalhe para mim. Isso também temxmlns:app="http://schemas.android.com/apk/res-auto"
Para mim, o código a seguir funcionou e foi suficiente.
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="fill"/>
Verifique o código abaixo para soluções.
Abaixo está o código do layout:
<com.yourpackage.CustomTabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/off_white"
app:tabIndicatorColor="@color/primaryColor"
app:tabIndicatorHeight="3dp"
app:tabMode="scrollable"
app:tabPaddingEnd="0dp"
app:tabPaddingStart="0dp" />
Observe que, para a contagem dinâmica de guias, não se esqueça de chamar setTabNumbers (tabcount).
import android.content.Context;
import android.support.design.widget.TabLayout;
import android.util.AttributeSet;
import android.util.
import java.lang.reflect.Field;
public class CustomTabLayout extends TabLayout
{
private static final int WIDTH_INDEX = 0;
private int DIVIDER_FACTOR = 3;
private static final String SCROLLABLE_TAB_MIN_WIDTH = "mScrollableTabMinWidth";
public CustomTabLayout(Context context) {
super(context);
initTabMinWidth();
}
public CustomTabLayout(Context context, AttributeSet attrs) {
super(context, attrs);
initTabMinWidth();
}
public CustomTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initTabMinWidth();
}
public void setTabNumbers(int num)
{
this.DIVIDER_FACTOR = num;
initTabMinWidth();
}
private void initTabMinWidth()
{
int[] wh = getScreenSize(getContext());
int tabMinWidth = wh[WIDTH_INDEX] / DIVIDER_FACTOR;
Log.v("CUSTOM TAB LAYOUT", "SCREEN WIDTH = " + wh[WIDTH_INDEX] + " && tabTotalWidth = " + (tabMinWidth*DIVIDER_FACTOR) + " && TotalTabs = " + DIVIDER_FACTOR);
Field field;
try {
field = TabLayout.class.getDeclaredField(SCROLLABLE_TAB_MIN_WIDTH);
field.setAccessible(true);
field.set(this, tabMinWidth);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
private static final int WIDTH_INDEX = 0;
private static final int HEIGHT_INDEX = 1;
public static int[] getScreenSize(Context context) {
int[] widthHeight = new int[2];
widthHeight[WIDTH_INDEX] = 0;
widthHeight[HEIGHT_INDEX] = 0;
try {
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
widthHeight[WIDTH_INDEX] = size.x;
widthHeight[HEIGHT_INDEX] = size.y;
if (!isScreenSizeRetrieved(widthHeight))
{
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
widthHeight[0] = metrics.widthPixels;
widthHeight[1] = metrics.heightPixels;
}
// Last defense. Use deprecated API that was introduced in lower than API 13
if (!isScreenSizeRetrieved(widthHeight)) {
widthHeight[0] = display.getWidth(); // deprecated
widthHeight[1] = display.getHeight(); // deprecated
}
} catch (Exception e) {
e.printStackTrace();
}
return widthHeight;
}
private static boolean isScreenSizeRetrieved(int[] widthHeight) {
return widthHeight[WIDTH_INDEX] != 0 && widthHeight[HEIGHT_INDEX] != 0;
}
}
Referência retirada de https://medium.com/@elsenovraditya/set-tab-minimum-width-of-scrollable-tablayout-programmatically-8146d6101efe
Solução para Scrollable (Kotlin)
Em xml:
<com.google.android.material.tabs.TabLayout
android:id="@+id/home_tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMaxWidth="0dp"
app:tabMode="scrollable"
android:fillViewport="true"
app:tabGravity="fill" />
Em Kotlin:
No meu caso, se menos de 3 guias alocarem espaço igual.
Nota: Se a condição é conforme sua exigência
if(list.size <= 3){
allotEachTabWithEqualWidth(your_tab_layout)
}
fun allotEachTabWithEqualWidth(tabLayout: TabLayout) {
mTabLayout.tabMode= TabLayout.MODE_FIXED
val slidingTabStrip = tabLayout.getChildAt(0) as ViewGroup
for (i in 0 until tabLayout.getTabCount()) {
val tab = slidingTabStrip.getChildAt(i)
val layoutParams = tab.layoutParams as LinearLayout.LayoutParams
layoutParams.weight = 1f
tab.layoutParams = layoutParams
}
}
Por que todo esse trabalho agitado? Basta colocar o app:tabMode="scrollable"
seu TabLayout em XML. É isso aí.
tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
Também é apenas uma propriedade a ser definida para tabLayout, não importa quantas guias você esteja adicionando, estática ou dinâmica.
Na minha variante desse problema, eu tinha três guias de tamanho moderado que não estavam ocupando toda a largura dos tablets. Eu não precisava que as guias fossem roláveis nos tablets, pois os tablets são grandes o suficiente para exibir as guias juntas sem necessidade de rolagem. Mas eu precisava que as guias fossem roláveis nos telefones, pois os telefones são pequenos demais para exibir todas as guias juntas.
A melhor solução no meu caso foi adicionar um res/layout-sw600dp/main_activity.xml
arquivo, onde o TabLayout relevante poderia ter app:tabGravity="fill"
e app:tabMode="fixed"
. Mas no meu regular res/layout/main_activity.xml
, eu deixei de fora app:tabGravity="fill"
e app:tabMode="fixed"
, em app:tabMode="scrollable"
vez disso.
Observe que você também precisa definir
app:tabPaddingStart="-1dp"
app:tabPaddingEnd="-1dp"
para preencher todo o espaço