Skip to content

Instantly share code, notes, and snippets.

View samuel22gj's full-sized avatar
👨‍💻
Coding

Samuel Huang samuel22gj

👨‍💻
Coding
View GitHub Profile
@samuel22gj
samuel22gj / compress.sh
Created November 17, 2022 08:16
compress mp3 by 48k bitrate and remove title metadata
#!/usr/bin/env bash
set -o errexit
set -o pipefail
set -o nounset
OIFS="$IFS"
IFS=$'\n'
info () {
@samuel22gj
samuel22gj / BarcodeEncoder.kt
Created April 25, 2022 14:33
Generate QR Code by ZXing in Android
import android.graphics.Bitmap
import com.google.zxing.BarcodeFormat
import com.google.zxing.EncodeHintType
import com.google.zxing.MultiFormatWriter
import com.google.zxing.common.BitMatrix
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
object BarcodeEncoder {
@samuel22gj
samuel22gj / BooleanTypeAdapterTest.kt
Last active December 17, 2021 08:34
SafeBooleanTypeAdapter for Kotlin
class BooleanTypeAdapterTest {
@Test
fun testBooleanTypeAdapter() {
val gson = GsonBuilder()
.registerTypeAdapter(Boolean::class.javaObjectType, BooleanObjectTypeAdapter())
.registerTypeAdapter(Boolean::class.javaPrimitiveType, BooleanPrimitiveTypeAdapter())
.create()
assertEquals(null, gson.fromJson("""{"isBoolean"=null}""", Foo::class.java).isBoolean)
/**
* A mediator to link a fragment container with a BottomNavigationView.
*
* The mediator will synchronize the fragment container's content
* with the selected item when a item of BottomNavigationView is selected.
*/
class FragmentBottomNavigationMediator(
private val fragmentManager: FragmentManager,
@IdRes private val containerViewId: Int,
private val bottomNavigationView: BottomNavigationView,
/**
* A customized [BottomNavigationView] with some convenience functions.
*/
class BottomNavigationViewPlus @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
@AttrRes defStyleAttr: Int = com.google.android.material.R.attr.bottomNavigationStyle
) : BottomNavigationView(
context, attrs, defStyleAttr
) {
object RecyclerViewUtils {
fun <VH : RecyclerView.ViewHolder> scrollToHolderWithFallback(
recyclerViewMatcher: Matcher<View>,
viewHolderMatcher: Matcher<VH>,
failureViewAction: ViewAction,
maxRetryCount: Int
) {
var count = maxRetryCount
@samuel22gj
samuel22gj / TestNameToastRule.kt
Last active February 22, 2020 13:12
Rule to be used in tests that display a Toast with class name and method name when each test starting.
/**
* Rule to be used in tests that display a Toast with class name and method name when each test starting.
*
* ```
* @RunWith(AndroidJUnit4::class)
* class FooTest {
*
* @get:Rule
* val testNameToastRule = TestNameToastRule()
*
sealed class SharedPreferenceDelegates<in R, T> : ReadWriteProperty<R, T> {
class BooleanType(
private val sharedPreferences: SharedPreferences,
private val key: String,
private val defaultValue: Boolean = false
) : SharedPreferenceDelegates<Any?, Boolean>() {
override fun getValue(thisRef: Any?, property: KProperty<*>): Boolean {
return sharedPreferences.getBoolean(key, defaultValue)
/**
* @see <a href="https://medium.com/androiddevelopers/windows-insets-fragment-transitions-9024b239a436">Windows Insets + Fragment Transitions</a>
*/
public class DispatchWindowInsetsToAllChildrenListener implements OnApplyWindowInsetsListener {
@Override
public WindowInsetsCompat onApplyWindowInsets(View view, WindowInsetsCompat windowInsetsCompat) {
boolean consumed = false;
if (view instanceof ViewGroup) {
public class ToolbarOffsetChangedListener implements AppBarLayout.OnOffsetChangedListener {
private static final String TAG = "ToolbarOffsetChangedListener";
private Toolbar toolbar;
private Drawable[] icons;
/**
* 觸發開始改變顏色的 offset [0, - AppBar's height]
*/
private int verticalOffsetTrigger = -1;