由于您有权访问底部导航视图,因此每次切换页面时都可以“重绘”底部的工具栏。我们做了类似的事情,没有发现任何性能问题。
您首先希望通过订阅OnElementChanged
中的页面更改来监视页面更改>
Element.CurrentPageChanged += ElementOnCurrentPageChanged;
我正在尝试匹配这样的设计。。
请注意,“选定的标签颜色”为蓝色,但中间标签的图标应始终为绿色圆圈,中间带有白色时钟。
我已经尝试了很多东西。首先,尝试使用具有绿色圆圈和时钟PNG资源的图层列表XML资源以编程方式进行此操作,该资源根本无法使用。然后,我让设计师给了我完整的图标(时钟和绿色圆圈),但是现在我遇到了这个问题。
(未选中)
(已选择)
我无法在Google上找到正确的词来搜索以解决此问题。
最后,我需要选择的选项卡颜色为蓝色,但是我需要中心选项卡图标始终是实际的图标,并且没有其他颜色(本质上,它看起来必须与.png一样。
PS:我正在使用Xamarin.Forms,FreshMvvm和FreshTabbedFONavigationContainer。但是,通过Renderer,我可以直接访问BottomNavigationView和所有其他本机Android组件。因此,解决方案不必是Xamarin解决方案。 Java / kotlin解决方案也可以工作,我可以将其转换为Xamarin。
=========================>
编辑:
=========================>
因此,我在下面使用Andres Castro代码做了很多事情,但是我仍然遇到和以前一样的问题。使用下面的安德列斯(Andres)代码,我切换回使用FontAwesome作为图标(效果很好),但是这样做意味着我需要使用LayerDrawable
创建圆圈/图标中心选项卡图标。
所以这就是我到目前为止的情况。
未选择的中心图标
选定的中心图标
如您所见,未选择时,中心图标仍为灰色,而被选中时,中心图标仍为蓝色(其他4个图标的正确选择/未选择的颜色)。
这是我到目前为止与中心图标有关的代码。
UpdateTabbedIcons
private void UpdateTabbedIcons() { for (var i = 0; i < Element.Children.Count; i++) { var tab = _bottomNavigationView.Menu.GetItem(i); var element = Element.Children[i]; if (element is NavigationPage navigationPage) { //if the child page is a navigation page get its root page element = navigationPage.RootPage; } UpdateTabIcon(tab, element); } }
UpdateTabIcon
public void UpdateTabIcon(IMenuItem menuItem, Page page) { var icon = page?.Icon; if (icon == null) return; var drawable = new IconDrawable(Context, icon, "fa-regular-pro-400.ttf"); var element = Element.CurrentPage; if (element is NavigationPage navigationPage) { //if the child page is a navigation page get its root page element = navigationPage.RootPage; } if (page is DoNowTabPage) { //Page for center icon drawable.Color(Helpers.Resources.White.ToAndroid()); var finalDrawable = GetCombinedDrawable(drawable); menuItem.SetIcon(finalDrawable); return; } else if (element == page) { drawable.Color(BarSelectedItemColor.ToAndroid()); } else { drawable.Color(BarItemColor.ToAndroid()); } menuItem.SetIcon(drawable); }
GetCombinedDrawable
private Drawable GetCombinedDrawable(IconDrawable iconDrawable) { var displayMetrics = Resources.DisplayMetrics; GradientDrawable circleDrawable = new GradientDrawable(); circleDrawable.SetColor(Helpers.Resources.Green.ToAndroid()); circleDrawable.SetShape(ShapeType.Oval); circleDrawable.SetSize((int)TypedValue.ApplyDimension(ComplexUnitType.Dip, 500, displayMetrics), (int)TypedValue.ApplyDimension(ComplexUnitType.Dip, 500, displayMetrics)); circleDrawable.Alpha = 1; var inset = (int)TypedValue.ApplyDimension(ComplexUnitType.Dip, 140, displayMetrics); var bottomInset = (int)TypedValue.ApplyDimension(ComplexUnitType.Dip, 40, displayMetrics); LayerDrawable finalDrawable = new LayerDrawable(new Drawable[] { circleDrawable, iconDrawable }); finalDrawable.SetLayerHeight(1, iconDrawable.IntrinsicHeight); finalDrawable.SetLayerWidth(1, iconDrawable.IntrinsicWidth); finalDrawable.SetLayerInset(1, inset, inset, inset, inset + bottomInset); finalDrawable.SetLayerInsetBottom(0, bottomInset); finalDrawable.ClearColorFilter(); return finalDrawable; }
正如您在为圆圈创建的
GradientDrawable
中看到的那样,我将其颜色设置为我的绿色(我有一个名为Resources的自定义类。这不是Android的Resources
类。] >所以这就是我被困住的地方。我将可绘制的圆设置为绿色,但是一旦在BottomNavigationView中,它的颜色将始终与其他图标的未选中/选中的颜色匹配。
希望克服最后一个问题。感谢您的帮助。
我正在尝试匹配这样的设计。请注意,“选定的选项卡颜色”是蓝色,但中间选项卡的图标应始终是绿色圆圈,中间带有白色时钟。我是...
由于您有权访问底部导航视图,因此每次切换页面时都可以“重绘”底部的工具栏。我们做了类似的事情,没有发现任何性能问题。
您首先希望通过订阅OnElementChanged
中的页面更改来监视页面更改>
Element.CurrentPageChanged += ElementOnCurrentPageChanged;
然后在ElementOnCurrentPageChanged
中,您可以遍历每个页面并获得该页面的菜单项
private void UpdateTabbedIcons()
{
for (var i = 0; i < Element.Children.Count; i++)
{
var tab = _bottomNavigationView.Menu.GetItem(i);
var element = Element.Children[i];
if (element is NavigationPage navigationPage)
{
//if the child page is a navigation page get its root page
element = navigationPage.RootPage;
}
UpdateTabIcon(tab, element);
}
}
在我们的例子中,我们使用字体图标,因此我们每次绘制图标并设置颜色。
public void UpdateTabIcon(IMenuItem menuItem, Page page) { var icon = page?.Icon?.File; if (icon == null) return; var drawable = new IconDrawable(Context, "FontAwesome.ttf", icon).SizeDp(20); var element = Element.CurrentPage; if (element is NavigationPage navigationPage) { //if the child page is a navigation page get its root page element = navigationPage.RootPage; } if (element == page) { drawable.Color(BarSelectedItemColor.ToAndroid()); } else { drawable.Color(BarItemColor.ToAndroid()); } menuItem.SetIcon(drawable); }
我们还必须重写OnAttachedToWindow以确保从不同状态返回到应用程序时图标被重绘。
protected override void OnAttachedToWindow() { UpdateTabbedIcons(); base.OnAttachedToWindow(); }
您将不得不对其进行一些修改以适合您的用例,但我认为该方法应该可以满足您的需求。
我可以为您提供帮助:
public class HomeMenuTabLayout extends TabLayout {
public static final int HOME_MENU_TABLAYOUT_COUNT = 5;
public static final int HOME_MENU_LIVE_INDEX = 0;
public static final int HOME_MENU_TEAM_INDEX = 1;
public static final int HOME_MENU_ADS_INDEX = 2;
public static final int HOME_MENU_WALLET_INDEX = 3;
public static final int HOME_MENU_POST_INDEX = 4;
public int selectedIndex = 0;
private TextView unread;
public HomeMenuTabLayout(Context context) {
super(context);
initItems(context);
}
public HomeMenuTabLayout(Context context, AttributeSet attrs) {
super(context, attrs);
initItems(context);
}
public HomeMenuTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initItems(context);
}
public void initItems(Context context) {
for (int i = 0; i < HOME_MENU_TABLAYOUT_COUNT; i++) {
addTab(newTab());
}
for (int i = 0; i < HOME_MENU_TABLAYOUT_COUNT; i++) {
TabLayout.Tab tab = this.getTabAt(i);
tab.setCustomView(getTabView(context, i, false));
}
}
public void setTagIndex(Context context, int index) {
getTabView(context, selectedIndex, false);
selectedIndex = index;
getTabView(context, selectedIndex, true);
}
private View getTabView(Context context, int index, boolean selected) {
View v = null;
TabLayout.Tab tab = this.getTabAt(index);
if (tab != null) {
v = tab.getCustomView();
if (v == null) {
v = LayoutInflater.from(context).inflate(R.layout.activity_main_tab_layout, null);
}
}
if (v == null) {
return null;
}
ImageView img = v.findViewById(R.id.tablayout_image);
int color = 0;
int color2 = 0;
if (selected) {
color = getResources().getColor(R.color.corn_flower_blue);
color2 = getResources().getColor(R.color.dark_sky_blue_three);
TmlyUtils.displayViewWithZoom(img);
} else {
color = getResources().getColor(R.color.battleship_grey_dark);
color2 = getResources().getColor(R.color.battleship_grey_dark);
}
switch (index) {
case HOME_MENU_ADS_INDEX:
Bitmap offers = StyleKit.imageOfTabbarSearchActive(color, color2);
img.setImageBitmap(offers);
break;
case HOME_MENU_LIVE_INDEX:
Bitmap live = StyleKit.imageOfTabbarHomeActive(color, color2);
img.setImageBitmap(live);
unread = v.findViewById(R.id.tablayout_unread);
break;
case HOME_MENU_TEAM_INDEX:
Bitmap team = StyleKit.imageOfTabbarSocialActive(color, color2);
img.setImageBitmap(team);
break;
case HOME_MENU_WALLET_INDEX:
Bitmap wallet = StyleKit.imageOfTabbarCaddyActive(color, color2);
img.setImageBitmap(wallet);
break;
case HOME_MENU_POST_INDEX:
Bitmap chat = StyleKit.imageOfTabbarPlusActive(getResources().getColor(R.color.white), getResources().getColor(R.color.white));
img.setImageBitmap(chat);
View cirle = v.findViewById(R.id.tablayout_circle);
cirle.setVisibility(View.VISIBLE);
break;
default:
break;
}
return v;
}
}
这是一个自定义的TabLayout,您可以看到我在扩展TabLayout类,创建TabLayout时,我调用了initItems方法,该方法添加了addTab并为其设置了自定义视图。
getTabView返回膨胀视图,您可以通过此视图看到>]
LayoutInflater.from(context).inflate(R.layout.activity_main_tab_layout, null);
如果需要的话
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="@dimen/tab_bar_height"> <ImageView android:id="@+id/tablayout_circle" android:layout_width="@dimen/tab_bar_height" android:layout_height="@dimen/tab_bar_height" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:background="@drawable/circle_blue_gradient" android:visibility="gone" tools:visibility="visible" /> <ImageView android:id="@+id/tablayout_image" android:layout_width="@dimen/tab_bar_icon_favorite_height" android:layout_height="@dimen/tab_bar_icon_favorite_height" android:layout_centerHorizontal="true" android:layout_centerVertical="true" /> </RelativeLayout>
放大视图后,可以使用]来获取view元素。
ImageView img = v.findViewById(R.id.tablayout_image);
您可以检查是否选中了带有选定布尔值的视图,在这种情况下,当索引为中心时,您需要忽略颜色开关。
当您单击TabLayout图标时,请不要忘记调用
setTagIndex();
如果不这样做,图像将不会重绘
由于您有权访问底部导航视图,因此每次切换页面时都可以“重绘”底部的工具栏。我们做了类似的事情,没有发现任何性能问题。
您首先希望通过订阅OnElementChanged
中的页面更改来监视页面更改>
Element.CurrentPageChanged += ElementOnCurrentPageChanged;
我可以为您提供帮助:
public class HomeMenuTabLayout extends TabLayout {
public static final int HOME_MENU_TABLAYOUT_COUNT = 5;
public static final int HOME_MENU_LIVE_INDEX = 0;
public static final int HOME_MENU_TEAM_INDEX = 1;
public static final int HOME_MENU_ADS_INDEX = 2;
public static final int HOME_MENU_WALLET_INDEX = 3;
public static final int HOME_MENU_POST_INDEX = 4;
public int selectedIndex = 0;
private TextView unread;
public HomeMenuTabLayout(Context context) {
super(context);
initItems(context);
}
public HomeMenuTabLayout(Context context, AttributeSet attrs) {
super(context, attrs);
initItems(context);
}
public HomeMenuTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initItems(context);
}
public void initItems(Context context) {
for (int i = 0; i < HOME_MENU_TABLAYOUT_COUNT; i++) {
addTab(newTab());
}
for (int i = 0; i < HOME_MENU_TABLAYOUT_COUNT; i++) {
TabLayout.Tab tab = this.getTabAt(i);
tab.setCustomView(getTabView(context, i, false));
}
}
public void setTagIndex(Context context, int index) {
getTabView(context, selectedIndex, false);
selectedIndex = index;
getTabView(context, selectedIndex, true);
}
private View getTabView(Context context, int index, boolean selected) {
View v = null;
TabLayout.Tab tab = this.getTabAt(index);
if (tab != null) {
v = tab.getCustomView();
if (v == null) {
v = LayoutInflater.from(context).inflate(R.layout.activity_main_tab_layout, null);
}
}
if (v == null) {
return null;
}
ImageView img = v.findViewById(R.id.tablayout_image);
int color = 0;
int color2 = 0;
if (selected) {
color = getResources().getColor(R.color.corn_flower_blue);
color2 = getResources().getColor(R.color.dark_sky_blue_three);
TmlyUtils.displayViewWithZoom(img);
} else {
color = getResources().getColor(R.color.battleship_grey_dark);
color2 = getResources().getColor(R.color.battleship_grey_dark);
}
switch (index) {
case HOME_MENU_ADS_INDEX:
Bitmap offers = StyleKit.imageOfTabbarSearchActive(color, color2);
img.setImageBitmap(offers);
break;
case HOME_MENU_LIVE_INDEX:
Bitmap live = StyleKit.imageOfTabbarHomeActive(color, color2);
img.setImageBitmap(live);
unread = v.findViewById(R.id.tablayout_unread);
break;
case HOME_MENU_TEAM_INDEX:
Bitmap team = StyleKit.imageOfTabbarSocialActive(color, color2);
img.setImageBitmap(team);
break;
case HOME_MENU_WALLET_INDEX:
Bitmap wallet = StyleKit.imageOfTabbarCaddyActive(color, color2);
img.setImageBitmap(wallet);
break;
case HOME_MENU_POST_INDEX:
Bitmap chat = StyleKit.imageOfTabbarPlusActive(getResources().getColor(R.color.white), getResources().getColor(R.color.white));
img.setImageBitmap(chat);
View cirle = v.findViewById(R.id.tablayout_circle);
cirle.setVisibility(View.VISIBLE);
break;
default:
break;
}
return v;
}
}
这是一个自定义的TabLayout,您可以看到我在扩展TabLayout类,创建TabLayout时,我调用了initItems方法,该方法添加了addTab并为其设置了自定义视图。
getTabView返回膨胀视图,您可以通过此视图看到>]
LayoutInflater.from(context).inflate(R.layout.activity_main_tab_layout, null);