markormesher / android-fab

Floating action button (FAB) for Android with speed-dial menu functionality
Apache License 2.0
211 stars 29 forks source link

Allow setting menu item label View in v2 #24

Closed barbeau closed 6 years ago

barbeau commented 6 years ago

In OneBusAway Android, we use this FAB library for a "Layers" button on top of the map (and it works quite well - thanks! :+1:)- see below screenshot (closed on left, open on right):

image

Because the underlying map can be quite busy, we added a solid background to the label on menu items to make them more readable (see solid blue background for "Bikeshare" label in above screenshot on right).

For v1 of this library, in our LayersSpeedDialAdapter we had the following (simplified a bit below - see link for full source code):

@Override
protected MenuItem getViews(Context context, int position) {
    MenuItem menuItem = new MenuItem();
    menuItem.iconDrawableId = layer.getIconDrawableId();

    // Set the TextView (label) background color to be solid
    TextView label = new TextView(context);
    label.setText(layer.getLayerlabel());
    label.setTextColor(Color.WHITE);
        label.setBackground(R.drawable.speed_dial_disabled_item_label);
    menuItem.labelView = label; // <--- This doesn't seem possible in v2?

    return menuItem;
}

It seems like in v2, you can set the menu item label as a String via the constructor or setter method:

SpeedDialMenuItem menuItem = new SpeedDialMenuItem(context, layer.getIconDrawableId(), layer.getLayerlabel());
menuItem.setLabel(layer.getLayerlabel());

...but there is no way of setting the View for the menu item label, or the background color for the menu item label.

@markormesher Am I missing a new way to do this in v2 of the library? If not, could this be added as a new feature?

Right now this blocks our migration to v2 of this library.

markormesher commented 6 years ago

Hey @barbeau - thanks for flagging this. You're right, there's no way currently to supply the actual view that is used in the menu, because of changes made to the way views are inflated and cached.

I'll take a look at resolving this tomorrow. I'm thinking of adding a few methods to the adapter interface that will be called with references to the label, icon and button views, something like onPrepareMenuItemLabel, etc. That would enable greater control for this use case without changing any functionality elsewhere (and is something I should have no problem releasing by EOD tomorrow). How does that sound?

barbeau commented 6 years ago

@markormesher Sounds good to me! Also, I accidentally omitted the label.setBackground() line of code (which is kind of important - that's the solid background!) from my initial post - I just edited it to add this line.

So, for the background of the TextView we're using XML resource drawables like speed_dial_disabled_item_label.xml that look like:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="12dp"/>
    <padding
            android:top="4dp"
            android:left="8dp"
            android:bottom="4dp"
            android:right="8dp"/>
    <solid android:color="@color/layer_disabled"/>
</shape>

So as long as we can accomplish something similar via methods on the adapter interface that should work. Thanks for looking at this!

markormesher commented 6 years ago

https://github.com/markormesher/android-fab/compare/expose-views-in-menu-adapter

Short and sweet, but should do the job. I'll merge and release this later today after I tackle #25.

markormesher commented 6 years ago

Fixed in v2.2.0 👍

barbeau commented 6 years ago

Thanks @markormesher!

barbeau commented 6 years ago

Thanks @markormesher, this works like a charm!

For anyone else that stumbles on this, I added this (slightly simplified) to my adapter code:

public void onPrepareItemLabel(@NotNull Context context, int position, @NotNull TextView label) {
    // Set the TextView background color to be solid
    label.setText(layer.getLayerlabel());
    label.setTextColor(Color.WHITE);
        label.setBackground(R.drawable.speed_dial_disabled_item_label);
}

...and now I get the solid label background back:

image

Full commit for migrating to v2.2.0 of this library (from 1.x) is in https://github.com/OneBusAway/onebusaway-android/commit/4621fe798cfc7635f30632a80588e891f90053d9.