ฉันสร้างคลาส AdaptiveTabLayout เพื่อให้บรรลุสิ่งนี้ นี่เป็นวิธีเดียวที่ฉันพบว่าสามารถแก้ปัญหาได้จริงตอบคำถามและหลีกเลี่ยง / แก้ไขปัญหาที่คำตอบอื่น ๆ ที่นี่ไม่มี
หมายเหตุ:
- จัดการรูปแบบโทรศัพท์ / แท็บเล็ต
- กรณีจับที่มีที่ว่างพอสำหรับแต่ห้องพักไม่เพียงพอสำหรับ
MODE_SCROLLABLE
MODE_FIXED
หากคุณไม่จัดการกรณีนี้มันจะเกิดขึ้นกับอุปกรณ์บางอย่างคุณจะเห็นขนาดข้อความที่แตกต่างกันหรือเตาอบข้อความสองบรรทัดในบางแท็บซึ่งดูไม่ดี
- ได้รับการวัดจริงและไม่ได้ตั้งสมมติฐานใด ๆ (เช่นหน้าจอกว้าง 360dp หรืออะไรก็ตาม ... ) ซึ่งใช้ได้กับขนาดหน้าจอจริงและขนาดแท็บจริง ซึ่งหมายความว่าใช้งานได้ดีกับการแปลเนื่องจากไม่ถือว่าขนาดแท็บใด ๆ แท็บจะได้รับการวัด
- จัดการกับการส่งผ่านที่แตกต่างกันในเฟส onLayout เพื่อหลีกเลี่ยงการทำงานพิเศษ
- ความกว้างของเค้าโครงต้องอยู่
wrap_content
บน xml อย่าตั้งค่าโหมดหรือแรงโน้มถ่วงใด ๆ บน xml
AdaptiveTabLayout.java
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.util.AttributeSet;
import android.widget.LinearLayout;
public class AdaptiveTabLayout extends TabLayout
{
private boolean mGravityAndModeSeUpNeeded = true;
public AdaptiveTabLayout(@NonNull final Context context)
{
this(context, null);
}
public AdaptiveTabLayout(@NonNull final Context context, @Nullable final AttributeSet attrs)
{
this(context, attrs, 0);
}
public AdaptiveTabLayout
(
@NonNull final Context context,
@Nullable final AttributeSet attrs,
final int defStyleAttr
)
{
super(context, attrs, defStyleAttr);
setTabMode(MODE_SCROLLABLE);
}
@Override
protected void onLayout(final boolean changed, final int l, final int t, final int r, final int b)
{
super.onLayout(changed, l, t, r, b);
if (mGravityAndModeSeUpNeeded)
{
setModeAndGravity();
}
}
private void setModeAndGravity()
{
final int tabCount = getTabCount();
final int screenWidth = UtilsDevice.getScreenWidth();
final int minWidthNeedForMixedMode = getMinSpaceNeededForFixedMode(tabCount);
if (minWidthNeedForMixedMode == 0)
{
return;
}
else if (minWidthNeedForMixedMode < screenWidth)
{
setTabMode(MODE_FIXED);
setTabGravity(UtilsDevice.isBigTablet() ? GRAVITY_CENTER : GRAVITY_FILL) ;
}
else
{
setTabMode(TabLayout.MODE_SCROLLABLE);
}
setLayoutParams(new LinearLayout.LayoutParams
(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
mGravityAndModeSeUpNeeded = false;
}
private int getMinSpaceNeededForFixedMode(final int tabCount)
{
final LinearLayout linearLayout = (LinearLayout) getChildAt(0);
int widestTab = 0;
int currentWidth;
for (int i = 0; i < tabCount; i++)
{
currentWidth = linearLayout.getChildAt(i).getWidth();
if (currentWidth == 0) return 0;
if (currentWidth > widestTab)
{
widestTab = currentWidth;
}
}
return widestTab * tabCount;
}
}
และนี่คือคลาส DeviceUtils:
import android.content.res.Resources;
public class UtilsDevice extends Utils
{
private static final int sWIDTH_FOR_BIG_TABLET_IN_DP = 720;
private UtilsDevice() {}
public static int pixelToDp(final int pixels)
{
return (int) (pixels / Resources.getSystem().getDisplayMetrics().density);
}
public static int getScreenWidth()
{
return Resources
.getSystem()
.getDisplayMetrics()
.widthPixels;
}
public static boolean isBigTablet()
{
return pixelToDp(getScreenWidth()) >= sWIDTH_FOR_BIG_TABLET_IN_DP;
}
}
ใช้ตัวอย่าง:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.com.stackoverflow.example.AdaptiveTabLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?colorPrimary"
app:tabIndicatorColor="@color/white"
app:tabSelectedTextColor="@color/text_white_primary"
app:tabTextColor="@color/text_white_secondary"
tools:layout_width="match_parent"/>
</FrameLayout>
ส่วนสำคัญ
ปัญหา / ขอความช่วยเหลือ:
Logcat:
W/View: requestLayout() improperly called by android.support.design.widget.TabLayout$SlidingTabStrip{3e1ebcd6 V.ED.... ......ID 0,0-466,96} during layout: running second layout pass
W/View: requestLayout() improperly called by android.support.design.widget.TabLayout$TabView{3423cb57 VFE...C. ..S...ID 0,0-144,96} during layout: running second layout pass
W/View: requestLayout() improperly called by android.support.design.widget.TabLayout$TabView{377c4644 VFE...C. ......ID 144,0-322,96} during layout: running second layout pass
W/View: requestLayout() improperly called by android.support.design.widget.TabLayout$TabView{19ead32d VFE...C. ......ID 322,0-466,96} during layout: running second layout pass
ผมไม่แน่ใจว่าจะแก้อย่างไร ข้อเสนอแนะใด ๆ ?
- ในการสร้างมาตรการย่อยของ TabLayout ฉันกำลังสร้างการแคสต์และสมมติฐานบางอย่าง (เช่นเดียวกับเด็กเป็น LinearLayout ที่มีมุมมองอื่น ๆ .... ) ซึ่งอาจทำให้เกิดปัญหากับการอัปเดตไลบรารี Design Support เพิ่มเติม แนวทาง / ข้อเสนอแนะที่ดีกว่า?