Mam zakładki instalacyjne jako UPDATE 29/05/2015 tego postu. Karty biorą pełną szerokość na moim telefonie Nexus 4, ale na tablecie Nexus 7 - na środku i nie pokrywają pełnej szerokości ekranu.
Zrzut ekranu Nexusa 7 Zrzut ekranu Nexusa 4
Mam zakładki instalacyjne jako UPDATE 29/05/2015 tego postu. Karty biorą pełną szerokość na moim telefonie Nexus 4, ale na tablecie Nexus 7 - na środku i nie pokrywają pełnej szerokości ekranu.
Zrzut ekranu Nexusa 7 Zrzut ekranu Nexusa 4
Odpowiedzi:
„Prostsza” odpowiedź pożyczona od Kaizie wystarczy dodać app:tabMaxWidth="0dp"
w plikuTabLayout
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" />
Miałem ten sam problem i sprawdziłem styl TabLayout i stwierdziłem, że jego domyślny styl Widget.Design.TabLayout
ma różne implementacje (normal, landscape i sw600dp).
Potrzebujemy tylko tabletu (sw600dp), który ma następującą implementację:
<style name="Widget.Design.TabLayout" parent="Base.Widget.Design.TabLayout">
<item name="tabGravity">center</item>
<item name="tabMode">fixed</item>
</style>
Z tego stylu użyjemy „ tabGravity ” (możliwymi wartościami są „środek” lub „wypełnienie”) przy użyciu wartości „wypełnienie”.
Musimy jednak pójść głębiej, a potem widzimy, że ten rozciąga się, od Base.Widget.Design.TabLayout
którego wdrożenia jest:
<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>
Dlatego z tego stylu będziemy musieli przesłonić „ tabMaxWidth ”. W moim przypadku ustawiłem to 0dp
, więc nie ma limitu.
Mój styl wyglądał tak:
<style name="MyTabLayout" parent="Widget.Design.TabLayout">
<item name="tabGravity">fill</item>
<item name="tabMaxWidth">0dp</item>
</style>
A następnie pasek kart wypełni cały ekran z boku na bok.
Rozwiązanie dla przewijalnego: (TabLayout.MODE_SCROLLABLE), czyli wtedy, gdy potrzebujesz więcej niż 2 kart (Dynamiczne karty)
Krok 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>
Krok 2: Twój układ 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" />
Krok 3: W swojej aktywności / fragmencie, gdziekolwiek masz zakładki.
/**
* 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
i ustawiłem wagę każdej zakładki w miarę dodawania. override fun addTab(tab: Tab, position: Int, setSelected: Boolean) { super.addTab(tab, position, setSelected) allotEachTabWithEqualWidth() }
Aby zmusić tabulatory do zajęcia pełnej szerokości (podzielenia na równe rozmiary), zastosuj do TabLayout
widoku następujące elementy :
TabLayout tabLayout = (TabLayout) findViewById(R.id.your_tab_layout);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
TabLayout
ustawienie jest ustawione app:tabMode=“scrollable”
, spowoduje to, że zakładki będą miały stałą długość (długie słowa będą się owijać), a zakładki nie będą się przesuwać, co zasadniczo sprawi, że zakładki znów się „naprawią”.
Jest to pomocne, musisz spróbować
<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" />
Pracuj dla mnie. To też maxmlns:app="http://schemas.android.com/apk/res-auto"
Dla mnie poniższy kod działał i był wystarczający.
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="fill"/>
Sprawdź poniższe kody, aby znaleźć rozwiązania.
Poniżej znajduje się kod układu:
<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" />
Uwaga: w celu dynamicznego liczenia kart nie zapomnij wywołać 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;
}
}
Referencje pochodzą z https://medium.com/@elsenovraditya/set-tab-minimum-width-of-scrollable-tablayout-programmatically-8146d6101efe
Rozwiązanie do przewijania (Kotlin)
W 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" />
W Kotlinie:
W moim przypadku, jeśli mniej niż 3 karty, przydzielam równe miejsce.
Uwaga: Jeśli warunek jest zgodny z wymaganiami
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
}
}
Dlaczego cała ta gorączkowa praca? Wystarczy umieścić app:tabMode="scrollable"
TabLayout w XML. Otóż to.
tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
ten sposób. Jest to tylko właściwość ustawiona dla tabLayout, nie ma znaczenia, ile kart dodajesz statycznie czy dynamicznie.
W moim wariancie tego problemu miałem 3 zakładki umiarkowanego rozmiaru, które nie zajmowały pełnej szerokości na tabletach. Nie potrzebowałem przewijania kart na tabletach, ponieważ tablety są wystarczająco duże, aby wyświetlać wszystkie karty bez przewijania. Ale potrzebowałem kart do przewijania na telefonach, ponieważ telefony są zbyt małe, aby wyświetlić wszystkie karty razem.
Najlepszym rozwiązaniem w moim przypadku było dodanie res/layout-sw600dp/main_activity.xml
pliku, w którym odpowiedni TabLayout mógłby mieć app:tabGravity="fill"
i app:tabMode="fixed"
. Ale w moich stałych res/layout/main_activity.xml
, wyszedłem na zewnątrz app:tabGravity="fill"
i app:tabMode="fixed"
, i miał app:tabMode="scrollable"
zamiast.
Pamiętaj, że musisz także ustawić
app:tabPaddingStart="-1dp"
app:tabPaddingEnd="-1dp"
aby wypełnić całą przestrzeń