Skip to content

Instantly share code, notes, and snippets.

View dzolnai's full-sized avatar

Dániel Zolnai dzolnai

  • Egeniq
  • Budapest
View GitHub Profile
@dzolnai
dzolnai / fragment_genres.xml
Created February 3, 2021 07:30
Genre fragment with a CollapsingToolbarLayout
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:expandedTitleMarginStart="@dimen/genre_clickable_title_left_margin"
app:expandedTitleMarginBottom="@dimen/genre_clickable_title_bottom_margin"
app:expandedTitleMarginTop="0dp"
app:collapsedTitleGravity="center"
android:background="@color/background"
app:collapsedTitleTextAppearance="@style/AppTheme.CollapsingToolbarTitle.Collapsed"
@dzolnai
dzolnai / View.kt
Last active August 2, 2023 15:12
Expandable TextView with clickable '...read more'
import android.annotation.SuppressLint
import android.content.Context
import android.text.Layout
import android.text.Spannable
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.StaticLayout
import android.text.TextPaint
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
@dzolnai
dzolnai / DisallowToolbarExpand.kt
Created December 28, 2020 15:20
Disallow the toolbar expand on a collapsible toolbar layout
internal fun disallowToolbarExpand() {
// Taken from: https://stackoverflow.com/a/49218710/1395437
binding.appBar.setExpanded(false, false)
ViewCompat.setNestedScrollingEnabled(binding.content, false)
val params = binding.appBar.layoutParams as CoordinatorLayout.LayoutParams
if (params.behavior == null) {
params.behavior = AppBarLayout.Behavior()
}
val behaviour = params.behavior as AppBarLayout.Behavior
behaviour.setDragCallback(object : AppBarLayout.Behavior.DragCallback() {
@dzolnai
dzolnai / AppBarOffsetChangeListener.kt
Created December 28, 2020 15:09
Detect appbar offset
binding.appBar.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { _, verticalOffset ->
// By updating the LayoutParams, we trigger the offset change listener, which then results in a somewhat infinite loop.
// This flag makes sure that we discard the next callback after updating the layout.
if (verticalOffset == lastOffset) {
return@OnOffsetChangedListener
}
val offsetPercentage = verticalOffset / -maxOffset // 0 is fully expanded, 1 is fully collapsed
val interpolatedPercentage = interpolator.getInterpolation(offsetPercentage)
val baseWidth = expandedTextWidth - (expandedTextWidth - collapsedTextWidth) * interpolatedPercentage
val marginExtra = expandedMargin - (expandedMargin - collapsedMargin) * offsetPercentage
@dzolnai
dzolnai / CustomMediaRouteButton.kt
Last active April 23, 2020 09:26
Custom Media Route button which hides when there are no Cast devices on the network
@file:Suppress("PackageDirectoryMismatch")
package androidx.mediarouter.app
import android.content.Context
import android.util.AttributeSet
import android.view.View
import androidx.core.content.ContextCompat
import androidx.mediarouter.media.MediaRouter
class CustomMediaRouteButton : MediaRouteButton {
@dzolnai
dzolnai / MainActivity.kt
Created November 29, 2019 13:06
Creating an ExoPlayer with your own audioprocessor
private val fftAudioProcessor = FFTAudioProcessor()
val renderersFactory = object : DefaultRenderersFactory(this) {
override fun buildAudioProcessors(): Array<AudioProcessor> {
val processors = super.buildAudioProcessors()
return processors + fftAudioProcessor
}
}
player = ExoPlayerFactory.newSimpleInstance(this, renderersFactory, DefaultTrackSelector())
@dzolnai
dzolnai / app.js
Created November 27, 2019 15:06
Running tau with an element
var t = tau.animation.target;
var digitElement = document.querySelector("#digit-element");
t(digitElement).tween({
translateY : -(finalOffset) * digitSizePx + constantOffset
}, {
duration : 1000,
ease: 'linear'
});
@dzolnai
dzolnai / Including tau in your Tizen project
Created November 27, 2019 15:00
The journey of creating an electric meter style Tizen watchface
<head>
...
<link rel="stylesheet" href="lib/tau/wearable/theme/default/tau.css">
<link rel="stylesheet" media="all" href="lib/tau/wearable/theme/default/tau.circle.css">
</head>
<body> 
...
<script src="js/app.js"></script>
<script src="lib/tau/animation/tau.animation.min.js"></script>
</body>
@dzolnai
dzolnai / AdobeLocationFramework.cs
Last active May 31, 2019 12:16
Get Adobe Analytics library working on Unity
//
// Copyright (c) 2017 eppz! mobile, Gergely Borbás (SP)
//
// http://www.twitter.com/_eppz
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
val recognizerIntent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM)
// Prefer dutch language for recognition
recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "nl-NL")
// Display text for the user as hint until results are available (only in overlay mode)
recognizerIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Speak to search...")
// Accept partial results if they come
recognizerIntent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true)