Skip to content

Commit

Permalink
Merge pull request #97 from AlanCheen/feature/dsl
Browse files Browse the repository at this point in the history
Feature/dsl
  • Loading branch information
AlanCheen authored Aug 9, 2022
2 parents 27f70cc + 2ebe316 commit f65809f
Show file tree
Hide file tree
Showing 14 changed files with 289 additions and 66 deletions.
3 changes: 0 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ PRs welcome.
- 🐎 `:racehorse:` when improving performance
- 🚱 `:non-potable_water:` when plugging memory leaks
- 📝 `:memo:` when writing docs
- 🐧 `:penguin:` when fixing something on Linux
- 🍎 `:apple:` when fixing something on macOS
- 🏁 `:checkered_flag:` when fixing something on Windows
- 🐛 `:bug:` when fixing a bug
- 🔥 `:fire:` when removing code or files
- 💚 `:green_heart:` when fixing the CI build
Expand Down
37 changes: 37 additions & 0 deletions app/src/main/java/me/yifeiyuan/flapdev/GitHubDemoFragment.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package me.yifeiyuan.flapdev

import android.view.View
import me.yifeiyuan.flap.delegate.makeDelegate
import me.yifeiyuan.flap.ext.bindTextView
import me.yifeiyuan.flapdev.components.SimpleTextModel
import me.yifeiyuan.flapdev.showcase.BaseTestcaseFragment

/**
* GitHub 代码示例
*
* Created by 程序亦非猿 on 2022/8/9.
*/
class GitHubDemoFragment : BaseTestcaseFragment() {

override fun onInit(view: View) {
super.onInit(view)

val simpleTextDelegate = makeDelegate<SimpleTextModel>(R.layout.flap_item_simple_text) {
onBind { model ->
bindTextView(R.id.tv_content) {
text = model.content
}
}
}

adapter.registerAdapterDelegate(simpleTextDelegate)

val dataList = ArrayList<Any>()

dataList.add(SimpleTextModel("Android"))
dataList.add(SimpleTextModel("Java"))
dataList.add(SimpleTextModel("Kotlin"))

adapter.setData(dataList)
}
}
5 changes: 4 additions & 1 deletion app/src/main/java/me/yifeiyuan/flapdev/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,10 @@ class MainActivity : AppCompatActivity() {
subtitle = "LayoutAdapterDelegate DSL"
replace(LayoutDelegateDSLTestcase::class.java)
}

R.id.nav_github_demo -> {
subtitle = "GitHub Demo"
replace(GitHubDemoFragment::class.java)
}
}
drawerLayout.close()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ open class BaseTestcaseFragment : Fragment(), Scrollable {
emptyView = view.findViewById(R.id.emptyView)
recyclerView = view.findViewById(R.id.recyclerView)
adapter = createAdapter()
adapter.setLifecycleOwner(viewLifecycleOwner)

adapter.setEmptyView(emptyView)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,17 @@ class LayoutDelegateDSLTestcase : BaseTestcaseFragment() {
}
}

onClick { model, position ->
onBind { model, position, payloads, adapter ->
bindTextView(R.id.tv_content) {
text = model.content
}
}

onClick { model, position, adapter ->
toast("onClick() called with: component = $this, model = $model, position = $position")
}

onLongClick { model, position ->
onLongClick { model, position, adapter ->
toast("onLongClick() called with: component = $this, model = $model, position = $position")
true
}
Expand All @@ -44,6 +50,31 @@ class LayoutDelegateDSLTestcase : BaseTestcaseFragment() {
onViewDetachedFromWindow {
Log.d(TAG, "simpleTextDelegate onViewDetachedFromWindow() called $position")
}

onViewRecycled {
Log.d(TAG, "onViewRecycled() called")
}

onFailedToRecycleView {
Log.d(TAG, "onFailedToRecycleView() called")
false
}

onResume {
Log.d(TAG, "simpleTextDelegate onResume() called")
}

onPause {
Log.d(TAG, "simpleTextDelegate onPause() called")
}

onStop {
Log.d(TAG, "simpleTextDelegate onStop() called")
}

onDestroy {
Log.d(TAG, "simpleTextDelegate onDestroy() called")
}
}

val testAllDelegate = makeDelegate<TestAllModel>(R.layout.component_test_all_feature) {
Expand All @@ -56,11 +87,11 @@ class LayoutDelegateDSLTestcase : BaseTestcaseFragment() {
}
}

onClick { model, position ->
onClick { model, position, adapter ->
toast("onClick() called with: component = $this, model = $model, position = $position")
}

onLongClick { model, position ->
onLongClick { model, position, adapter ->
toast("onLongClick() called with: component = $this, model = $model, position = $position")
true
}
Expand All @@ -72,6 +103,22 @@ class LayoutDelegateDSLTestcase : BaseTestcaseFragment() {
onViewDetachedFromWindow {
Log.d(TAG, "testAllDelegate onViewDetachedFromWindow() called $position")
}

onViewRecycled {

}

onFailedToRecycleView {
false
}

onResume {
Log.d(TAG, "testAllDelegate onResume() called")
}

onPause {
Log.d(TAG, "testAllDelegate onPause() called")
}
}

adapter.registerAdapterDelegates(simpleTextDelegate, testAllDelegate)
Expand Down
5 changes: 4 additions & 1 deletion app/src/main/res/menu/activity_main_drawer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@
android:id="@+id/nav_layout_delegate_dsl"
android:icon="@drawable/ic_menu_slideshow"
android:title="LayoutAdapterDelegate DSL" />

<item
android:id="@+id/nav_github_demo"
android:icon="@drawable/ic_menu_slideshow"
android:title="GitHub Demo" />

</group>
</menu>
Original file line number Diff line number Diff line change
Expand Up @@ -212,13 +212,6 @@ private TypeSpec createAdapterDelegateTypeSpec(final RoundEnvironment roundEnvir
.addParameter(CLASS_FLAP_ADAPTER, "adapter")
.addStatement("component.bindData(data, position, payloads, adapter, this)");

// MethodSpec getComponentModelClass = MethodSpec.methodBuilder("getComponentModelClass")
// .addAnnotation(Override.class)
// .addModifiers(Modifier.PUBLIC)
// .returns(Class.class)
// .addStatement("return " + itemModelClass + ".class")
// .build();

MethodSpec.Builder onViewAttachedToWindow = MethodSpec.methodBuilder("onViewAttachedToWindow")
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
Expand All @@ -233,6 +226,23 @@ private TypeSpec createAdapterDelegateTypeSpec(final RoundEnvironment roundEnvir
.addParameter(CLASS_COMPONENT, "component")
.addStatement("component.onViewAttachedToWindow(adapter)");


MethodSpec.Builder onFailedToRecycleView = MethodSpec.methodBuilder("onFailedToRecycleView")
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.addParameter(CLASS_FLAP_ADAPTER, "adapter")
.addParameter(CLASS_COMPONENT, "component")
.addStatement("return component.onFailedToRecycleView(adapter)")
.returns(Boolean.TYPE);


MethodSpec.Builder onViewRecycled = MethodSpec.methodBuilder("onViewRecycled")
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.addParameter(CLASS_FLAP_ADAPTER, "adapter")
.addParameter(CLASS_COMPONENT, "component")
.addStatement("component.onViewRecycled(adapter)");

ParameterizedTypeName name = ParameterizedTypeName.get(CLASS_ADAPTER_DELEGATE, itemModelClass, componentClass);

TypeSpec.Builder builder =
Expand All @@ -244,9 +254,10 @@ private TypeSpec createAdapterDelegateTypeSpec(final RoundEnvironment roundEnvir
.addMethod(getItemIdMethodBuilder.build())
.addMethod(delegateMethodBuilder.build())
.addMethod(onBindViewHolderMethodBuilder.build())
// .addMethod(getComponentModelClass)
.addMethod(onViewAttachedToWindow.build())
.addMethod(onViewDetachedFromWindow.build())
.addMethod(onFailedToRecycleView.build())
.addMethod(onViewRecycled.build())
.addSuperinterface(name);

return builder.build();
Expand Down
20 changes: 11 additions & 9 deletions flap/src/main/java/me/yifeiyuan/flap/Component.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package me.yifeiyuan.flap

import android.content.Context
import android.view.View
import androidx.annotation.CallSuper
import androidx.annotation.IdRes
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
Expand Down Expand Up @@ -50,7 +51,6 @@ abstract class Component<T>(itemView: View) : RecyclerView.ViewHolder(itemView),
}

/**
* Overriding `onBind` to bind your model to your Component.
*
* @param model The model that you need to bind.
* @param position position
Expand All @@ -69,6 +69,8 @@ abstract class Component<T>(itemView: View) : RecyclerView.ViewHolder(itemView),

/**
* 执行数据绑定,处理业务逻辑
*
* @see onBind
*/
abstract fun onBind(model: T)

Expand All @@ -77,17 +79,17 @@ abstract class Component<T>(itemView: View) : RecyclerView.ViewHolder(itemView),
}

/**
* @param flapAdapter The adapter which is using your Component.
* @see FlapAdapter.onViewAttachedToWindow
*/
@CallSuper
open fun onViewAttachedToWindow(flapAdapter: FlapAdapter) {
onVisibilityChanged(true, flapAdapter)
}

/**
* @param flapAdapter The adapter which is using your Component.
* @see FlapAdapter.onViewDetachedFromWindow
*/
@CallSuper
open fun onViewDetachedFromWindow(flapAdapter: FlapAdapter) {
onVisibilityChanged(false, flapAdapter)
}
Expand All @@ -99,37 +101,37 @@ abstract class Component<T>(itemView: View) : RecyclerView.ViewHolder(itemView),
* @see onViewAttachedToWindow
* @see onViewDetachedFromWindow
*/
@CallSuper
open fun onVisibilityChanged(visible: Boolean, flapAdapter: FlapAdapter) {
isVisible = visible
}

/**
* @param flapAdapter The adapter which is using your FlapItem.
* @see FlapAdapter.onViewRecycled
*/
open fun onViewRecycled(flapAdapter: FlapAdapter) {}

/**
* @param flapAdapter The adapter which is using your FlapItem.
* @return True if the View should be recycled, false otherwise.
* @return true if the View should be recycled, false otherwise.
* @see FlapAdapter.onFailedToRecycleView
*/
open fun onFailedToRecycleView(flapAdapter: FlapAdapter): Boolean {
return false
}

@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
open fun onResume() {
open fun onResume(owner: LifecycleOwner) {
}

@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
open fun onPause() {
open fun onPause(owner: LifecycleOwner) {
}

@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
open fun onStop() {
open fun onStop(owner: LifecycleOwner) {
}

@CallSuper
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
open fun onDestroy(owner: LifecycleOwner) {
owner.lifecycle.removeObserver(this)
Expand Down
9 changes: 5 additions & 4 deletions flap/src/main/java/me/yifeiyuan/flap/FlapAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ open class FlapAdapter : RecyclerView.Adapter<Component<*>>(), IRegistry {
payloads: MutableList<Any>
) {
try {
tryAttachLifecycleOwner(component)
val delegate = getDelegateByViewType(component.itemViewType)
val data = getItemData(position)
dispatchOnBindViewHolderStart(this, delegate, component, data, position, payloads)
Expand All @@ -200,6 +199,7 @@ open class FlapAdapter : RecyclerView.Adapter<Component<*>>(), IRegistry {
this
)
dispatchOnBindViewHolderEnd(this, delegate, component, data, position, payloads)
tryAttachLifecycleOwner(component)
} catch (e: Exception) {
e.printStackTrace()
FlapDebug.e(TAG, "onBindViewHolder: Error = ", e)
Expand Down Expand Up @@ -326,12 +326,13 @@ open class FlapAdapter : RecyclerView.Adapter<Component<*>>(), IRegistry {
* 会优先于 FlapComponentPool.putRecycledView 被调用
*/
override fun onViewRecycled(component: Component<*>) {
component.onViewRecycled(this)
FlapDebug.d(TAG, "onViewRecycled() called with: component = $component")
val delegate = getDelegateByViewType(component.itemViewType)
delegate.onViewRecycled(this, component)
}

override fun onFailedToRecycleView(component: Component<*>): Boolean {
return component.onFailedToRecycleView(this)
val delegate = getDelegateByViewType(component.itemViewType)
return delegate.onFailedToRecycleView(this, component)
}

override fun onViewAttachedToWindow(component: Component<*>) {
Expand Down
15 changes: 15 additions & 0 deletions flap/src/main/java/me/yifeiyuan/flap/delegate/AdapterDelegate.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package me.yifeiyuan.flap.delegate

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.annotation.CallSuper
import androidx.recyclerview.widget.RecyclerView
import me.yifeiyuan.flap.Component
import me.yifeiyuan.flap.FlapAdapter
Expand Down Expand Up @@ -99,4 +100,18 @@ interface AdapterDelegate<M, VH : Component<M>> {
fun onViewDetachedFromWindow(adapter: FlapAdapter, component: Component<*>) {
component.onViewDetachedFromWindow(adapter)
}

/**
* @see FlapAdapter.onFailedToRecycleView
*/
fun onFailedToRecycleView(adapter: FlapAdapter, component: Component<*>): Boolean {
return component.onFailedToRecycleView(adapter)
}

/**
* @see FlapAdapter.onViewRecycled
*/
fun onViewRecycled(adapter: FlapAdapter, component: Component<*>) {
component.onViewRecycled(adapter)
}
}
Loading

0 comments on commit f65809f

Please sign in to comment.