View "injection" library for Android.

Related tags

Kotlin kotterknife
Overview

Kotter Knife

Deprecated: This was a terrible idea because it allocates an object for every view reference. Do not use, and do not use anything like it. Use view binding instead.

Butter Knife-esque view binding for Kotlin.

public class PersonView(context: Context, attrs: AttributeSet?) : LinearLayout(context, attrs) {
  val firstName: TextView by bindView(R.id.first_name)
  val lastName: TextView by bindView(R.id.last_name)

  // Optional binding.
  val details: TextView? by bindOptionalView(R.id.details)

  // List binding.
  val nameViews: List<TextView> by bindViews(R.id.first_name, R.id.last_name)

  // List binding with optional items being omitted.
  val nameViews: List<TextView> by bindOptionalViews(R.id.first_name, R.id.middle_name, R.id.last_name)
}

These methods are available on subclasses of Activity, Dialog, ViewGroup, Fragment, the support library Fragment, and recycler view's ViewHolder.

Download

Currently not available via Maven Central.

A SNAPSHOT is available in the Sonatype snapshot repo.

compile 'com.jakewharton:kotterknife:0.1.0-SNAPSHOT'

You can also copy ButterKnife.kt into your source tree. The file depends on the 'support-v4' and 'recyclerview-v7' libraries but the dependency is easily removed by deleting a few lines.

Comments, suggestions, and pull requests are encouraged!

License

Copyright 2014 Jake Wharton

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • Generate less classes

    Generate less classes

    Discovered that my previous change to eliminate reflection led to an abundance of generated classes. For the combination of the 6 targets and the 4 method types there were 24 classes generated where most were really duplicates.

    Here is a patch that corrects that and reduces those 24 down to 6

    diff --git a/src/main/kotlin/butterknife/ButterKnife.kt b/src/main/kotlin/butterknife/ButterKnife.kt
    index 947b824..5611c25 100644
    --- a/src/main/kotlin/butterknife/ButterKnife.kt
    +++ b/src/main/kotlin/butterknife/ButterKnife.kt
    @@ -9,60 +9,69 @@ import android.view.View
     import kotlin.properties.ReadOnlyProperty
    
     public fun <V : View> View.bindView(id: Int)
    -    : ReadOnlyProperty<View, V> = required(id, ::findViewById)
    +    : ReadOnlyProperty<View, V> = required(id, viewFinder)
     public fun <V : View> Activity.bindView(id: Int)
    -    : ReadOnlyProperty<Activity, V> = required(id, ::findViewById)
    +    : ReadOnlyProperty<Activity, V> = required(id, viewFinder)
     public fun <V : View> Dialog.bindView(id: Int)
    -    : ReadOnlyProperty<Dialog, V> = required(id, ::findViewById)
    +    : ReadOnlyProperty<Dialog, V> = required(id, viewFinder)
     public fun <V : View> Fragment.bindView(id: Int)
    -    : ReadOnlyProperty<Fragment, V> = required(id, ::findViewById)
    +    : ReadOnlyProperty<Fragment, V> = required(id, viewFinder)
     public fun <V : View> SupportFragment.bindView(id: Int)
    -    : ReadOnlyProperty<SupportFragment, V> = required(id, ::findViewById)
    +    : ReadOnlyProperty<SupportFragment, V> = required(id, viewFinder)
     public fun <V : View> ViewHolder.bindView(id: Int)
    -    : ReadOnlyProperty<ViewHolder, V> = required(id, ::findViewById)
    +    : ReadOnlyProperty<ViewHolder, V> = required(id, viewFinder)
    
     public fun <V : View> View.bindOptionalView(id: Int)
    -    : ReadOnlyProperty<View, V?> = optional(id, ::findViewById)
    +    : ReadOnlyProperty<View, V?> = optional(id, viewFinder)
     public fun <V : View> Activity.bindOptionalView(id: Int)
    -    : ReadOnlyProperty<Activity, V?> = optional(id, ::findViewById)
    +    : ReadOnlyProperty<Activity, V?> = optional(id, viewFinder)
     public fun <V : View> Dialog.bindOptionalView(id: Int)
    -    : ReadOnlyProperty<Dialog, V?> = optional(id, ::findViewById)
    +    : ReadOnlyProperty<Dialog, V?> = optional(id, viewFinder)
     public fun <V : View> Fragment.bindOptionalView(id: Int)
    -    : ReadOnlyProperty<Fragment, V?> = optional(id, ::findViewById)
    +    : ReadOnlyProperty<Fragment, V?> = optional(id, viewFinder)
     public fun <V : View> SupportFragment.bindOptionalView(id: Int)
    -    : ReadOnlyProperty<SupportFragment, V?> = optional(id, ::findViewById)
    +    : ReadOnlyProperty<SupportFragment, V?> = optional(id, viewFinder)
     public fun <V : View> ViewHolder.bindOptionalView(id: Int)
    -    : ReadOnlyProperty<ViewHolder, V?> = optional(id, ::findViewById)
    +    : ReadOnlyProperty<ViewHolder, V?> = optional(id, viewFinder)
    
     public fun <V : View> View.bindViews(vararg ids: Int)
    -    : ReadOnlyProperty<View, List<V>> = required(ids, ::findViewById)
    +    : ReadOnlyProperty<View, List<V>> = required(ids, viewFinder)
     public fun <V : View> Activity.bindViews(vararg ids: Int)
    -    : ReadOnlyProperty<Activity, List<V>> = required(ids, ::findViewById)
    +    : ReadOnlyProperty<Activity, List<V>> = required(ids, viewFinder)
     public fun <V : View> Dialog.bindViews(vararg ids: Int)
    -    : ReadOnlyProperty<Dialog, List<V>> = required(ids, ::findViewById)
    +    : ReadOnlyProperty<Dialog, List<V>> = required(ids, viewFinder)
     public fun <V : View> Fragment.bindViews(vararg ids: Int)
    -    : ReadOnlyProperty<Fragment, List<V>> = required(ids, ::findViewById)
    +    : ReadOnlyProperty<Fragment, List<V>> = required(ids, viewFinder)
     public fun <V : View> SupportFragment.bindViews(vararg ids: Int)
    -    : ReadOnlyProperty<SupportFragment, List<V>> = required(ids, ::findViewById)
    +    : ReadOnlyProperty<SupportFragment, List<V>> = required(ids, viewFinder)
     public fun <V : View> ViewHolder.bindViews(vararg ids: Int)
    -    : ReadOnlyProperty<ViewHolder, List<V>> = required(ids, ::findViewById)
    +    : ReadOnlyProperty<ViewHolder, List<V>> = required(ids, viewFinder)
    
     public fun <V : View> View.bindOptionalViews(vararg ids: Int)
    -    : ReadOnlyProperty<View, List<V>> = optional(ids, ::findViewById)
    +    : ReadOnlyProperty<View, List<V>> = optional(ids, viewFinder)
     public fun <V : View> Activity.bindOptionalViews(vararg ids: Int)
    -    : ReadOnlyProperty<Activity, List<V>> = optional(ids, ::findViewById)
    +    : ReadOnlyProperty<Activity, List<V>> = optional(ids, viewFinder)
     public fun <V : View> Dialog.bindOptionalViews(vararg ids: Int)
    -    : ReadOnlyProperty<Dialog, List<V>> = optional(ids, ::findViewById)
    +    : ReadOnlyProperty<Dialog, List<V>> = optional(ids, viewFinder)
     public fun <V : View> Fragment.bindOptionalViews(vararg ids: Int)
    -    : ReadOnlyProperty<Fragment, List<V>> = optional(ids, ::findViewById)
    +    : ReadOnlyProperty<Fragment, List<V>> = optional(ids, viewFinder)
     public fun <V : View> SupportFragment.bindOptionalViews(vararg ids: Int)
    -    : ReadOnlyProperty<SupportFragment, List<V>> = optional(ids, ::findViewById)
    +    : ReadOnlyProperty<SupportFragment, List<V>> = optional(ids, viewFinder)
     public fun <V : View> ViewHolder.bindOptionalViews(vararg ids: Int)
    -    : ReadOnlyProperty<ViewHolder, List<V>> = optional(ids, ::findViewById)
    +    : ReadOnlyProperty<ViewHolder, List<V>> = optional(ids, viewFinder)
    
    -private fun Fragment.findViewById(id: Int): View? = getView().findViewById(id)
    -private fun SupportFragment.findViewById(id: Int): View? = getView().findViewById(id)
    -private fun ViewHolder.findViewById(id: Int): View? = itemView.findViewById(id)
    +private val View.viewFinder: View.(Int) -> View?
    +    get() = View::findViewById
    +private val Activity.viewFinder: Activity.(Int) -> View?
    +    get() = Activity::findViewById
    +private val Dialog.viewFinder: Dialog.(Int) -> View?
    +    get() = Dialog::findViewById
    +private val Fragment.viewFinder: Fragment.(Int) -> View?
    +    get() = { getView().findViewById(it) }
    +private val SupportFragment.viewFinder: SupportFragment.(Int) -> View?
    +    get() = { getView().findViewById(it) }
    +private val ViewHolder.viewFinder: ViewHolder.(Int) -> View?
    +    get() = { itemView.findViewById(it) }
    
     private fun viewNotFound(id:Int, desc: PropertyMetadata) =
         throw IllegalStateException("View ID $id for '${desc.name}' not found.")
    
    opened by dalewking 6
  • failed to resolve: com.jakewharton:kotterknife:0.1.0-SNAPSHOT

    failed to resolve: com.jakewharton:kotterknife:0.1.0-SNAPSHOT

    when I add compile 'com.jakewharton:kotterknife:0.1.0-SNAPSHOT' to my gradle file,it didn't work and show failed to resolve: com.jakewharton:kotterknife:0.1.0-SNAPSHOT message.This is my build.gredle file. apply plugin: 'com.android.application' apply plugin: 'kotlin-android'

    android { compileSdkVersion 22 buildToolsVersion "23.0.0 rc2"

    defaultConfig {
        applicationId "jien.kotlinandroid"
        minSdkVersion 16
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    sourceSets {
    

    // main.java.srcDirs += 'src/main/kotlin' debug.java.srcDirs += 'src/main/kotlin' } }

    dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:22.2.0' compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile 'com.jakewharton:kotterknife:0.1.0-SNAPSHOT' compile 'com.android.support:recyclerview-v7:22.2.0' }

    buildscript { ext.kotlin_version = '0.12.200' repositories { mavenCentral() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } repositories { mavenCentral() }

    opened by jien 6
  • Binding with source

    Binding with source

    Added delegates for binding with source other than this. With this change you can reproduce behavior of Butterknife for list adapters (should solve #9).

    public class MyAdapter(val context: Context) : BaseAdapter() {
      override fun getView(position: Int, view: View?, parent: ViewGroup): View? {
        var view = view ?: inflater.inflate(R.layout.whatever, parent, false)
        val holder: ViewHolder = view.getTag() as? ViewHolder ?: ViewHolder(view)
        view.setTag(holder)
    
        holder.name.setText("John Doe")
        // etc...
    
        return view
      }
    
      class ViewHolder(view: View) {
        val name: TextView by bindView(view, R.id.title)
        val jobTitle: TextView by bindView(view, R.id.job_title)
      }
    }
    
    
    opened by piotrdubiel 3
  • error with suport libraries.

    error with suport libraries.

    there is en error when I use kotterknife in my project: "All com.android.support libraries must use the exact same version specification (mixing versions can lead to runtime crashes). Found versions 26.0.2, 25.4.0. Examples include com.android.support:recyclerview-v7:26.0.2 and com.android.support:animated-vector-drawable:25.4.0” My project just use 25.4.0 support libraries. If I remove kotterknife, there is no problem.

    opened by weijinhuang 2
  • Remove unnecessary public modifiers

    Remove unnecessary public modifiers

    @JakeWharton This PR removes unnecessary boilerplate—all Kotlin symbols are public by default:

    If you do not specify any visibility modifier, public is used by default, which means that your declarations will be visible everywhere

    opened by SUPERCILEX 2
  • Clean up and add caching

    Clean up and add caching

    @JakeWharton Taken from https://github.com/JakeWharton/butterknife/blob/master/.travis.yml#L3 and https://github.com/JakeWharton/butterknife/pull/1052

    opened by jaredsburrows 2
  • Will @OnClick be added?

    Will @OnClick be added?

    Annotations from Butterknife like @OnClick or @OnItemLongClick are not added in Kotterknife. Is this in the road map? Although view.setOnClickListener{...} from Kotlin is pretty clean, but it would be great if we can have the same code style like Butterknife.

    opened by taingmeng1 2
  • bindView doesn't work with CheckBox

    bindView doesn't work with CheckBox

    This is the error given by the compiler:

    Missing setValue(MyActivity.kotlin.reflect.KProperty<*>,android.widget.Checkbox) method on delegate of type kotlin.properties.ReadOnlyProperty<android.app.Activity, android.widget.Checkbox>

    opened by jibbo 2
  • Why does't upload kotterknife to Maven Central ?

    Why does't upload kotterknife to Maven Central ?

    Hello, Jake. I love Kotlin and kotterknife.

    Today, I has not be able to compile my Android project because kotterknife uses Kotlin RC.

    +--- com.jakewharton:kotterknife:0.1.0-SNAPSHOT
    |    +--- com.android.support:support-v4:23.1.1 (*)
    |    +--- com.android.support:recyclerview-v7:23.1.1
    |    |    +--- com.android.support:support-annotations:23.1.1 -> 23.1.0
    |    |    \--- com.android.support:support-v4:23.1.1 (*)
    |    \--- org.jetbrains.kotlin:kotlin-stdlib:1.0.0-rc-1036 (*)
    

    My project is used Kotlin beta 3 in production environment, so I was troubled very much. Could you release kotterknife, and upload to Maven Central ?

    Thank you.

    opened by pine 2
  • Update to Kotlin M14

    Update to Kotlin M14

    This PR updates the Kotlin version used by kotterknife to the newly released M14.

    At a first glance, the only thing that should be addressed is the use of the operator modifier[1][2] in the get method of the Lazy class. I am not sure that is the intended use case for that method, so I decided not to include that change in this PR.

    [1] : http://blog.jetbrains.com/kotlin/2015/10/kotlin-m14-is-out/ [2] : http://blog.jetbrains.com/kotlin/2015/09/call-for-feedback-upcoming-changes-in-kotlin/

    opened by mrz 2
  • Kotterknife refactoring

    Kotterknife refactoring

    Refactoring of the internal workings of Kotterknife with the goal of:

    • Eliminate run time reflection
    • Reduce runtime heap demands (go from 2 class instances per delegation to 1)
    • Reduce number of classes defined
    • Make it more functional

    I purposefully used many small commits to make it easier to review by reviewing each step of the transformation one at a time.

    opened by dalewking 2
  • bindView does not work perfectly with fragment withing viewpager

    bindView does not work perfectly with fragment withing viewpager

    I've viewpager with 5 fragments one of the fragment has recyclerView private val recyclerView : RecyclerView by bindView(R.id.list)

    It works find once it first appears but one I move to other fragment and return to the fragment that has list, the list does not appear and I get recyclerview No adapter attached; skipping layout I switch to regular view.findViewById(). the issue has been resolve.

    it looks bindView does not bind to fragment's view or something

    opened by MuBoori 1
  • DialogFragment use

    DialogFragment use

    Point 1 Kotterknife behaves in a way that if DialogFragment.getDialog() != null, it will use getDialog().findViewById() or if a getDialog() == null it will attempt getView().findViewById()

    The FragmentManager calls getLayoutInflater before onCreateView, and in a DialogFragment onCreateDialog is called as part of getLayoutInflater, therefore there is no point at which a View will exist when a Dialog doesn't.

    So I recommend perhaps removing the fallback as to not confuse developers looking at the source.

    Point 2

    The view created in onCreateView is not set to the dialog until onActivityCreated. Therefore if a behaviour of initialising the view state in onViewCreated is taken then a crash is guaranteed.

    There doesn't seem to be a great way of knowing if Dialog.setContentView or FragmentonActivityCreated was called so perhaps this detail should be added to documentation?

    --

    I'll make a PR later, but wanted to see if this was agreeable or I'm misunderstanding why I was running into issues.

    opened by kassim 0
  • Problem with SNAPSHOT

    Problem with SNAPSHOT

    Hi Jake,

    Yesterday you updated kotterknife. For some reason we got Unresolved reference: bindView.

    We tried exclude groups for kotlin and support libs(we still using 25.4.0), but problem was still persisted. (Maybe binary compatibility or what)

    Can you please try avoid of using snapshot without stable build? from "com.jakewharton:kotterknife:0.1.0-SNAPSHOT" to something like "com.jakewharton:kotterknife:0.1.1" , ... etc?

    We did alternative solution for now: Uploaded to artifactory old library with different group name to work with ours builds. Thanks

    opened by hanibalsk 2
  • Failed to resolve

    Failed to resolve

    Hi I added sonatype dependency like this

    repositories {
        maven {
            url "https://oss.sonatype.org/content/repositories/snapshots"
        }
    }
    

    and compile 'com.jakewharton:kotterknife:0.1.0-SNAPSHOT'

    to the app gradle.

    But I still got Error:(39, 13) Failed to resolve: com.jakewharton:kotterknife:0.1.0-SNAPSHOT

    Can someone help me with it?

    opened by xiaogegexiao 1
  • Error when included in project with butterknife

    Error when included in project with butterknife

    in an app I'm slowly moving over to kotlin in Build.gradle I add in:

     kapt 'com.jakewharton:butterknife-compiler:8.5.1'
      compile 'com.jakewharton:butterknife:8.5.1'
      compile 'com.jakewharton:kotterknife:0.1.0-SNAPSHOT'
    

    When I Build it fails with:

    Error:Error converting bytecode to dex:
    Cause: com.android.dex.DexException: Multiple dex files define Lbutterknife/BuildConfig;
    Error:com.android.dex.DexException: Multiple dex files define Lbutterknife/BuildConfig;
    Error:	at com.android.dx.merge.DexMerger.readSortableTypes(DexMerger.java:608)
    Error:	at com.android.dx.merge.DexMerger.getSortedTypes(DexMerger.java:563)
    Error:	at com.android.dx.merge.DexMerger.mergeClassDefs(DexMerger.java:545)
    Error:	at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:167)
    Error:	at com.android.dx.merge.DexMerger.merge(DexMerger.java:194)
    Error:	at com.android.builder.dexing.DexArchiveMergerCallable.mergeDexes(DexArchiveMergerCallable.java:66)
    Error:	at com.android.builder.dexing.DexArchiveMergerCallable.call(DexArchiveMergerCallable.java:54)
    Error:	at com.android.builder.dexing.DexArchiveMergerCallable.call(DexArchiveMergerCallable.java:37)
    Error:	at java.util.concurrent.ForkJoinTask$AdaptedCallable.exec(ForkJoinTask.java:1424)
    Error:	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
    Error:	at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
    Error:	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
    Error:	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
    Error:Execution failed for task ':app:transformDexArchiveWithDexMergerForDebug'.
    > com.android.build.api.transform.TransformException: com.android.dex.DexException: Multiple dex files define Lbutterknife/BuildConfig;
    
    opened by RoryKelly 6
Owner
Jake Wharton
Jake Wharton
Lightweight Kotlin DSL dependency injection library

Warehouse DSL Warehouse is a lightweight Kotlin DSL dependency injection library this library has an extremely faster learning curve and more human fr

Osama Raddad 18 Jul 17, 2022
Dependency Injection library for Compose Multiplatform, Koin wrapper.

?? Cokoin Injection library for Compose (Multiplatform and Jetpack), Koin wrapper. It uses @Composable functions to configure KoinContext and Scopes.

Bruno Wieczorek 57 Dec 29, 2022
🍭 GithubSearchKMM - Github Repos Search - Android - iOS - Kotlin Multiplatform Mobile using Jetpack Compose, SwiftUI, FlowRedux, Coroutines Flow, Dagger Hilt, Koin Dependency Injection, shared KMP ViewModel, Clean Architecture

GithubSearchKMM Github Repos Search - Kotlin Multiplatform Mobile using Jetpack Compose, SwiftUI, FlowRedux, Coroutines Flow, Dagger Hilt, Koin Depend

Petrus Nguyễn Thái Học 50 Jan 7, 2023
Boilerplate code for implementing MVVM in Android using Jetpack libraries, coroutines, dependency injection and local persistance

MVVM Foundation This projects aims to speed up development of Android apps by providing a solid base to extend Libraries Jetpack Fragment Material3 :

Gabriel Gonzalez 2 Nov 10, 2022
Built with Jetpack compose, multi modules MVVM clean architecture, coroutines + flow, dependency injection, jetpack navigation and other jetpack components

RickAndMortyCompose - Work in progress A simple app using Jetpack compose, clean architecture, multi modules, coroutines + flows, dependency injection

Daniel Waiguru 9 Jul 13, 2022
Automatic CoroutineDispatcher injection and extensions for kotlinx.coroutines

Dispatch Utilities for kotlinx.coroutines which make them type-safe, easier to test, and more expressive. Use the predefined types and factories or de

Rick Busarow 132 Dec 9, 2022
A injection minecraft cheat using jvm attach api

Luminous A injection minecraft cheat using jvm attach api Website: https://lumi.getfdp.today Build We used a thing called Wrapper to make development

null 24 Dec 21, 2022
Blinking-image-view - A variant of Android View that blinks only the source image (not the background)

Blinker View for Android What is this? Blinker View is an Android View that blinks a given drawable. Yes, it's that simple. Place it in your layout an

Milos Marinkovic 4 Jul 29, 2020
A library for creating dynamic skeleton view

Skeleton Placeholder View Overview A Library designed to draw a Skeleton by "skinning" the view from a provided layout. Skeleton is composed of Bone w

Ferry Irawan 25 Jul 20, 2021
A library for otp view with gradient and lines

AndroidOtpView (With gradient color in lines) Preview Otp View library for Android Getting started Add it in your root build.gradle at the end of repo

Poonam Parth 19 Feb 14, 2022
Android sliding panel that is part of the view hierarchy, not above it.

sliding-panel A ViewGroup that implements a sliding panel that is part of the view hierarchy, not above it. Difference from other libraries All other

Pierfrancesco Soffritti 441 Nov 12, 2022
🍞 The ultimate breadcrumbs view for Android!

KrumbsView The ultimate breadcrumbs view for Android! Inspired by JotterPad's breadcrumbs. Features: Custom typeface (from /assets and /res/font folde

Adriel Café 179 Dec 9, 2022
:speedboat: Floating navigation view for displaying a list of items dynamically on Android.

Submarine Fully customizable floating navigation view for listing items dynamically on Android. Including in your project Gradle Add below codes to yo

Jaewoong Eum 460 Dec 21, 2022
Android View Lifecycle Extensions

Android View Lifecycle Extensions Extensions for Android View class that let you access a view lifecycle without having to create a custom view (exten

Thomas Gorisse 22 Dec 6, 2022
A simple project that describes the relationship between the view and it's viewmodel in android development

View-ViewModel-Communication A simple project that describes the relationship between the view and it's viewmodel in android development In MVVM archi

Segun Francis 1 Nov 6, 2021
Custom Sneaker view for Android.

SneakerView How to install ? You can add the library to your project using jitpack.io. Add the code below to your project's settings.gradle file. all

Osman Gül 3 Aug 26, 2022
ZoomHelper will make any view to be zoomable just like Instagram pinch-to-zoom

ZoomHelper ZoomHelper will make any view to be zoomable just like the Instagram pinch-to-zoom. ?? Installation ZoomHelper is available in the JCenter,

AmirHosseinAghajari 238 Dec 25, 2022
Arc Layout is a view group with which you can add a arc-shaped container in your layout.

ArcLayout Arc Layout is a view group with which you can add a arc-shaped container in your layout. Two main variables are the direction and the curvat

Ali Rezaiyan 32 Aug 17, 2022
A simple and easy adapter for RecyclerView. You don't have to make adapters and view holders anymore. Slush will help you.

한국어 No more boilerplate adapters and view holders. Slush will make using RecyclerView easy and fast. The goal of this project is to make RecyclerView,

SeungHyun 26 Sep 13, 2022