0

I'm trying to make a toolbar that I can insert into other Anko components. Here is an example of what I am going for:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        MainUI().setContentView(this)

        val toolbar: Toolbar = find(R.id.toolbar)
        setSupportActionBar(toolbar)
    }
}

class MainUI : AnkoComponent<MainActivity> {
    override fun createView(ui: AnkoContext<MainActivity>) = with(ui) {
        coordinatorLayout {
            fitsSystemWindows = true
            lparams {
                width = matchParent
                height = matchParent
            }
            ToolbarUI().createView(ui).lparams { width = matchParent }
            recyclerView {...}.lparams {
                width = matchParent
                height = matchParent
                behavior = AppBarLayout.ScrollingViewBehavior()
            }
        }
    }
}

class ToolbarUI : AnkoComponent<AppCompatActivity> {
    override fun createView(ui: AnkoContext<AppCompatActivity>) = with(ui) {
        appBarLayout {
            ...
            toolbar {
                setTitleTextColor(Color.WHITE)
                id = R.id.toolbar
                title = resources.getString(R.string.main_activity)
                ...
            }.lparams {
                width = matchParent
                height = wrapContent
            }
        }
    }
}

This way I could use this same AppBarLayout elsewhere with much less code. But I am getting this: java.lang.IllegalStateException: View is already set: org.jetbrains.anko.design._AppBarLayout

Anyone could help me with the correct way to implement this?

Phito
  • 1,195
  • 3
  • 10
  • 20

2 Answers2

2

I was able to do it with ViewManager based on this answer.

Here is the new code:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        MainUI().setContentView(this)

        val toolbar: Toolbar = find(R.id.toolbar)
        setSupportActionBar(toolbar)
    }
}

class MainUI : AnkoComponent<MainActivity> {
    override fun createView(ui: AnkoContext<MainActivity>) = with(ui) {
        coordinatorLayout {
            fitsSystemWindows = true
            lparams {
                width = matchParent
                height = matchParent
            }
            toolbarUI(resources.getString(R.string.main_activity)).lparams { width = matchParent }
            recyclerView {...}.lparams {
                width = matchParent
                height = matchParent
                behavior = AppBarLayout.ScrollingViewBehavior()
            }
        }
    }

    fun ViewManager.toolbarUI(activity: String) = appBarLayout {
        toolbar {
            setTitleTextColor(Color.WHITE)
            id = R.id.toolbar
            title = activity
        }.lparams {
            width = matchParent
            height = wrapContent
        }
    }
}
Phito
  • 1,195
  • 3
  • 10
  • 20
1

The problem is that ToolbarUI().createView(ui) creates view on the same AnkoContext, on ui, which is created with setContentView = true by default. You can try using another AnkoContext, which is not going to attach view to Activity: ToolbarUI().createView(AnkoContextImpl(activity, this /* parent ViewGroup */, true)).

Miha_x64
  • 5,973
  • 1
  • 41
  • 63