kotlin / anko Goto Github PK
View Code? Open in Web Editor NEWPleasant Android application development
License: Apache License 2.0
Pleasant Android application development
License: Apache License 2.0
Can you achieve the performances of an annotation processor with Anko ?
The example will repro the stacktrace at the bottom on Android 5.0.0
You may need a theme with the actionbar enabled. I am using android:Theme.Material.Light.DarkActionBar
class MainActivity() : Activity() {
override fun onCreate(state: Bundle?) {
super.onCreate(state)
scrollView {
verticalLayout {
editText()
}.layoutParams() {}
}
}
}
java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to android.view.ViewGroup$MarginLayoutParams
at android.widget.ScrollView.measureChildWithMargins(ScrollView.java:1252)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at android.widget.ScrollView.onMeasure(ScrollView.java:337)
at android.view.View.measure(View.java:17430)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
The problem: To me there was no apparent way to get references to the root view of DSL scripts. So I thought of this way to sort of mimic the framework setContent api and get us a reference to our DSL root. I'm new to kotlin and anko so feedback is much appreciated.
The solution:
abstract class BaseActivity : RxAppCompatActivity(), AnkoLogger{
var layout : View by Delegates.notNull()
fun setLayout(inflate : () -> View ){
layout = with(this){
inflate()
}
}
}
usage
class Main : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setLayout{
frameLayout {
backgroundColor = Color.RED
}
}
}
override fun onResume(){
super.onResume()
debug(layout)
}
}
The dip
, sp
, px2dip
and px2sp
functions are defined for Context
, UiHelper
and android.app.Fragment
but they are not defined for android.support.v4.app.Fragment
nor for Dialog
.
Is there a reason for this ?
For each size, there should be an easy way to set a resource dimension.
Also, when setting a text size from a resource dimension, COMPLEX_UNIT_PX must be passed.
As an example, here's my extension method to TextView to set a textSize from a dimension resource:
public var TextView.textSizeDimen: Int
get() = throw AnkoException("'textSizeDimen' property doesn't have a getter")
set(res) = setTextSize(TypedValue.COMPLEX_UNIT_PX, getContext().getResources().getDimension(res))
when updating to AS 1.3 I had to bump the plugin version and also kotlin to 0.12.200 - now I only get an error for anko - saying it has an unsupported format
Windows 8.1 64 / android-studio-bundle-141.1903250-windows / Kotln 0.12.200
Error when opening any Kotlin project:
"Cannot load project: com.itellij.ide.plugins.PluginManager$StartupAbortedException:
com.intellij.diagnostic.PluginException:
kotlin.properties.Delegates.lazy(Lkotlin/Function0;)LKotlin/properties/ReadOnlyProperty;(Plugin:org.jetbrains.kotlin.android.dsl)"
First of all, the documentation should be updated to reflect the renaming of the function Intent
to intentFor
.
The documentation states that parameters can be given to Intent
, but the function intentFor
does not take any parameter.
Just like the function startActivity
, I believe it should take vararg params: Pair<String, Any>
as parameter.
The latest anko release is only compatible with M11. Is there a workaround to make it wirk with M12 until the next version is released?
I would like to know, how to use anko to handle android layout variations like layout-land or layout-sw600dp?
It would great if you can provide sample code.
Is there an estimate as to when a Koan release will be out that's built against M11?
frameLayout{ layoutParams(matchParent, matchParent)}
vs the recommended
frameLayout{ }.layoutParams(matchParent, matchParent)
I see doing it the first way only works partially, some attributes do not work like margins. I think the required way really hurts the readability of the layout it would be preferable to put it inline.
AnkoLogger.error() needs a default throwable param so you can make the call Log.e(String, String, Throwable) to print a stacktrace.
It's probably a good idea to generate listener helpers (and/or properties) for Menu
, ActionBar
and similar classes as well.
Example: ActionBar.ActionBarMenuOnItemClick
.
Hello @yanex,
I would like use koan and MPAndroidChart together because a dsl it's very good way for me. But I don't know how can I use a several code constructions. For example exists a code https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartActivity1.java#L62 but I cannot use this
construction in my code. Also I would like use like ... { data = data }...
instead of ... { setData(data) } ...
and also the same in similar cases. This is my repository https://github.com/xgrommx/KoanMPAndroidChartExample/blob/master/app/src/main/kotlin/com/gromm/koanexample/MainActivity.kt#L39
When I try to override the log tag I get an IllegalAccessError. What am I doing wrong?
abstract class BaseActivity : RxAppCompatActivity(), AnkoLogger by KoatLogger(){
}
//... off in some other file
class KoatLogger : AnkoLogger {
override val loggerTag = "koat"
}
In Anko 0.6-15, I can find no extension method whatsoever that apply to android.support.v4.app.Fragment
.
Any plan to support support fragments ?
Helper functions, such as passwordEditText()
are required so one doesn't need to specify an InputType
exactly.
I found 2 problems with the Intent
function:
android.content.Intent
, making it difficult to use if I'm in an activity that overrides functions like onActivityResult
or onNewIntent
. Since Activity
already has a property intent
, I propose to rename the function to intentFor
or newIntent
.reified T : java.lang.Class<_>
. I guess it should only bereified T : Any
.Also, Anko provides a utility function startActivity
but not startActivityForResult
.
Finally, startActivity
is defined for Activity
and android.app.Fragment
but not for android.support.v4.app.Fragment
I'm using asyncResult
in one of my fragments and when I execute it the following exception occurs:
java.lang.NoSuchMethodError: No static method async(Landroid/support/v4/app/Fragment;Lkotlin/jvm/functions/Function1;)Ljava/util/concurrent/Future; in class Lorg/jetbrains/anko/AnkoPackage; or its super classes (declaration of 'org.jetbrains.anko.AnkoPackage' appears in /data/app/pacakge.name/base.apk)
Also when compiling with ProGuard enabled the following warning appears:
Warning: de.busliniensuche.android.BookingSummaryServiceFragment: can't find referenced method 'java.util.concurrent.Future asyncResult(android.content.Context,kotlin.jvm.functions.Function0)' in program class org.jetbrains.anko.AnkoPackage
I'm using Anko 0.6.2-19s and Kotlin 0.12.412 with Gradle.
I can't seem to find a good way of setting a style for a view. For example if I wanted a large ProgressBar in XML I would write:
<ProgressBar
style="@android:style/Widget.DeviceDefault.Light.ProgressBar.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
How do you do this in anko?
Is it possible to make it platform independent than android specific.
The extension function withArguments
is defined for android.app.Fragment
but not for android.support.v4.app.Fragment
.
[suppress("NOTHING_TO_INLINE")]
public inline fun ViewManager.horizontalProgressBar(): android.widget.ProgressBar = horizontalProgressBar({})
public inline fun ViewManager.horizontalProgressBar(inlineOptions(InlineOption.ONLY_LOCAL_RETURN) init: android.widget.ProgressBar.() -> Unit): android.widget.ProgressBar = addView {
ctx ->
val view = android.widget.ProgressBar(ctx,null,android.R.attr.progressBarStyleHorizontal)
view.init()
view
}
Not sure if null is the right thing to put though.
background=?primaryColor
?There's no emptyView
property for the AdapterView
class.
It would be useful to add CHANGELOG.md file to enable quick sync with library changes for its users. Parsing commit log trying to filter essential changes is rather troublesome.
I am trying to add a appcompat toolbar using anko but can't find any example or guide. An example will help a lot.
I want to lean this.If you have example can better learning
Is it possible (and how) to create a custom adapter for a listview, with a custom layout? ArrayAdapter constructor requires an id of the layout, like here:
listView {
adapter = ArrayAdapter(ctx, android.R.layout.simple_list_item_1, listOf("a", "b"))
}
YouTrack issue: https://youtrack.jetbrains.com/issue/KT-7635
I am using Anko 0.6-15s
and I can't find android.support.v4.app.Fragment.withArguments()
extension function.
I searched a bit and I couldn't seem to figure out how to embed a fragment in my activity.
For example I want to do something like this.
frameLayout {
linearLayout {
baselineAligned = false
orientation = LinearLayout.HORIZONTAL
fragment {
name = "FragmentClass"
}.layoutParams(width = matchParent, height = matchParent)
}.layoutParams(width = matchParent, height = matchParent)
}
fun dipToPx(dp: Int): Int {
return dp * Resources.getSystem().getDisplayMetrics().density.toInt()
}
val Int.px: Int
get(){
return this
}
val Int.dp: Int
get(){
return dipToPx(this);
}
val Int.dip: Int
get(){
return dipToPx(this)
}
Trying to nest two views that don't want default layout params doesn't work correctly due to scope. In the example below you get a runtime error because verticalLayout{}.layoutParams()
tries to invoke the ScrollView layoutParams instead of LineraLayout. The workaround is to do this verticalLayout{layoutParams()}
but in that case margins do not work.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
root = verticalLayout {
toolbar = toolbarSupport {
defaultToolbar()
title = getLabel()
}
scrollView = scrollView{
ll = verticalLayout{
}.layoutParams(width = matchParent)
}.layoutParams(matchParent, matchParent)
}
Both parseRow()
methods throw an exception if the column count is != 0
instead of when it is != 1
:
override fun parseRow(columns: Array): T { if (columns.size() != 0) throw SQLiteException("Invalid row: row for SingleColumnParser must contain exactly one column") [suppress("UNCHECKED_CAST")] return columns[0] as T }
For example how do you fade in a view?
As you can see here, the Anko JCenter repository contains versions 0.6-15
, 0.6-15s
and 0.6-19
but no 0.6-19s
.
So we can't have both the SDK 19 features and the support library.
Activity
has runOnUIThread {}
but
Fragment
must call getActivity().runOnUiThread {}
Service
must call Handler(Looper.getMainLooper()).post {}
Anko has a Context.uiThread
method but it is private and only meant to be used for Async contexts through AnkoAsyncContext.uiThread
.
It would be great to give all Android system component their own uiThread {}
method.
Hi! I'm trying to use the DLS Preview plugin in Android Studio. However, it show only the white background, not the preview, even when I use the refresh button. How to fix this?
Hi,
Im not a big fan of the ank DSL style but the extension functions are really awesome. If would be nice if you could split the two libraries and make it possible to only include the extension functions in projects.
As the title says
For things like TextView.addTextChangedListener
, Anko has three diferent functions: beforeTextChanged
, onTextChanged
and afterTextChanged
.
Each of these three functions all start with:
val props = getTag() as? ViewProps
if (props != null) {
/* do some magic */
}
...which means that those callback setters will only work if the view tag is set to a ViewProps
object. This in turn means that the setter will not work in any of those cases:
setTag(Object)
inside the init block before calling any of those three functions.Moreover, these functions will fail silently, meaning that it will not work and the programmer will have very little way of understanding why.
Here is a utility that I have created that essentially does the same, but without those problems (in fact, I was using these kind of utils before Anko):
class TextWatcherFunctions : TextWatcher {
private var _beforeTextChanged: ((CharSequence, Int, Int, Int) -> Unit)? = null
private var _onTextChanged: ((CharSequence, Int, Int, Int) -> Unit)? = null
private var _afterTextChanged: ((Editable) -> Unit)? = null
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int)
= _beforeTextChanged?.invoke(s, start, count, after)
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int)
= _onTextChanged?.invoke(s, start, before, count)
override fun afterTextChanged(s: Editable)
= _afterTextChanged?.invoke(s)
public fun beforeTextChanged(function: (CharSequence, Int, Int, Int) -> Unit) {
_beforeTextChanged = function
}
public fun onTextChanged(function: (CharSequence, Int, Int, Int) -> Unit) {
_onTextChanged = function
}
public fun afterTextChanged(function: (Editable) -> Unit) {
_afterTextChanged = function
}
}
public fun EditText.addTextChangedListener(init: TextWatcherFunctions.() -> Unit): TextWatcher {
val watcher = TextWatcherFunctions()
watcher.init()
addTextChangedListener(watcher)
return watcher
}
This allows me to set only one of those functions with the syntax:
myEditText.addTextChangedListener {
onTextChanged { /* Do something amazing :) */ }
}
In the context of Anko, instead of
editText {
onTextChanged { /* Do something amazing :) */ }
}
it would be:
editText {
addTextChangedListener {
onTextChanged { /* Do something amazing :) */ }
}
}
Of course, the wording would have to be re-thought to be closer to Anko's paradigm.
I know this adds a new block level, but I argue that this has significant advantages over the current implementation:
addTextChangedListener
returns the created listener, allowing the programmer to later call removeTextChangedListener
. Although, to be complete, it would be cleaner for it to return an rxjava like Subscription
object on which to call an unsubscribe
.What do you think ?
It looks like the default support v7 appcompat tinting is disabled if you use anko.
Is there any solution other than adding those?
public fun ViewManager.appCompatEditText(init: AppCompatEditText.() -> Unit = {}): AppCompatEditText =
__dslAddView({ AppCompatEditText(it, null) }, init, this)
public fun ViewManager.appCompatCheckBox(init: AppCompatCheckBox.() -> Unit = {}): AppCompatCheckBox =
__dslAddView({ AppCompatCheckBox(it, null) }, init, this)
public fun ViewManager.appCompatRadioButton(init: AppCompatRadioButton.() -> Unit = {}): AppCompatRadioButton =
__dslAddView({ AppCompatRadioButton(it, null) }, init, this)
There're no progressDialog()
and indeterminateProgressDialog()
function overloads that accept String
resources.
Anko team,
Thanks for the great library. :)
I'm having trouble referring to views outside the current scope.
My use case is to call an EditText from a button that lives in a different layout/ViewGroup.
Please look at the below examples to see what I am trying to accomplish. It's possible that there's a way that I'm not seeing.
Works! :)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
verticalLayout {
val name = editText() {
id = nameId
}
button("Register") {
onClick {
toast("Hello, ${name.text}!")
}
}
}
}
Won't compile - name is used outside scope
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
relativeLayout {
verticalLayout {
val name = editText() {
id = nameId
}
}
button("Register") {
onClick {
toast("Hello, ${name.text}!")
}
}
}
}
Runs, but name doesn't create an actual instance of editText inside relativeLayout. So there's no editText in the UI.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val name = editText() {
relativeLayout {
verticalLayout {
val name = editText() {
id = nameId
}
}
button("Register") {
onClick {
toast("Hello, ${name.text}!")
}
}
}
}
Crash at runtime - findViewById returns a View, not an EditText
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val name = editText() {
val nameId = 1
relativeLayout {
verticalLayout {
val name = editText() {
id = nameId
}
}
button("Register") {
onClick {
// fails with: android.view.View! cannot be cast to T
val name = find<EditText>(nameId)
// fails with: android.view.View! cannot be cast to android.widget.EditText
val name: EditText = findViewById(nameId) as EditText
toast("Hello, ${name.text}!")
}
}
}
}
Many thanks for your time and attention. Let me know how I can help get this resolved.
'IF NOT EXISTS' is useless for DROP TABLE. Should be 'IF EXISTS'
Possible libraries to take another methods from (including mine): https://android-arsenal.com/tag/205
I am attempting to make reusable components but there is no easy way to do it that I can see. Here is what I'm attempting. We need each generated _Class to also extend a _View trait so we can easily extend all of them as if were were writing an extension function on View.
Use case:
fun _FrameLayout.defaultToolbar() : Toolbar{
return with(this){
toolbarSupport{
setTitle("hello")
setElevationCompat(getContext().dip(4))
backgroundColor = getContext().attribute(R.attr.colorPrimary).data
}.layoutParams(width = matchParent, height = getContext().attrAsDimen(R.attr.actionBarSize))
}
}
class Main : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
frameLayout {
val toolbar = defaultToolbar()
}
}
}
Now switching from frameLayout to say LinearLayout would require another extension function for _LinearLayout and so on for every ViewGroup you want to resuse the layout in. It would be great to do something like this instead.
fun _ViewGroup.defaultToolbar() : Toolbar{
return with(this){
toolbarSupport{
setTitle("hello")
setElevationCompat(getContext().dip(4))
backgroundColor = getContext().attribute(R.attr.colorPrimary).data
}.layoutParams(width = matchParent, height = getContext().attrAsDimen(R.attr.actionBarSize))
}
}
Or is there a good way to do something similar now?
Let's said I want to make a a listview item with a fixed size. In order to do that with anko I need to put it inside another ViewGroup.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.