强制堆叠标签
Posted
技术标签:
【中文标题】强制堆叠标签【英文标题】:Force stacked tabs 【发布时间】:2012-11-19 18:31:58 【问题描述】:有没有办法?我希望标签与操作栏分开(在第二行),即使在横向模式下也是如此。
我试图强迫它,但我不能。例如,android 中的 Twitter 应用,当更改为横向模式时,会继续显示两行(单独的行中的选项卡,称为堆叠选项卡)。
谢谢!
【问题讨论】:
【参考方案1】:您不仅不能强制堆叠标签,甚至不能强制标签 - Android 可以并且将用下拉列表替换它们,以便在某些屏幕尺寸和方向进行导航。
您唯一的解决方案是远离操作栏选项卡,例如使用ViewPager
和PagerTabStrip
。
【讨论】:
好的!谢谢你的回答!【参考方案2】:我很幸运地使用了以下反射“hack”:
private void forceStackedTabs()
ActionBar ab = getSupportActionBar();
if ( ab instanceof ActionBarImpl )
// Pre-ICS
disableEmbeddedTabs( ab );
else if ( ab instanceof ActionBarWrapper )
// ICS
try
Field abField = ab.getClass().getDeclaredField( "mActionBar" );
abField.setAccessible( true );
disableEmbeddedTabs( abField.get( ab ) );
catch (NoSuchFieldException e)
Log.e( TAG, "Error disabling actionbar embedded", e );
catch (IllegalArgumentException e)
Log.e( TAG, "Error disabling actionbar embedded", e );
catch (IllegalAccessException e)
Log.e( TAG, "Error disabling actionbar embedded", e );
private void disableEmbeddedTabs(Object ab)
try
Method setHasEmbeddedTabsMethod = ab.getClass().getDeclaredMethod("setHasEmbeddedTabs", boolean.class);
setHasEmbeddedTabsMethod.setAccessible(true);
setHasEmbeddedTabsMethod.invoke(ab, false);
catch (Exception e)
Log.e( TAG, "Error disabling actionbar embedded", e );
请注意,我自己没有想到这一点,只是简单地重写了这个答案中给出的代码:replicate ActionBar Tab(s) with custom view
【讨论】:
这在为 Kitkat 和 Lollipop 编译时似乎不起作用。我找不到 ActionBarImpl 类。【参考方案3】:我用它来强制从 Gingerbread 到 KitKat 的 ActionBar 堆叠或非堆叠标签。
修改自:http://www.blogc.at/2014/01/23/android-tabs-appear-above-or-below-actionbar/
setHasEmbeddedTabs(mActionbar,false);
public static void setHasEmbeddedTabs(Object inActionBar, final boolean inHasEmbeddedTabs)
// get the ActionBar class
Class<?> actionBarClass = inActionBar.getClass();
// if it is a Jelly Bean implementation (ActionBarImplJB), get the super class (ActionBarImplICS)
if ("android.support.v7.app.ActionBarImplJB".equals(actionBarClass.getName()))
actionBarClass = actionBarClass.getSuperclass();
// if Android 4.3 >
if ("android.support.v7.app.ActionBarImplJBMR2".equals(actionBarClass.getName()))
actionBarClass = actionBarClass.getSuperclass().getSuperclass();
try
// try to get the mActionBar field, because the current ActionBar is probably just a wrapper Class
// if this fails, no worries, this will be an instance of the native ActionBar class or from the ActionBarImplBase class
final Field actionBarField = actionBarClass.getDeclaredField("mActionBar");
actionBarField.setAccessible(true);
inActionBar = actionBarField.get(inActionBar);
actionBarClass = inActionBar.getClass();
catch (IllegalAccessException e)
catch (IllegalArgumentException e)
catch (NoSuchFieldException e)
try
// now call the method setHasEmbeddedTabs, this will put the tabs inside the ActionBar
// if this fails, you're on you own <img class="wp-smiley" src="http://www.blogc.at/wp-includes/images/smilies/icon_wink.gif">
final Method method = actionBarClass.getDeclaredMethod("setHasEmbeddedTabs", new Class[] Boolean.TYPE );
method.setAccessible(true);
method.invoke(inActionBar, new Object[] inHasEmbeddedTabs );
catch (NoSuchMethodException e)
catch (InvocationTargetException e)
catch (IllegalAccessException e)
catch (IllegalArgumentException e)
【讨论】:
这是可行的,尽管标签指示器被剪裁在最左边和最右边的标签上。 它在 Gingerbread 上运行良好,但在纵向模式下的 KitKat (Galaxy Tab Pro) 和 Lollipop (Nexus5) 上,标签的位置比它们应该在的位置低一点(不居中),所以 (蓝色)选择线不可见。【参考方案4】:如果您需要支持手机和平板电脑并且不想使用单独的实现,您可以将其放入您的活动中:
@Override
public Resources getResources()
if (mResourcesImpl == null)
mResourcesImpl = new ResourcesImpl(super.getResources());
return mResourcesImpl;
class ResourcesImpl extends Resources
private Resources mResources;
private Set<Integer> mActionBarEmbedTabsIds = new HashSet<Integer>();
ResourcesImpl(Resources resources)
super(resources.getAssets(), resources.getDisplayMetrics(), resources.getConfiguration());
mResources = resources;
String packageName = getPackageName();
mActionBarEmbedTabsIds.add(mResources.getIdentifier("abc_action_bar_embed_tabs", "bool", packageName));
mActionBarEmbedTabsIds.add(mResources.getIdentifier("abc_action_bar_embed_tabs_pre_jb", "bool", packageName));
mActionBarEmbedTabsIds.add(mResources.getIdentifier("action_bar_embed_tabs", "bool", "android"));
mActionBarEmbedTabsIds.add(mResources.getIdentifier("action_bar_embed_tabs_pre_jb", "bool", "android"));
mActionBarEmbedTabsIds.remove(0);
@Override
public boolean getBoolean(int id) throws NotFoundException
if (mActionBarEmbedTabsIds.contains(id))
return areActionBarTabsEmbed(); // stacked ot embed goes here
return super.getBoolean(id);
【讨论】:
以上是关于强制堆叠标签的主要内容,如果未能解决你的问题,请参考以下文章
R语言ggplot2可视化:可视化堆叠的直方图在bin中的每个分组部分添加数值标签为堆叠直方图中的每个分组部分添加数值标签
R语言ggplot2可视化:可视化堆叠的直方图添加每个分组的每个bin的计数标签在堆叠直方图的bin中的每个分组部分添加数值标签