답변:
이와 같은 Java 코드 또는 XML에서 TextView를 만듭니다.
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:textSize="15sp"
android:textColor="@color/tabs_default_color"
android:gravity="center"
android:layout_height="match_parent"
/>
사용자 정의 textview를 사용하는 경우 TabLayout이이 ID를 확인하므로 ID를 그대로 유지하십시오.
그런 다음 코드에서이 레이아웃을 확장하고 Typeface해당 텍스트보기 에서 사용자 지정 을 설정 하고이 사용자 지정보기를 탭에 추가합니다.
for (int i = 0; i < tabLayout.getTabCount(); i++) {
//noinspection ConstantConditions
TextView tv = (TextView)LayoutInflater.from(this).inflate(R.layout.custom_tab,null)
tv.setTypeface(Typeface);
tabLayout.getTabAt(i).setCustomView(tv);
}
tabTextColor하고 tabSelectedTextColor등록 할 수 있습니까?
사용 TabLayout중이고 글꼴을 변경하려면 다음과 같이 이전 솔루션에 새로운 for 루프를 추가해야합니다.
private void changeTabsFont() {
ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
int tabsCount = vg.getChildCount();
for (int j = 0; j < tabsCount; j++) {
ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
int tabChildsCount = vgTab.getChildCount();
for (int i = 0; i < tabChildsCount; i++) {
View tabViewChild = vgTab.getChildAt(i);
if (tabViewChild instanceof TextView) {
((TextView) tabViewChild).setTypeface(Font.getInstance().getTypeFace(), Typeface.NORMAL);
}
}
}
}
TabLayout
setTypeFace입니다 TypeFace당신이 찾을 수없는 경우 경우에, Font(나를 위해 존재 표시되지 않습니다) 클래스
자신 만의 스타일을 만들고 부모 스타일을 parent="@android:style/TextAppearance.Widget.TabWidget"
그리고 탭 레이아웃에서이 스타일을 app:tabTextAppearance="@style/tab_text"
예 : 스타일 :
<style name="tab_text" parent="@android:style/TextAppearance.Widget.TabWidget">
<item name="android:fontFamily">@font/poppins_regular</item>
</style>
예 : 탭 레이아웃 구성 요소 :
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:tabTextAppearance="@style/tab_text" />
parent="TextAppearance.Design.Tab". 제 경우에 사용 하고 있습니다.
TextAppearance.Widget.TabWidget. @Javatar의 대답이 나를 위해 수정했습니다.
praveen Sharma의 훌륭한 답변입니다. 약간의 추가 : changeTabsFont()필요한 모든 곳 에서 사용하는 대신 TabLayout자신 만의 CustomTabLayout.
import android.content.Context;
import android.graphics.Typeface;
import android.support.design.widget.TabLayout;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class CustomTabLayout extends TabLayout {
private Typeface mTypeface;
public CustomTabLayout(Context context) {
super(context);
init();
}
public CustomTabLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CustomTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mTypeface = Typeface.createFromAsset(getContext().getAssets(), "fonts/Roboto-Regular.ttf");
}
@Override
public void addTab(Tab tab) {
super.addTab(tab);
ViewGroup mainView = (ViewGroup) getChildAt(0);
ViewGroup tabView = (ViewGroup) mainView.getChildAt(tab.getPosition());
int tabChildCount = tabView.getChildCount();
for (int i = 0; i < tabChildCount; i++) {
View tabViewChild = tabView.getChildAt(i);
if (tabViewChild instanceof TextView) {
((TextView) tabViewChild).setTypeface(mTypeface, Typeface.NORMAL);
}
}
}
}
그리고 하나 더.
TabViewA는 LinearLayout로 TextView내부 (또한 선택적으로 포함 할 수있다 ImageView). 따라서 코드를 더 간단하게 만들 수 있습니다.
@Override
public void addTab(Tab tab) {
super.addTab(tab);
ViewGroup mainView = (ViewGroup) getChildAt(0);
ViewGroup tabView = (ViewGroup) mainView.getChildAt(tab.getPosition());
View tabViewChild = tabView.getChildAt(1);
((TextView) tabViewChild).setTypeface(mTypeface, Typeface.NORMAL);
}
하지만이 방법은 권장하지 않습니다. 경우 TabLayout구현이 변경됩니다,이 코드가 제대로 작동하지 않거나 충돌 할 수 있습니다.
사용자 정의하는 또 다른 방법은 사용자 TabLayout정의보기를 추가하는 것입니다. 여기에 좋은 예가 있습니다.
addTab(Tab tab, int position, boolean setSelected)대신 addTab(Tab tab).
(API 레벨 16) 이상을 XML실행하는 장치 에서 기능에서 글꼴 지원을 Android 4.1사용하려면 지원 라이브러리 26 이상을 사용하십시오.
myfont.ttf새로 만든 글꼴 폴더에 파일을 넣으십시오.에 res/values/styles.xml추가 :
<style name="customfontstyle" parent="@android:style/TextAppearance.Small">
<item name="android:fontFamily">@font/myfont</item>
</style>
레이아웃 파일에서 app : tabTextAppearance = "@ style / customfontstyle"을 추가합니다.
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="fill"
app:tabTextAppearance="@style/customfontstyle"
app:tabMode="fixed" />
[fonts in xml]을 참조하세요 . ( https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml )
다음 방법은 전체 글꼴을 ViewGroup재귀 적으로 변경 합니다. 의 내부 구조에 신경 쓸 필요가 없기 때문에이 방법을 선택했습니다 TabLayout. 내가 사용하고 서예 글꼴을 설정하는 라이브러리를.
void changeFontInViewGroup(ViewGroup viewGroup, String fontPath) {
for (int i = 0; i < viewGroup.getChildCount(); i++) {
View child = viewGroup.getChildAt(i);
if (TextView.class.isAssignableFrom(child.getClass())) {
CalligraphyUtils.applyFontToTextView(child.getContext(), (TextView) child, fontPath);
} else if (ViewGroup.class.isAssignableFrom(child.getClass())) {
changeFontInViewGroup((ViewGroup) viewGroup.getChildAt(i), fontPath);
}
}
}
당신은 이것을 사용할 수 있습니다, 그것은 나를 위해 작동합니다.
private void changeTabsFont() {
ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
int tabsCount = vg.getChildCount();
for (int j = 0; j < tabsCount; j++) {
ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
int tabChildsCount = vgTab.getChildCount();
for (int i = 0; i < tabChildsCount; i++) {
View tabViewChild = vgTab.getChildAt(i);
if (tabViewChild instanceof TextView) {
AssetManager mgr = getActivity().getAssets();
Typeface tf = Typeface.createFromAsset(mgr, "fonts/Roboto-Regular.ttf");//Font file in /assets
((TextView) tabViewChild).setTypeface(tf);
}
}
}
}
글쎄, 나는 루프를 사용하지 않고 23.4.0에서 간단하다는 것을 알았습니다. @ejw가 제안한대로 addTab (@NonNull Tab tab, boolean setSelected)를 재정의하면됩니다.
@Override
public void addTab(@NonNull Tab tab, boolean setSelected) {
CoralBoldTextView coralTabView = (CoralBoldTextView) View.inflate(getContext(), R.layout.coral_tab_layout_view, null);
coralTabView.setText(tab.getText());
tab.setCustomView(coralTabView);
super.addTab(tab, setSelected);
}
그리고 여기에 XML이 있습니다
<?xml version="1.0" encoding="utf-8"?>
<id.co.coralshop.skyfish.ui.CoralBoldTextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/custom_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="center"
android:singleLine="true"
android:textColor="@color/graylove"
android:textSize="@dimen/tab_text_size" />
도움이 되길 바랍니다 :)
android:textColor="@color/graylove"state_selected 색상이의 상태 목록 선택을해야 지정
으로 안드레이는 대답 당신은 확장하여 fontface을 변경할 수 있습니다 TabLayout의 클래스를. 그리고 Penzzz가 말했듯이 addTab 메소드 에서는 할 수 없습니다 . onLayout 메서드를 다음과 같이 재정의합니다 .
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom){
super.onLayout(changed, left, top, right, bottom);
final ViewGroup tabStrip = (ViewGroup)getChildAt(0);
final int tabCount = tabStrip.getChildCount();
ViewGroup tabView;
int tabChildCount;
View tabViewChild;
for(int i=0; i<tabCount; i++){
tabView = (ViewGroup)tabStrip.getChildAt(i);
tabChildCount = tabView.getChildCount();
for(int j=0; j<tabChildCount; j++){
tabViewChild = tabView.getChildAt(j);
if(tabViewChild instanceof AppCompatTextView){
if(fontFace == null){
fontFace = Typeface.createFromAsset(context.getAssets(), context.getString(R.string.IranSans));
}
((TextView) tabViewChild).setTypeface(fontFace, Typeface.BOLD);
}
}
}
}
onLayout 메서드를 덮어 써야합니다. setupWithViewPager 메서드를 사용 하여 TabLayout을 ViewPager와 바인딩 할 때 setText 메서드 또는 PagerAdapter에서 탭 텍스트를 설정해야하고이 경우 부모 ViewGroup ( (TextView 텍스트를 변경하면 부모의 onLayout 메서드가 호출 됨-tabView에는 두 개의 자식이 있고 하나는 ImageView이고 다른 하나는 TextView입니다)
또 다른 해결책 :
먼저 다음 코드 줄 :
if(fontFace == null){
fontFace = Typeface.createFromAsset(context.getAssets(), context.getString(R.string.IranSans));
}
위의 솔루션에서 두 개의 루프 외부에 작성해야합니다.
그러나 API> = 16에 대한 더 나은 솔루션 은 android : fontFamily를 사용하는 것입니다 .
크리에이트 안드로이드 자원 디렉토리 라는 이름의 글꼴 및 디렉토리에 원하는 글꼴을 복사합니다.
그런 다음 다음 스타일을 사용하십시오.
<style name="tabLayoutTitles">
<item name="android:textColor">@color/white</item>
<item name="android:textSize">@dimen/appFirstFontSize</item>
<item name="android:fontFamily">@font/vazir_bold</item>
</style>
<style name="defaultTabLayout">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">@dimen/defaultTabLayoutHeight</item>
<item name="android:gravity">right</item>
<item name="tabTextAppearance">@style/tabLayoutTitles</item>
<item name="tabSelectedTextColor">@color/white</item>
<item name="tabIndicatorColor">@color/white</item>
<item name="tabIndicatorHeight">@dimen/accomTabIndicatorHeight</item>
<item name="tabMode">fixed</item>
<item name="tabGravity">fill</item>
<item name="tabBackground">@drawable/rectangle_white_ripple</item>
<item name="android:background">@color/colorPrimary</item>
</style>
onLayout()탭 전환이나 탭 아래의 목록 스크롤과 같은 모든 레이아웃 변경으로 호출되었으며 for많은 탭 TabLayout앱 에서 중첩 된 s 가 지연됩니다.
onLayout()위해 탭 전환시 여러 번 호출되지만 (정확히 이유는 확실하지 않음)이 사실을 설명하기 위해 글꼴을 설정했습니다 boolean changed. 이렇게하면 글꼴을 여러 번 설정하는 것을 방지 할 수 있습니다.
I think this is easier way.
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
app:tabTextColor="@color/lightPrimary"
app:tabSelectedTextColor="@color/white"
style="@style/CustomTabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<style name="CustomTabLayout" parent="Widget.Design.TabLayout">
<item name="tabMaxWidth">20dp</item>
<item name="tabMode">scrollable</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/CustomTabTextAppearance</item>
<item name="tabSelectedTextColor">?android:textColorPrimary</item>
</style>
<style name="CustomTabTextAppearance" parent="TextAppearance.Design.Tab">
<item name="android:textSize">16sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">?android:textColorSecondary</item>
<item name="textAllCaps">false</item>
</style>
나를 위해 일한 Kotlin 확장 프로그램 :
fun TabLayout.setFont(font: FontUtils.Fonts) {
val vg = this.getChildAt(0) as ViewGroup
for (i: Int in 0..vg.childCount) {
val vgTab = vg.getChildAt(i) as ViewGroup?
vgTab?.let {
for (j: Int in 0..vgTab.childCount) {
val tab = vgTab.getChildAt(j)
if (tab is TextView) {
tab.typeface = FontUtils.getTypeFaceByFont(FontUtils.Fonts.BOLD, context)
}
}
}
}
}
내 2p, 참조 확인 기능이있는 Kotlin, 문제가 발생하면 중지되므로 모든 곳에 적용 가능합니다.
private fun setTabLayouFont(tabLayout: TabLayout) {
val viewGroupTabLayout = tabLayout.getChildAt(0) as? ViewGroup?
(0 until (viewGroupTabLayout?.childCount ?: return))
.map { viewGroupTabLayout.getChildAt(it) as? ViewGroup? }
.forEach { viewGroupTabItem ->
(0 until (viewGroupTabItem?.childCount ?: return))
.mapNotNull { viewGroupTabItem.getChildAt(it) as? TextView }
.forEach { applyDefaultFontToTextView(it) }
}
}
그리고 여기에 선택된 탭과 선택되지 않은 탭의 글꼴 변경을 허용하는 Kotlin의 구현이 있습니다.
class FontTabLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
@AttrRes defStyleAttr: Int = 0
) : TabLayout(context, attrs, defStyleAttr) {
private var textSize = 14f
private var defaultSelectedPosition = 0
private var selectedTypeFace: Typeface? = ResourcesCompat.getFont(context, R.font.muli_bold)
private var normalTypeFace: Typeface? = ResourcesCompat.getFont(context, R.font.muli_regular)
@ColorInt private var selectedColor = 0
@ColorInt private var normalTextColor = 0
init {
attrs?.let { initAttrs(it) }
addOnTabSelectedListener()
}
private fun initAttrs(attrs: AttributeSet) {
val a = context.obtainStyledAttributes(attrs, R.styleable.FontTabLayout)
textSize = a.getDimensionPixelSize(R.styleable.FontTabLayout_textSize, 14).toFloat()
defaultSelectedPosition = a.getInteger(R.styleable.FontTabLayout_defaultSelectedPosition, 0)
val selectedResourceId = a.getResourceId(R.styleable.FontTabLayout_selectedTypeFace, R.font.muli_bold)
val normalResourceId = a.getResourceId(R.styleable.FontTabLayout_normalTypeFace, R.font.muli_regular)
selectedColor = a.getColor(com.google.android.material.R.styleable.TabLayout_tabSelectedTextColor, 0)
normalTextColor = a.getColor(R.styleable.FontTabLayout_normalTextColor, 0)
selectedTypeFace = ResourcesCompat.getFont(context, selectedResourceId)
normalTypeFace = ResourcesCompat.getFont(context, normalResourceId)
a.recycle()
}
private fun addOnTabSelectedListener() {
addOnTabSelectedListener(object : OnTabSelectedListenerAdapter() {
override fun onTabUnselected(tab: Tab?) {
getCustomViewFromTab(tab)?.apply {
setTextColor(normalTextColor)
typeface = normalTypeFace
}
}
override fun onTabSelected(tab: Tab?) {
getCustomViewFromTab(tab)?.apply {
setTextColor(selectedColor)
typeface = selectedTypeFace
}
}
private fun getCustomViewFromTab(tab: Tab?) = tab?.customView as? AppCompatTextView
})
}
override fun setupWithViewPager(viewPager: ViewPager?, autoRefresh: Boolean) {
super.setupWithViewPager(viewPager, autoRefresh)
addViews(viewPager)
}
private fun addViews(viewPager: ViewPager?) {
for (i in 0 until tabCount) {
val customTabView = getCustomTabView(i).apply {
typeface = if (i == defaultSelectedPosition) selectedTypeFace else normalTypeFace
val color = if (i == defaultSelectedPosition) selectedColor else normalTextColor
setTextColor(color)
text = viewPager?.adapter?.getPageTitle(i)
}
getTabAt(i)?.customView = customTabView
}
}
private fun getCustomTabView(position: Int): AppCompatTextView {
return AppCompatTextView(context).apply {
gravity = Gravity.CENTER
textSize = this@FontTabLayout.textSize
text = position.toString()
}
}
}
attrs.xml에서 :
<declare-styleable name="FontTabLayout">
<attr name="normalTextColor" format="reference|color" />
<attr name="textSize" format="dimension" />
<attr name="defaultSelectedPosition" format="integer" />
<attr name="selectedTypeFace" format="reference" />
<attr name="normalTypeFace" format="reference" />
</declare-styleable>
kotlin 확장 기능으로 다음을 사용하십시오.
fun TabLayout.setFontSizeAndColor(typeface: Typeface, @DimenRes textSize: Int, @ColorRes textColor: Int) {
val viewGroup: ViewGroup = this.getChildAt(0) as ViewGroup
val tabsCount: Int = viewGroup.childCount
for (j in 0 until tabsCount) {
val viewGroupTab: ViewGroup = viewGroup.getChildAt(j) as ViewGroup
val tabChildCount: Int = viewGroupTab.childCount
for (i in 0 until tabChildCount) {
val tabViewChild: View = viewGroupTab.getChildAt(i) as View
if ( tabViewChild is TextView) {
tabViewChild.typeface = typeface
tabViewChild.gravity = Gravity.FILL
tabViewChild.maxLines = 1
tabViewChild.setTextSize(TypedValue.COMPLEX_UNIT_PX, this.resources.getDimension(textSize))
tabViewChild.setTextColor(ContextCompat.getColor(this.context, textColor))
}
}
}
}