Last active
March 14, 2019 16:40
-
-
Save Grohden/a847cca67c22925017cdd34f1255baa7 to your computer and use it in GitHub Desktop.
Menu icon with count/badge - Android
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<!-- This is the circle around the counter value --> | |
<shape xmlns:android="http://schemas.android.com/apk/res/android" | |
android:shape="oval"> | |
<solid android:color="#CC0001"/> | |
</shape> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* All the massive/repetitive/boring activity code above */ | |
override fun onPrepareOptionsMenu(menu: Menu) { | |
super.onPrepareOptionsMenu(menu) | |
val filterMenu = menu.findItem(R.id.actionFilter) | |
/* | |
* Note: the view somehow manages to get ~3px more larger than a normal | |
* menu icon, i don't really now why the hell this happens and i could not | |
* fix that - i've spent like 5 hours just trying to make this shit work exacly like the | |
* default item. | |
*/ | |
filterMenu.setIconWithCount( | |
requireContext(), | |
R.drawable.ic_funnel_white_24dp, | |
filterCount | |
) | |
} | |
/* All the massive/repetitive/boring activity code bellow */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package android.api.sucks | |
import android.content.Context | |
import android.graphics.drawable.BitmapDrawable | |
import android.view.LayoutInflater | |
import android.view.MenuItem | |
import android.view.View | |
import android.graphics.Bitmap | |
import android.graphics.Canvas | |
import android.graphics.Color | |
import androidx.annotation.DrawableRes | |
import androidx.appcompat.content.res.AppCompatResources | |
import br.com.ngi.mnt.R | |
import kotlinx.android.synthetic.main.icon_with_count.view.* | |
/** | |
* Sets the icon with a counter badge on the top right corner | |
* if the count is not 0 | |
* | |
* @param context the android god object | |
* @param iconRes the item icon id/res | |
* @param count the count value | |
* | |
*/ | |
fun MenuItem.setIconWithCount( | |
context: Context, | |
@DrawableRes iconRes: Int, | |
count: Int | |
) { | |
val inflater = LayoutInflater.from(context) | |
val view = inflater.inflate(R.layout.icon_with_count, null) | |
AppCompatResources | |
.getDrawable(view.context, iconRes) | |
.let { view.counterIcon.setBackgroundDrawable(it) } | |
if (count == 0) { | |
view.count.gone() | |
} else { | |
view.count.text = "$count" | |
} | |
view.measure( | |
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), | |
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED) | |
) | |
view.layout(0, 0, view.measuredWidth, view.measuredHeight) | |
val bitmap = view.getBitmapFromView() | |
this.icon = BitmapDrawable(context.resources, bitmap) | |
} | |
/** | |
* Returns the view drawable (basically a screenshot of the view) | |
* the code is from this answer https://stackoverflow.com/a/52905682/4777865 | |
*/ | |
fun View.getBitmapFromView(): Bitmap { | |
val returnedBitmap = Bitmap.createBitmap( | |
measuredWidth, | |
measuredHeight, | |
Bitmap.Config.ARGB_8888 | |
) | |
val canvas = Canvas(returnedBitmap) | |
val bgDrawable = this.background | |
if (bgDrawable != null) { | |
bgDrawable.draw(canvas) | |
} else { | |
canvas.drawColor(Color.TRANSPARENT) | |
} | |
draw(canvas) | |
return returnedBitmap | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<!-- | |
This is the view that will be rendered in the place of the 'pure icon' | |
Note: the layout preview is really distorted, but in the device it works | |
Note 2: the view somehow manages to get 3px~ more larger than a normal | |
Menu icon, i don't really know why the hell this happens and i could not | |
fix that. | |
--> | |
<FrameLayout | |
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:layout_width="wrap_content" | |
android:layout_height="?attr/actionBarSize" | |
> | |
<androidx.constraintlayout.widget.ConstraintLayout | |
android:id="@+id/counterRoot" | |
android:layout_width="30dp" | |
android:layout_height="30dp" | |
android:clickable="true" | |
android:focusable="true" | |
tools:background="@android:color/black" | |
android:background="?attr/selectableItemBackground" | |
android:layout_gravity="center" | |
android:layout_marginBottom="2dp" | |
> | |
<ImageView | |
android:id="@+id/counterIcon" | |
android:layout_width="25dp" | |
android:layout_height="25dp" | |
tools:background="@drawable/ic_funnel_white_24dp" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintStart_toStartOf="parent" | |
tools:ignore="ContentDescription" | |
/> | |
<TextView | |
android:id="@+id/count" | |
android:layout_width="14dp" | |
android:layout_height="14dp" | |
android:layout_marginBottom="14dp" | |
android:layout_marginStart="16dp" | |
android:background="@drawable/circular_red_shape" | |
tools:text="1" | |
android:textAlignment="center" | |
android:textColor="@android:color/white" | |
android:textSize="10sp" | |
android:textStyle="bold" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintStart_toStartOf="parent" | |
tools:ignore="SmallSp" | |
/> | |
</androidx.constraintlayout.widget.ConstraintLayout> | |
</FrameLayout> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment