我使用以下代码将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拒绝任何布局更改。甚至尝试将文本颜色设置为红色都无法正常工作。
答案 0 :(得分:1)
我认为是因为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);
}
}
答案 1 :(得分:0)
检查以下示例:
1)MainActivity.class
\n
2)CustomPagerAdapter.class
public class MainActivity extends AppCompatActivity {
private final String TAG = MainActivity.class.getSimpleName();
private RelativeLayout rl;
private TabLayout tabLayout;
private RtlViewPager viewPager;
private Button b;
private Context langResContext;
private String language;
private SharedPreferences sharedPreferences;
private final String ARABIC = "ar";
private final String ENGLISH = "en";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sharedPreferences = getSharedPreferences(getResources().getString(R.string.prefs), MODE_PRIVATE);
rl = (RelativeLayout) findViewById(R.id.rl);
viewPager = (RtlViewPager) findViewById(R.id.viewpager);
/**
* get saved language and update ui
*/
language = sharedPreferences.getString(getResources().getString(R.string.language),
getResources().getString(R.string.language_default));
b = (Button) findViewById(R.id.b);
if (language.equals(getResources().getString(R.string.Arabic))) {
language = getResources().getString(R.string.Arabic);
langResContext = setLanguage(ARABIC, MainActivity.this);
b.setText(getResources().getString(R.string.English));
} else {
language = getResources().getString(R.string.English);
langResContext = setLanguage(ENGLISH, MainActivity.this);
b.setText(getResources().getString(R.string.Arabic));
}
CustomPagerAdapter customPagerAdapter = new CustomPagerAdapter(getSupportFragmentManager(), 3, MainActivity.this,
language, langResContext);
viewPager.setAdapter(customPagerAdapter);
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (b.getText().toString().equals(getResources().getString(R.string.Arabic))) {
language = getResources().getString(R.string.Arabic);
langResContext = setLanguage(ARABIC, MainActivity.this);
b.setText(getResources().getString(R.string.English));
} else {
language = getResources().getString(R.string.English);
langResContext = setLanguage(ENGLISH, MainActivity.this);
b.setText(getResources().getString(R.string.Arabic));
}
saveLanguage(language);
onLanguageChanged(language, langResContext, true);
}
});
onLanguageChanged(language, langResContext, false);
}
@TargetApi(Build.VERSION_CODES.KITKAT)
private void onLanguageChanged(String language, Context langResContext, boolean recreate) {
if (language.equals(getResources().getString(R.string.Arabic))) {
rl.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
} else {
rl.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
}
for (int i = 0; i < tabLayout.getTabCount(); i++) {
tabLayout.getTabAt(i).setCustomView(null);
@SuppressLint("InflateParams")
TextView tv = (TextView) LayoutInflater.from(this).inflate(R.layout.custom_tabview, null);
Objects.requireNonNull(tabLayout.getTabAt(i)).setCustomView(tv);
if (language.equals(getResources().getString(R.string.Arabic))) {
tv.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/JannaLT-Regular.ttf"));
tv.setTextColor(Color.BLUE);
} else {
tv.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/SrabiScript.ttf"));
tv.setTextColor(Color.GREEN);
}
switch (i) {
case 0:
tv.setText(langResContext.getResources().getString(R.string.page1));
break;
case 1:
tv.setText(langResContext.getResources().getString(R.string.page2));
break;
case 2:
tv.setText(langResContext.getResources().getString(R.string.page3));
break;
}
CustomPagerAdapter customPagerAdapter = (CustomPagerAdapter) viewPager.getAdapter();
if (customPagerAdapter != null) {
customPagerAdapter.setLanguage(language, langResContext);
CustomFragment customFragment = (CustomFragment) getSupportFragmentManager().findFragmentByTag(customPagerAdapter.getFragmentTag(i, viewPager.getId()));
if (customFragment != null) {
customFragment.setLanguage(language, langResContext);
customFragment.applyLanguageChanges();
}
}
}
if(recreate){
MainActivity.this.recreate();
}
}
private void saveLanguage(String language) {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(getResources().getString(R.string.language), language);
editor.apply();
}
/**
* https://stackoverflow.com/questions/2900023/change-app-language-programmatically-in-android
*
* Thanks to Zoe's Answer
*/
/**
* * Full locale list: https://stackoverflow.com/questions/7973023/what-is-the-list-of-supported-languages-locales-on-android
*
* @param lang language code (e.g. en_US)
* @return the context
* PLEASE READ: This method can be changed for usage outside an Activity. Simply add a COntext to the arguments
*/
public Context setLanguage(String lang, Context c) {
int API = Build.VERSION.SDK_INT;
if (API >= 17) {
return setLanguage17(lang, c);
} else {
return setLanguageLegacy(lang, c);
}
}
/**
* Set language for API 17
*
* @param lang
* @param c
* @return
*/
@TargetApi(17)
public Context setLanguage17(String lang, Context c) {
Configuration overrideConfiguration = c.getResources().getConfiguration();
Locale locale = new Locale(lang);
Locale.setDefault(locale);
overrideConfiguration.setLocale(locale);
//the configuration can be used for other stuff as well
Context context = createConfigurationContext(overrideConfiguration);//"local variable is redundant" if the below line is uncommented, it is needed
//Resources resources = context.getResources();//If you want to pass the resources instead of a Context, uncomment this line and put it somewhere useful
return context;
}
public Context setLanguageLegacy(String lang, Context c) {
Resources res = c.getResources();
// Change locale settings in the app.
DisplayMetrics dm = res.getDisplayMetrics();//Utility line
android.content.res.Configuration conf = res.getConfiguration();
conf.locale = new Locale(lang);//setLocale requires API 17+ - just like createConfigurationContext
Locale.setDefault(conf.locale);
res.updateConfiguration(conf, dm);
//Using this method you don't need to modify the Context itself. Setting it at the start of the app is enough. As you
//target both API's though, you want to return the context as you have no clue what is called. Now you can use the Context
//supplied for both things
return c;
}
}
3)CustomFragment.class
public class CustomPagerAdapter extends FragmentPagerAdapter {
private int numberOfPages = 0;
private Context context;
private String language;
private Context langResContext;
private int[] color = new int[]{Color.RED, Color.MAGENTA, Color.GREEN};
public CustomPagerAdapter(FragmentManager fm, int numberOfPages, Context context,
String language, Context langResContext) {
super(fm);
this.numberOfPages = numberOfPages;
this.context = context;
this.language = language;
this.langResContext = langResContext;
}
@Override
public Fragment getItem(int position) {
CustomFragment customFragment = new CustomFragment(context,
language, langResContext);
Bundle extras = new Bundle();
extras.putInt(CustomFragment.NUMBER, position);
extras.putInt(CustomFragment.COLOR, color[position]);
customFragment.setArguments(extras);
return customFragment ;
}
@Override
public int getCount() {
return this.numberOfPages;
}
public String getFragmentTag(int pos, int vpId) {
return "android:switcher:" + vpId + ":" + pos;
}
public void setLanguage(String language, Context langResContext) {
this.language = language;
this.langResContext = langResContext;
}
}
4)activity_main.xml
public class CustomFragment extends Fragment {
private int number = 0;
private int color = Color.BLACK;
public static final String NUMBER = "number";
public static final String COLOR = "color";
public static final String LANGUAGE = "language";
private Context context;
private String language;
private Context langResContext;
public CustomFragment(Context context, String language, Context langResContext) {
super();
this.context = context;
this.langResContext = langResContext;
this.language = language;
}
public CustomFragment() {
super();
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View layout = (View) inflater.inflate(R.layout.custom_fragment, container, false);
return layout;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (getArguments() != null) {
Bundle extra = getArguments();
number = extra.getInt(NUMBER, 0);
color = extra.getInt(COLOR, Color.BLACK);
}
applyLanguageChanges();
}
public void applyLanguageChanges() {
View view = getView();
Context langResContext = this.langResContext != null ? this.langResContext : this.context;
if (getArguments() != null && view != null) {
Bundle extra = getArguments();
number = extra.getInt(NUMBER, 0);
color = extra.getInt(COLOR, Color.WHITE);
TextView tv = (TextView) view.findViewById(R.id.tv);
String text = "0";
switch (number) {
case 0:
text = langResContext.getResources().getString(R.string.page1);
break;
case 1:
text = langResContext.getResources().getString(R.string.page2);
break;
case 2:
text = langResContext.getResources().getString(R.string.page3);
break;
}
tv.setText(text);
tv.setBackgroundColor(this.color);
}
}
public void setLanguage(String language, Context langResContext){
this.language = language;
this.langResContext = langResContext;
}
}
5)custom_fragment.xml
<com.google.android.material.tabs.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tabLayout"
android:layout_alignParentTop="true"
android:background="@color/colorPrimary"
app:tabSelectedTextColor="@android:color/white"
app:tabTextColor="@android:color/black">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/page1"
android:text="@string/page1">
</com.google.android.material.tabs.TabItem>
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/page2"
android:text="@string/page2">
</com.google.android.material.tabs.TabItem>
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/page3"
android:text="@string/page3">
</com.google.android.material.tabs.TabItem>
</com.google.android.material.tabs.TabLayout>
<com.duolingo.open.rtlviewpager.RtlViewPager
android:id="@+id/viewpager"
android:layout_below="@id/tabLayout"
android:layout_width="match_parent"
android:layout_above="@id/b"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:layout_height="match_parent"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="@string/English"
android:id="@+id/b">
</Button>
</RelativeLayout>
6)custom_tabview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="45sp"
android:gravity="center"
android:id="@+id/tv"
android:textColor="@android:color/white"
android:text="Page">
</TextView>
</LinearLayout>
7)strings.xml(英语)
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tv"
android:gravity="center"
xmlns:android="http://schemas.android.com/apk/res/android">
</TextView>
8)strings.xml(阿拉伯语)
<resources>
<string name="page1">Page 1</string>
<string name="page2">Page 2</string>
<string name="page3">Page 3</string>
<string name="prefs">prefs</string>
<string name="language">language_pref</string>
<string name="language_default">English</string>
<string name="English">English</string>
<string name="Arabic">العربية</string>
</resources>
9)输出