首页 > 解决方案 > Duolingo 的 RTL ViewPager 覆盖 TabLayout 字体

问题描述

我正在使用以下代码将 TabLayout 的选项卡设置为自定义字体:

Locale locale = Locale.getDefault();
if (locale.equals(new Locale("ar"))) {
    for (int i = 0; i < tabs.getTabCount(); i++) {
        @SuppressLint("InflateParams") TextView tv = (TextView)LayoutInflater.from(this).inflate(R.layout.custom_tabview,null);
        tv.setTypeface(Typeface.createFromAsset(getAssets(),"fonts/JannaLT-Regular.ttf"));
        Objects.requireNonNull(tabs.getTabAt(i)).setCustomView(tv);
    }
}

这工作正常,直到我用 RtlViewPager 库替换 XML 中的 ViewPager,因为 Google 出于某种原因,仍然没有修复 RTL 布局中尴尬的不正确滑动。

<com.duolingo.open.rtlviewpager.RtlViewPager
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

前:

<androidx.viewpager.widget.ViewPager
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

字体不想改变。通过调试,我可以看出该if语句仍在执行,for 循环以及其中的所有内容也是如此。但它只是没有改变。出于某种原因,只需将其从 ViewPager 更改为 RtlViewPager,就会导致 TabLayout 拒绝任何布局更改。即使尝试将文本颜色设置为红色也不起作用。

标签: androidandroid-viewpager

解决方案


我认为这是因为 RTLviewpager 使用原始适配器的包装器,然后当适配器连接到 ViewPager 时它通知数据集更改了两次。

因此,简单的方法是将自定义数据观察器附加到 ViewPager 适配器,在自定义 TabLayout 内,并且每当数据更改时,再次应用自定义字体。

public class MyTabLayout extends TabLayout {


    @Nullable
    private PagerAdapter mPagerAdapter;

    private final DataSetObserver mDataSetObserver = new DataSetObserver() {
        @Override
        public void onChanged() {
            super.onChanged();
            notifyDataSetChanged();
        }
    };

    private final Runnable changeFontRunnable = () -> {
        /* ------ APPLY YOUR FONT HERE TO TAB LAYOUT  --------- */
    };

    public MyTabLayout(Context context) {
        super(context);
    }

    public MyTabLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    @Override
    public void setupWithViewPager(@Nullable ViewPager viewPager) {
        super.setupWithViewPager(viewPager);

        if (viewPager != null && viewPager.getAdapter() != null) {
            unregisterObserver();
            mPagerAdapter = viewPager.getAdapter();
            registerObserver();
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        unregisterObserver();
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        unregisterObserver();
        registerObserver();
    }

    private void registerObserver() {
        if (mPagerAdapter != null) {
            mPagerAdapter.registerDataSetObserver(mDataSetObserver);
        }
    }

    private void unregisterObserver() {
        if (mPagerAdapter != null) {
            try {
                // may throw exception when the observer is not registered before
                mPagerAdapter.unregisterDataSetObserver(mDataSetObserver);
            } catch (IllegalStateException ignored) {}
        }
    }

    public void notifyDataSetChanged() {
        post(changeFontRunnable);
    }
}

推荐阅读