使 TabLayout 的元素适合屏幕
Fitting Elements of the TabLayout into Screen
我的 Android 应用程序中有一个 Activity,其中包含用于在不同片段之间切换的 TabLayout。我实现了一个自定义 FragmentStatePagerAdapter 来插入我的列并使用 tabLayout.setupWithViewPager(mViewPager) 方法在我的 Activity 中初始化它。
我的问题是,如果我在我的 tabLayout 中使用 TabLayout.MODE_FIXED,我最终会得到其中一个元素,即讨论,如下图所示:
在另一种情况下,如果我使用 TabLayout.MODE_SCROLLABLE,我最终会将 tabLayout 的所有预定义元素都缩小到应用程序的左角,并且有大量空白 space,无论我指定的重力是这样的:
我试图获得的结果是:
1) 固定模式下没有两个内衬或重叠元素的 TabLayout,或者;
2) 可滚动模式下的 TabLayout 至少覆盖所有空 space 可用 and/or 覆盖超过给定的 space 因为只要用户可以在 TabLayout 中滚动就可以接受查看和访问不可见的选项卡。
相关源代码和资源代码如下。如果需要更多信息,请告诉我。
我的activity代码:
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import swe574.boun.edu.androidproject.adapters.GroupTabPagerAdapter;
public class GroupActivity extends AppCompatActivity {
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {@link FragmentPagerAdapter} derivative, which will keep every
* loaded fragment in memory. If this becomes too memory intensive, it
* may be best to switch to a
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
private GroupTabPagerAdapter mSectionsPagerAdapter;
/**
* The {@link ViewPager} that will host the section contents.
*/
private ViewPager mViewPager;
private List<String> mTitles;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_group);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mTitles = new ArrayList<>();
mTitles.addAll(Arrays.asList(new String[]{"Home" , "Meetings" , "Discussions" , "Notes"}));
mSectionsPagerAdapter = new GroupTabPagerAdapter(getSupportFragmentManager(), mTitles, 4);
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
tabLayout.setTabGravity(TabLayout.GRAVITY_CENTER);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_group, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
我的 GroupTabPagerAdapter 代码:
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import java.util.List;
import swe574.boun.edu.androidproject.fragments.DiscussionFragment;
import swe574.boun.edu.androidproject.fragments.GroupHomeFragment;
import swe574.boun.edu.androidproject.fragments.MeetingFragment;
import swe574.boun.edu.androidproject.fragments.NoteFragment;
public class GroupTabPagerAdapter extends FragmentStatePagerAdapter {
private List<String> mTitles;
private int mNumOfTabs;
public GroupTabPagerAdapter(FragmentManager fm, List<String> mTitles, int mNumOfTabs) {
super(fm);
this.mTitles = mTitles;
this.mNumOfTabs = mNumOfTabs;
}
@Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new GroupHomeFragment();
break;
case 1:
fragment = new MeetingFragment();
break;
case 2:
fragment = new DiscussionFragment();
break;
case 3:
fragment = new NoteFragment();
break;
}
return fragment;
}
@Override
public int getCount() {
return mNumOfTabs;
}
@Override
public CharSequence getPageTitle(int position) {
return mTitles.get(position);
}
}
我的Activity布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="swe574.boun.edu.androidproject.GroupActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/appbar_padding_top"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
感谢您的帮助。
我通过在自定义 class 中扩展 TabLayout 并使用以下方法覆盖 onMeasure 方法来解决此问题:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
try {
if (getTabCount() == 0){
return;
}
Field field = TabLayout.class.getDeclaredField("mTabMinWidth");
field.setAccessible(true);
field.set(this, (int) (getMeasuredWidth() / (float) getTabCount()) * 1);
} catch (Exception e) {
e.printStackTrace();
}
}
我的 Android 应用程序中有一个 Activity,其中包含用于在不同片段之间切换的 TabLayout。我实现了一个自定义 FragmentStatePagerAdapter 来插入我的列并使用 tabLayout.setupWithViewPager(mViewPager) 方法在我的 Activity 中初始化它。
我的问题是,如果我在我的 tabLayout 中使用 TabLayout.MODE_FIXED,我最终会得到其中一个元素,即讨论,如下图所示:
在另一种情况下,如果我使用 TabLayout.MODE_SCROLLABLE,我最终会将 tabLayout 的所有预定义元素都缩小到应用程序的左角,并且有大量空白 space,无论我指定的重力是这样的:
我试图获得的结果是:
1) 固定模式下没有两个内衬或重叠元素的 TabLayout,或者;
2) 可滚动模式下的 TabLayout 至少覆盖所有空 space 可用 and/or 覆盖超过给定的 space 因为只要用户可以在 TabLayout 中滚动就可以接受查看和访问不可见的选项卡。
相关源代码和资源代码如下。如果需要更多信息,请告诉我。
我的activity代码:
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import swe574.boun.edu.androidproject.adapters.GroupTabPagerAdapter;
public class GroupActivity extends AppCompatActivity {
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {@link FragmentPagerAdapter} derivative, which will keep every
* loaded fragment in memory. If this becomes too memory intensive, it
* may be best to switch to a
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
private GroupTabPagerAdapter mSectionsPagerAdapter;
/**
* The {@link ViewPager} that will host the section contents.
*/
private ViewPager mViewPager;
private List<String> mTitles;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_group);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mTitles = new ArrayList<>();
mTitles.addAll(Arrays.asList(new String[]{"Home" , "Meetings" , "Discussions" , "Notes"}));
mSectionsPagerAdapter = new GroupTabPagerAdapter(getSupportFragmentManager(), mTitles, 4);
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
tabLayout.setTabGravity(TabLayout.GRAVITY_CENTER);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_group, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
我的 GroupTabPagerAdapter 代码:
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import java.util.List;
import swe574.boun.edu.androidproject.fragments.DiscussionFragment;
import swe574.boun.edu.androidproject.fragments.GroupHomeFragment;
import swe574.boun.edu.androidproject.fragments.MeetingFragment;
import swe574.boun.edu.androidproject.fragments.NoteFragment;
public class GroupTabPagerAdapter extends FragmentStatePagerAdapter {
private List<String> mTitles;
private int mNumOfTabs;
public GroupTabPagerAdapter(FragmentManager fm, List<String> mTitles, int mNumOfTabs) {
super(fm);
this.mTitles = mTitles;
this.mNumOfTabs = mNumOfTabs;
}
@Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new GroupHomeFragment();
break;
case 1:
fragment = new MeetingFragment();
break;
case 2:
fragment = new DiscussionFragment();
break;
case 3:
fragment = new NoteFragment();
break;
}
return fragment;
}
@Override
public int getCount() {
return mNumOfTabs;
}
@Override
public CharSequence getPageTitle(int position) {
return mTitles.get(position);
}
}
我的Activity布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="swe574.boun.edu.androidproject.GroupActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/appbar_padding_top"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
感谢您的帮助。
我通过在自定义 class 中扩展 TabLayout 并使用以下方法覆盖 onMeasure 方法来解决此问题:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
try {
if (getTabCount() == 0){
return;
}
Field field = TabLayout.class.getDeclaredField("mTabMinWidth");
field.setAccessible(true);
field.set(this, (int) (getMeasuredWidth() / (float) getTabCount()) * 1);
} catch (Exception e) {
e.printStackTrace();
}
}