Git Product home page Git Product logo

ibrahimyilmaz / kiel Goto Github PK

View Code? Open in Web Editor NEW
370.0 10.0 30.0 323 KB

(Published to MavenCentral) Kotlin way of building RecyclerView Adapter ๐Ÿงฉ. You do not have to write RecyclerView Adapters again and again and suffer from handling of different view types. Kiel will help you.

License: Apache License 2.0

Kotlin 100.00%
recyclerview recyclerview-adapter viewholder visitor-pattern kotlin kotlin-android android-library kiel

kiel's Issues

[kiel]: Make `PagingDataAdapter` composable

As an Android Developer, we would like to able to use Kiel with PagingDataAdapter . With this we may utilize the power of Paging 3.

https://developer.android.com/topic/libraries/architecture/paging/v3-overview
https://developer.android.com/reference/kotlin/androidx/paging/PagingDataAdapter

syntax would be:

val adapter =pagingAdapter<Type>{
diffUtil{...}
register{...}
}

adapter.submitData(...)

In addition to this, it will be nice to have an example in the samples project.

[question] Use setHasFixedSize list will not be displayed

@ibrahimyilmaz If the RecyclerView layout uses wrap_content instead of match_parent and setHasFixedSize = true, the list will not be displayed.

activity_country_indonesia.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/app_bar_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" / "wrap_content"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        tools:listitem="@layout/item_task_detail" />

</LinearLayout>

CountryIndonesiaActivity.kt

class CountryIndonesiaActivity : BaseActivity() {
    private val viewModel by viewModel<CountryIndonesiaViewModel>()
    private lateinit var binding: ActivityCountryIndonesiaBinding
    private val viewAdapter by lazy { createAdapter(::onItemClicked) }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityCountryIndonesiaBinding.inflate(layoutInflater)
        setContentView(binding.root)
        setupActionBarWithBackButton(binding.toolbar)
        initView()

        viewModel.loadData()
    }

    private fun initView() {
        with(binding.recyclerView) {
            adapter = viewAdapter
            setHasFixedSize(true)
        }
    }

    override fun observeChange() {
        observe(viewModel.items, ::onDataLoaded)
        observe(viewModel.toastMessage, ::showSnackbarMessage)
    }

    private fun onDataLoaded(items: List<BaseViewItem>) {
        viewAdapter.submitList(items)
    }


    private fun onItemClicked(viewItem: BaseViewItem, view: View) {
        when (viewItem) {
            is DailyItem -> {

            }
            is TextItem -> {
                DailyGraphActivity.startActivity(this)
            }
        }
    }

    companion object {
        @JvmStatic
        fun startActivity(context: Context?) =
            context?.startActivity(Intent(context, CountryIndonesiaActivity::class.java))
    }
}

This question can be through kotlin-mvvm-covid19 project test.

[kiel] : Support HasStableId in adapterOf

In order to set hasStableId, we may pass lambda or interface to RecyclerViewAdapter to override getItemId.

When it is passed, RecyclerViewAdapter use it,
When it is not passed, RecyclerViewAdapter default super.getItemId()

Aim is to make it composable also:

syntax would be:

val adapter =adapterOf<Type>{
         itemId{ t.getId() }
         ....
}

[kiel] Create alternative methods for register , where layoutResource is passed as a value, and then wrapped into a function type.

Create alternative methods for register , where layoutResource is passed as a value, and then wrapped into a function type.

This

register(
    type = Text::class.java
    layoutResource = { R.layout.adapter_message_text_item }
    viewHolder = { ::TextMessageViewHolder }
    onViewHolderBound = { vh, _, it ->
        vh.messageText.text = it.text
        vh.sentAt.text = it.sentAt
    }
)

would become this:
Kotlin

register(
    type = Text::class.java
    layoutResource = R.layout.adapter_message_text_item
    viewHolder = { ::TextMessageViewHolder }
    onViewHolderBound = { vh, _, it ->
        vh.messageText.text = it.text
        vh.sentAt.text = it.sentAt
    }
)

With:

fun register(layoutResourceProvider: () -> Int) {
    // use layoutResourceProvider
}

fun register(layoutResource: Int) = register(
    layoutResourceProvider = { layoutResource }
)

[kiel] Avoid using Builder Classes.

in general we try to avoid builder classes in Kotlin, as they're not needed and introduce nullability.
So considernig this:
Kotlin

register {
    type { Text::class.java }
    layoutResource { R.layout.adapter_message_text_item }
    viewHolder { ::TextMessageViewHolder }
    onViewHolderBound<Text, TextMessageViewHolder> { vh, _, it ->
        vh.messageText.text = it.text
        vh.sentAt.text = it.sentAt
    }
}

Could look like this:
Kotlin

register(
    type = Text::class.java
    layoutResource = { R.layout.adapter_message_text_item }
    viewHolder = { ::TextMessageViewHolder }
    onViewHolderBound = { vh, _, it ->
        vh.messageText.text = it.text
        vh.sentAt.text = it.sentAt
    }
)

[samples] : Create example with long/normal click listeners

I got this feedback from reddit:

Need example with long/normal click listeners + per-view-id click tracking 
(in case if item has "favorite" and "delete" buttons for example).

It will be great to show an example how to deal with click events. With an example, README may also be improved.

[kiel] Drop Jetifier

FEATURE REQUEST

Hi! Thank you for making Kiel! I've played with it for some time now and I want to use it in our project but this issue is we are trying to reduce build time by dropping jetifier.

We found out by dropping jetifier we can reduce a significant amount of build time. thank you!

Describe the solution you'd like

I've forked your project and dropped jetifier, test it and it works! I just disabled the app module because of some conflicts. Anyway it's working fine in my test project.

 implementation 'com.github.raquezha:kiel:1.2.1-beta'

Describe alternatives you've considered

I hope you consider this feature request

Additional context

  1. Adam Bennet's Article about droping jetifier: https://adambennett.dev/2020/08/disabling-jetifier/
  2. Can I Drop Jetifier Repo: https://github.com/plnice/can-i-drop-jetifier

[kiel] : Make ListAdapter Composable

As an Android Developer, we would like to able to use Kiel with ListAdapter .

syntax would be:

val adapter =listAdapter<...>{
diffUtil{...}
register{...}
}

In addition to this, it will be nice to have an example in the samples project.

Composable Diff improvements

#40 added syntax to define Diff callback for whole adapter. But you still have no ability to define diff callback for register blocks separately.

There is example of how it may look like:

adapterOf<Animal> {
    register(
        layoutResource = R.layout.item_cat,
        viewHolder = ::CatHolder,
        diff = diff(
            areItemsTheSame = { cat1, cat2 -> cat1.name == cat2.name }
        )
    )

    register(
        layoutResource = R.layout.item_dog,
        viewHolder = ::DogHolder,
        diff = diff(
            areItemsTheSame = { dog1, dog2 -> dog1.bark == dog2.bark }
        )
    )
}

This builder under the hood should create single DiffUtil.Callback with multiple "delegates": one for Cat, one for Dog. Then, when DiffUtil.Callback methods are called, that Callback must pick appropriate "delegate" and call it

how to define viewTypes with conditions

now we can register viewTypes but README has no way to determine which viewType is created at spefici position i.e
how to make views has two types Head, Sub

  • Head with odd positions
  • Sub with even positions

[kiel] - Consider new syntax alternatives.

consider the syntax alternatives like that(there can be some alternatives like kluent!):

adapterOf<Something> {
    register {
        type = Text::class.java
        layoutResource { R.layout.adapter_message_text_item }
        // ..
    }
}

And could look like this:

adapterOf<Something> {
    register(Text::class.java) {
        layoutResource { R.layout.adapter_message_text_item }
        // ..
    }
}
adapterOf<Something> {
    Text::class.java.register {
        layoutResource { R.layout.adapter_message_text_item }
        // ..
    }
}

[kiel] Implement Unit Test for `RecyclerViewAdapter`

During the implementation of RecyclerViewListAdapter, implementing getViewType method somehow was missed.
Robolectric or Android Instrumentation test it does not matter, it will be nice to have unit tests for Adapters.

[kiel] Support for load more functions

Hi there,
RecyclerView usually have to handle a large amount of data, I think it really need to add support for load more functions.
What do you think?

[kiel] Check and make internal non-public entities

As a feedback by Gabor Varadi,

Most classes and typealiases seem to be
 default visibility, which is public. But the library
 should try to minimize this and make 
non public things internal

We should make internal kiel's non public entities.

Improve Readme to make Kiel more accessible.

As a developer, we would like to understand :

  • How we can use Kiel better
  • How we can use DataBinding with Kiel
  • How we can use ViewBinding with Kiel
    So Readme can be improved.

Any idea or support is welcome

Add "import" information in README

Hi,
I just tried out your library and I have to say: Awesome!
I WILL use it in my projects from now on.

But it seems like adapterOf does not get imported automatically, so I had to search for the import in the sample app.
Maybe you should add the note to the README that you need the import import me.ibrahimyilmaz.kiel.adapter.RecyclerViewAdapter.Companion.adapterOf like in the Download section.

Greetings!

[kiel] : Make DiffUtil usage composable too

I got this comment from Reddit:

Suggestion: make DiffUtil usage composable too :)
Look: RecyclerView.Adapter and DiffUtil.Callback are very similar! Adapter is responsible for converting item of ANY type into view, Callback is responsible for comparing items of ANY types with each other.
You noticed, that Adapter become much easier to use if you separate each recycler type and allow to compose them together inside one adapter. But DiffUtil.Callback is the same โ€” if you make it composable, it will reduce much of boilerplate code.
I suggest you to add areItemsTheSame and areContentsTheSame methods right inside your register DSL. I have written very similar library a year or two ago - and it works great in our team 

syntax would be :

recyclerView.adapter = adapterOf<Type>{
   diffUtil{
          areItemsTheSame{ old, new -> old.id == new.id }
          content{ old, new -> old == new }
          changePayload{ old, new -> }
     }
    ....
 }

This is

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.