mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
feat: use attribute handlers to apply attributes in IViewAdapter
This commit is contained in:
+46
-5
@@ -48,7 +48,15 @@ import javax.tools.Diagnostic.Kind.ERROR
|
||||
class ViewAdapterAnnotationProcessor : AbstractProcessor() {
|
||||
|
||||
private val adapterElement by lazy {
|
||||
processingEnv.elementUtils.getTypeElement(ADAPTER_BASE_CLASS)
|
||||
processingEnv.typeUtils.erasure(
|
||||
processingEnv.elementUtils.getTypeElement(ADAPTER_BASE_CLASS).asType()
|
||||
)
|
||||
}
|
||||
|
||||
private val viewElement by lazy {
|
||||
processingEnv.typeUtils.erasure(
|
||||
processingEnv.elementUtils.getTypeElement("android.view.View").asType()
|
||||
)
|
||||
}
|
||||
|
||||
private val indexClassBuilder =
|
||||
@@ -143,11 +151,31 @@ class ViewAdapterAnnotationProcessor : AbstractProcessor() {
|
||||
return
|
||||
}
|
||||
|
||||
if (!processingEnv.typeUtils.isSubtype(element.asType(), adapterElement.asType())) {
|
||||
if (
|
||||
!processingEnv.typeUtils.isAssignable(
|
||||
processingEnv.typeUtils.erasure(element.asType()),
|
||||
adapterElement
|
||||
)
|
||||
) {
|
||||
processingEnv.messager.printMessage(ERROR, "Class must be a subtype of $ADAPTER_BASE_CLASS")
|
||||
return
|
||||
}
|
||||
|
||||
if (element.typeParameters.size != 1) {
|
||||
processingEnv.messager.printMessage(
|
||||
ERROR,
|
||||
"A view adapter must have exactly one type parameter"
|
||||
)
|
||||
}
|
||||
|
||||
val typeParam = element.typeParameters[0]
|
||||
if (!processingEnv.typeUtils.isAssignable(typeParam.asType(), viewElement)) {
|
||||
processingEnv.messager.printMessage(
|
||||
ERROR,
|
||||
"The type parameter of view adapter must be assignable from android.view.View"
|
||||
)
|
||||
}
|
||||
|
||||
val annotation = element.getAnnotation(ViewAdapter::class.java) ?: throw IllegalStateException()
|
||||
val viewName = getViewName(annotation)
|
||||
|
||||
@@ -157,9 +185,13 @@ class ViewAdapterAnnotationProcessor : AbstractProcessor() {
|
||||
for (superclass in superclasses) {
|
||||
block.addStatement("superclasses.add(\$S)", superclass)
|
||||
}
|
||||
|
||||
|
||||
val adapterType = ClassName.get(element)
|
||||
val paramType = getViewTypeName(annotation)
|
||||
|
||||
block.add("\n")
|
||||
block.addStatement("final var adapter = new \$T()", TypeName.get(element.asType()))
|
||||
block.addStatement("final var adapter = new \$T()", ParameterizedTypeName.get(adapterType, paramType))
|
||||
block.addStatement("adapter.\$L(superclasses)", METHOD_SET_SUPERCLASS_HIERARCHY)
|
||||
block.addStatement("adapter.\$L(\$S)", METHOD_SET_MODULE, annotation.moduleNamespace)
|
||||
block.addStatement("\$L.put(\$S, adapter)", INDEX_MAP_FIELD, viewName)
|
||||
@@ -181,7 +213,7 @@ class ViewAdapterAnnotationProcessor : AbstractProcessor() {
|
||||
)
|
||||
indexClassBuilder.addField(
|
||||
FieldSpec.builder(type, INDEX_MAP_FIELD, PRIVATE, STATIC, FINAL)
|
||||
.initializer("new \$T<>();", HashMap::class.java)
|
||||
.initializer("new \$T<>()", HashMap::class.java)
|
||||
.build()
|
||||
)
|
||||
|
||||
@@ -210,6 +242,15 @@ class ViewAdapterAnnotationProcessor : AbstractProcessor() {
|
||||
.build()
|
||||
)
|
||||
}
|
||||
|
||||
private fun getViewTypeName(annotation: ViewAdapter) : TypeName {
|
||||
return try {
|
||||
ClassName.get(annotation.forView.java)
|
||||
?: throw IllegalStateException("Cannot find type of $annotation")
|
||||
} catch (err: MirroredTypeException) {
|
||||
(processingEnv.typeUtils.asElement(err.typeMirror) as TypeElement).let { ClassName.get(it) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun getViewName(annotation: ViewAdapter): String {
|
||||
return try {
|
||||
@@ -232,7 +273,7 @@ class ViewAdapterAnnotationProcessor : AbstractProcessor() {
|
||||
} catch (err: MirroredTypeException) {
|
||||
val typeElement = processingEnv.typeUtils.asElement(err.typeMirror) as TypeElement
|
||||
result.add(typeElement.qualifiedName.toString())
|
||||
|
||||
|
||||
var superclass = typeElement.superclass
|
||||
while (superclass != null) {
|
||||
val superType = processingEnv.typeUtils.asElement(superclass) as? TypeElement?
|
||||
|
||||
Binary file not shown.
+24
-4
@@ -376,8 +376,25 @@ open class AndroidModule( // Class must be open because BaseXMLTest mocks this..
|
||||
* @param pck The package to look for.
|
||||
*/
|
||||
fun findResourceTableForPackage(pck: String, hasGroup: AaptResourceType? = null): ResourceTable? {
|
||||
return findAllResourceTableForPackage(pck, hasGroup).let {
|
||||
if (it.isNotEmpty()) {
|
||||
return it.first()
|
||||
} else null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks all the resource tables from this module and returns if any of the tables contain
|
||||
* resources for the the given package.
|
||||
*
|
||||
* @param pck The package to look for.
|
||||
*/
|
||||
fun findAllResourceTableForPackage(
|
||||
pck: String,
|
||||
hasGroup: AaptResourceType? = null
|
||||
): List<ResourceTable> {
|
||||
if (pck == SdkConstants.ANDROID_PKG) {
|
||||
return getFrameworkResourceTable()
|
||||
return getFrameworkResourceTable()?.let { listOf(it) } ?: emptyList()
|
||||
}
|
||||
|
||||
val tables: List<ResourceTable> =
|
||||
@@ -387,17 +404,20 @@ open class AndroidModule( // Class must be open because BaseXMLTest mocks this..
|
||||
addAll(getDependencyResourceTables())
|
||||
}
|
||||
|
||||
val result = mutableListOf<ResourceTable>()
|
||||
for (table in tables) {
|
||||
val resPck = table.findPackage(pck) ?: continue
|
||||
if (hasGroup == null) {
|
||||
return table
|
||||
result.add(table)
|
||||
continue
|
||||
}
|
||||
if (resPck.findGroup(hasGroup) != null) {
|
||||
return table
|
||||
result.add(table)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Binary file not shown.
+13
-1
@@ -23,7 +23,15 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.android.aaptcompiler.AaptResourceType.STYLEABLE
|
||||
import com.android.aaptcompiler.AttributeResource
|
||||
import com.android.aaptcompiler.ConfigDescription
|
||||
import com.android.aaptcompiler.Styleable
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import com.itsaky.androidide.inflater.internal.ViewAdapterIndex
|
||||
import com.itsaky.androidide.inflater.internal.ViewImpl
|
||||
import com.itsaky.androidide.projects.ProjectManager
|
||||
import com.itsaky.androidide.projects.api.AndroidModule
|
||||
import com.itsaky.androidide.uidesigner.adapters.ViewAttrListAdapter
|
||||
import com.itsaky.androidide.uidesigner.databinding.LayoutViewInfoBinding
|
||||
import com.itsaky.androidide.uidesigner.databinding.LayoutViewInfoHeaderBinding
|
||||
@@ -31,6 +39,8 @@ import com.itsaky.androidide.uidesigner.models.UiAttribute
|
||||
import com.itsaky.androidide.uidesigner.viewmodel.WorkspaceViewModel
|
||||
import com.itsaky.androidide.uidesigner.viewmodel.WorkspaceViewModel.Companion.SCREEN_VALUE_EDITOR
|
||||
import com.itsaky.androidide.uidesigner.viewmodel.WorkspaceViewModel.Companion.SCREEN_VIEW_INFO
|
||||
import com.itsaky.androidide.utils.ILogger
|
||||
import java.util.TreeSet
|
||||
|
||||
/**
|
||||
* A [BottomSheetDialogFragment] which shows information about a clicked view.
|
||||
@@ -53,6 +63,7 @@ class ViewInfoFragment : Fragment() {
|
||||
}
|
||||
|
||||
private var header: LayoutViewInfoHeaderBinding? = null
|
||||
private val log = ILogger.newInstance("ViewInfoFragment")
|
||||
|
||||
companion object {
|
||||
const val TAG = "ide.uidesigner.viewinfo"
|
||||
@@ -86,7 +97,8 @@ class ViewInfoFragment : Fragment() {
|
||||
private fun showViewInfo() {
|
||||
val binding = this.binding ?: return
|
||||
val header = this.header ?: return
|
||||
val view = this.viewModel.view ?: return
|
||||
val view = this.viewModel.view as? ViewImpl ?: return
|
||||
val adapter = ViewAdapterIndex.getAdapter(view.name) ?: return
|
||||
|
||||
header.name.text = view.simpleName
|
||||
header.desc.text = view.name
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.INamespace
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import com.itsaky.androidide.inflater.internal.AttributeImpl
|
||||
import com.itsaky.androidide.inflater.internal.ViewAdapterIndex
|
||||
|
||||
/**
|
||||
* UI Designer specific implementation of [IAttribute].
|
||||
@@ -36,7 +37,7 @@ constructor(
|
||||
) : AttributeImpl(namespace, name, value) {
|
||||
|
||||
constructor(src: IAttribute) : this(namespace = src.namespace, name = src.name, value = src.value)
|
||||
|
||||
|
||||
/**
|
||||
* Whether this attribute is required or not. Required attributes cannot be removed from a view
|
||||
* once applied.
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.itsaky.androidide.inflater.LayoutBehavior.HORIZONTAL
|
||||
import com.itsaky.androidide.inflater.LayoutBehavior.TOP_LEFT
|
||||
import com.itsaky.androidide.inflater.LayoutBehavior.VERTICAL
|
||||
import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
import com.itsaky.androidide.inflater.internal.ViewAdapterIndex
|
||||
import com.itsaky.androidide.inflater.internal.ViewGroupImpl
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.inflater
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
|
||||
/**
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
data class AttributeHandlerScope<T : View>(
|
||||
val view: T,
|
||||
val file: LayoutFile,
|
||||
val context: Context,
|
||||
val layoutParams: ViewGroup.LayoutParams,
|
||||
val namespace: INamespace,
|
||||
val name: String,
|
||||
val value: String
|
||||
)
|
||||
@@ -17,12 +17,17 @@
|
||||
|
||||
package com.itsaky.androidide.inflater
|
||||
|
||||
import android.view.View
|
||||
import com.android.SdkConstants
|
||||
import com.itsaky.androidide.inflater.internal.AttributeImpl
|
||||
import com.itsaky.androidide.inflater.internal.ViewImpl
|
||||
|
||||
/**
|
||||
* Handles logic for applying attributes to a view.
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
abstract class IViewAdapter : AbstractParser() {
|
||||
abstract class IViewAdapter<T : View> : AbstractParser() {
|
||||
|
||||
/** Superclasses of the view that this adpater handles. */
|
||||
var superclassHierarchy: List<String> = emptyList()
|
||||
@@ -34,9 +39,9 @@ abstract class IViewAdapter : AbstractParser() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The package name or namespace of the module/artifact in which the view that this adapter handles is defined.
|
||||
* The value is set to "android" by default unless explicitly specified in the [ViewAdapter]
|
||||
* [com.itsaky.androidide.annotations.inflater.ViewAdapter] annotation.
|
||||
* The package name or namespace of the module/artifact in which the view that this adapter
|
||||
* handles is defined. The value is set to "android" by default unless explicitly specified in the
|
||||
* [ViewAdapter][com.itsaky.androidide.annotations.inflater.ViewAdapter] annotation.
|
||||
*
|
||||
* This is used by the UI designer to quickly look for attributes of an inflated view from the
|
||||
* resource tables.
|
||||
@@ -49,6 +54,19 @@ abstract class IViewAdapter : AbstractParser() {
|
||||
field = value
|
||||
}
|
||||
|
||||
/** The attributes that are supported by the adapter. The attributes in the list are immutable. */
|
||||
val supportedAttributes by lazy {
|
||||
attributeHandlers.map {
|
||||
AttributeImpl(namespace = defaultNamespace(), name = it.key, value = "").immutable()
|
||||
}
|
||||
}
|
||||
|
||||
private val attributeHandlers by lazy {
|
||||
val handlers = mutableMapOf<String, AttributeHandlerScope<T>.() -> Unit>()
|
||||
createAttrHandlers(handlers::put)
|
||||
return@lazy handlers
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the given attribute to the given view.
|
||||
*
|
||||
@@ -56,7 +74,9 @@ abstract class IViewAdapter : AbstractParser() {
|
||||
* @param attribute The attribute to apply.
|
||||
* @return Whether the attribute was applied or not.
|
||||
*/
|
||||
abstract fun apply(view: IView, attribute: IAttribute): Boolean
|
||||
open fun apply(view: IView, attribute: IAttribute): Boolean {
|
||||
return doApply(view, attribute) { applyInternal() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the basic attributes to a view so that it could be rendered.
|
||||
@@ -73,4 +93,70 @@ abstract class IViewAdapter : AbstractParser() {
|
||||
* @return `true` if the attribute is required, `false` otherwise.
|
||||
*/
|
||||
abstract fun isRequiredAttribute(attribute: IAttribute): Boolean
|
||||
|
||||
/**
|
||||
* The default namespace that will be used by the UI designer to create and apply new attributes.
|
||||
*/
|
||||
protected open fun defaultNamespace(): INamespace {
|
||||
return INamespace.ANDROID
|
||||
}
|
||||
|
||||
protected open fun canHandleNamespace(namespace: INamespace): Boolean {
|
||||
return this.canHandleNamespace(namespace.uri)
|
||||
}
|
||||
protected open fun canHandleNamespace(nsUri: String): Boolean {
|
||||
return SdkConstants.ANDROID_URI == nsUri
|
||||
}
|
||||
|
||||
protected open fun AttributeHandlerScope<T>.applyInternal(): Boolean {
|
||||
val handler = attributeHandlers[name]
|
||||
if (handler != null) {
|
||||
handler()
|
||||
}
|
||||
return handler != null || applyLayoutParams()
|
||||
}
|
||||
|
||||
protected open fun AttributeHandlerScope<T>.applyLayoutParams(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides easy access to various properties related to the view and attribute when applying an
|
||||
* attributes.
|
||||
*/
|
||||
private fun doApply(
|
||||
view: IView,
|
||||
attribute: IAttribute,
|
||||
apply: AttributeHandlerScope<T>.() -> Boolean,
|
||||
): Boolean {
|
||||
|
||||
if (!canHandleNamespace(attribute.namespace)) {
|
||||
return false
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return (view.view as T).let {
|
||||
val file = (view as ViewImpl).file
|
||||
return@let AttributeHandlerScope(
|
||||
it,
|
||||
file,
|
||||
it.context,
|
||||
it.layoutParams,
|
||||
attribute.namespace,
|
||||
attribute.name,
|
||||
attribute.value
|
||||
)
|
||||
.let(apply)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the attribute handlers. Subclasses are expected to use the [create] function to create
|
||||
* new handlers.
|
||||
*
|
||||
* A subclass should call the `super` method and add only the view specific attribute handlers.
|
||||
*/
|
||||
protected open fun createAttrHandlers(
|
||||
create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit
|
||||
) {}
|
||||
}
|
||||
|
||||
+14
-24
@@ -18,6 +18,7 @@
|
||||
package com.itsaky.androidide.inflater.internal.adapters
|
||||
|
||||
import android.widget.AbsListView
|
||||
import com.itsaky.androidide.inflater.AttributeHandlerScope
|
||||
import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
|
||||
@@ -26,30 +27,19 @@ import com.itsaky.androidide.inflater.IView
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
abstract class AbsListViewAttrAdapter : AdapterViewAttrAdapter() {
|
||||
|
||||
override fun apply(view: IView, attribute: IAttribute): Boolean {
|
||||
return doApply<AbsListView>(view, attribute) { _, context, _, _, name, value ->
|
||||
var applied = true
|
||||
when (name) {
|
||||
"cacheColorHint" -> cacheColorHint = parseColor(context, value)
|
||||
"choiceMode" -> choiceMode = parseChoiceMode(value)
|
||||
"drawSelectorOnTop" -> isDrawSelectorOnTop = parseBoolean(value)
|
||||
"fastScrollEnabled" -> isFastScrollEnabled = parseBoolean(value)
|
||||
"listSelector" -> selector = parseDrawable(context, value)
|
||||
"smoothScrollbar" -> isSmoothScrollbarEnabled = parseBoolean(value)
|
||||
"stackFromBottom" -> isStackFromBottom = parseBoolean(value)
|
||||
"textFilterEnabled" -> isTextFilterEnabled = parseBoolean(value)
|
||||
"transcriptMode" -> transcriptMode = parseTranscriptMode(value)
|
||||
else -> applied = false
|
||||
}
|
||||
|
||||
if (!applied) {
|
||||
applied = super.apply(view, attribute)
|
||||
}
|
||||
|
||||
return@doApply applied
|
||||
}
|
||||
abstract class AbsListViewAttrAdapter<T : AbsListView> : AdapterViewAttrAdapter<T>() {
|
||||
|
||||
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
|
||||
super.createAttrHandlers(create)
|
||||
create("cacheColorHint") { view.cacheColorHint = parseColor(context, value) }
|
||||
create("choiceMode") { view.choiceMode = parseChoiceMode(value) }
|
||||
create("drawSelectorOnTop") { view.isDrawSelectorOnTop = parseBoolean(value) }
|
||||
create("fastScrollEnabled") { view.isFastScrollEnabled = parseBoolean(value) }
|
||||
create("listSelector") { view.selector = parseDrawable(context, value) }
|
||||
create("smoothScrollbar") { view.isSmoothScrollbarEnabled = parseBoolean(value) }
|
||||
create("stackFromBottom") { view.isStackFromBottom = parseBoolean(value) }
|
||||
create("textFilterEnabled") { view.isTextFilterEnabled = parseBoolean(value) }
|
||||
create("transcriptMode") { view.transcriptMode = parseTranscriptMode(value) }
|
||||
}
|
||||
|
||||
protected open fun parseTranscriptMode(value: String): Int {
|
||||
|
||||
+8
-27
@@ -18,39 +18,20 @@
|
||||
package com.itsaky.androidide.inflater.internal.adapters
|
||||
|
||||
import android.widget.AbsSeekBar
|
||||
import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import com.itsaky.androidide.inflater.AttributeHandlerScope
|
||||
|
||||
/**
|
||||
* Attribute adapter for [AbsSeekBar].
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
abstract class AbsSeekBarAttrAdapter : ProgressBarAttrAdapter() {
|
||||
abstract class AbsSeekBarAttrAdapter<T : AbsSeekBar> : ProgressBarAttrAdapter<T>() {
|
||||
|
||||
override fun apply(view: IView, attribute: IAttribute): Boolean {
|
||||
return doApply<AbsSeekBar>(view, attribute) {
|
||||
_,
|
||||
context,
|
||||
_,
|
||||
_,
|
||||
name,
|
||||
value ->
|
||||
var applied = true
|
||||
|
||||
when (name) {
|
||||
"thumbTint" -> thumbTintList = parseColorStateList(context, value)
|
||||
"thumbTintMode" -> thumbTintMode = parsePorterDuffMode(value)
|
||||
"tickMarkTint" -> tickMarkTintList = parseColorStateList(context, value)
|
||||
"tickMarkTintMode" -> tickMarkTintMode = parsePorterDuffMode(value)
|
||||
else -> applied = false
|
||||
}
|
||||
|
||||
if (!applied) {
|
||||
applied = super.apply(view, attribute)
|
||||
}
|
||||
|
||||
return@doApply applied
|
||||
}
|
||||
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
|
||||
super.createAttrHandlers(create)
|
||||
create("thumbTint") { view.thumbTintList = parseColorStateList(context, value) }
|
||||
create("thumbTintMode") { view.thumbTintMode = parsePorterDuffMode(value) }
|
||||
create("tickMarkTint") { view.tickMarkTintList = parseColorStateList(context, value) }
|
||||
create("tickMarkTintMode") { view.tickMarkTintMode = parsePorterDuffMode(value) }
|
||||
}
|
||||
}
|
||||
|
||||
+9
-31
@@ -18,44 +18,22 @@
|
||||
package com.itsaky.androidide.inflater.internal.adapters
|
||||
|
||||
import android.R.layout
|
||||
import android.content.Context
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import android.widget.AbsSpinner
|
||||
import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.INamespace
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
import com.itsaky.androidide.inflater.AttributeHandlerScope
|
||||
|
||||
/**
|
||||
* Attribute adapter for [AbsSpinner].
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
abstract class AbsSpinnerAttrAdapter : AdapterViewAttrAdapter() {
|
||||
override fun apply(view: IView, attribute: IAttribute): Boolean {
|
||||
return doApply<AbsSpinner>(view, attribute) {
|
||||
_: LayoutFile,
|
||||
context: Context,
|
||||
_: LayoutParams,
|
||||
_: INamespace,
|
||||
name: String,
|
||||
value: String ->
|
||||
var applied = true
|
||||
when (name) {
|
||||
"entries" -> {
|
||||
val array = parseStringArray(value)
|
||||
val adapter = newSimpleAdapter(context, array)
|
||||
adapter.setDropDownViewResource(layout.simple_spinner_dropdown_item)
|
||||
setAdapter(adapter)
|
||||
}
|
||||
else -> applied = false
|
||||
}
|
||||
|
||||
if (!applied) {
|
||||
applied = super.apply(view, attribute)
|
||||
}
|
||||
|
||||
return@doApply applied
|
||||
abstract class AbsSpinnerAttrAdapter<T : AbsSpinner> : AdapterViewAttrAdapter<T>() {
|
||||
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
|
||||
super.createAttrHandlers(create)
|
||||
create("entries") {
|
||||
val array = parseStringArray(value)
|
||||
val adapter = newSimpleAdapter(context, array)
|
||||
adapter.setDropDownViewResource(layout.simple_spinner_dropdown_item)
|
||||
view.adapter = adapter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -27,4 +27,4 @@ import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
@ViewAdapter(AbsoluteLayout::class)
|
||||
open class AbsoluteLayoutAttrAdapter : ViewGroupAttrAdapter()
|
||||
open class AbsoluteLayoutAttrAdapter<T : AbsoluteLayout> : ViewGroupAttrAdapter<T>()
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ import com.itsaky.androidide.inflater.internal.ViewGroupImpl
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
abstract class AdapterViewAttrAdapter : ViewGroupAttrAdapter() {
|
||||
abstract class AdapterViewAttrAdapter<T: AdapterView<*>> : ViewGroupAttrAdapter<T>() {
|
||||
|
||||
companion object {
|
||||
const val ADAPTER_DEFAULT_ITEM_COUNT = 3
|
||||
|
||||
+9
-30
@@ -17,14 +17,9 @@
|
||||
|
||||
package com.itsaky.androidide.inflater.internal.adapters
|
||||
|
||||
import android.content.Context
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import android.widget.AutoCompleteTextView
|
||||
import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.INamespace
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
import com.itsaky.androidide.inflater.AttributeHandlerScope
|
||||
|
||||
/**
|
||||
* Attribute adapter for [AutoCompleteTextView].
|
||||
@@ -32,30 +27,14 @@ import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(AutoCompleteTextView::class)
|
||||
class AutoCompleteTextViewAttrAdapter : EditTextAttrAdapter() {
|
||||
open class AutoCompleteTextViewAttrAdapter<T : AutoCompleteTextView> : EditTextAttrAdapter<T>() {
|
||||
|
||||
override fun apply(view: IView, attribute: IAttribute): Boolean {
|
||||
return doApply<AutoCompleteTextView>(view, attribute) {
|
||||
file: LayoutFile,
|
||||
context: Context,
|
||||
_: LayoutParams,
|
||||
_: INamespace,
|
||||
name: String,
|
||||
value: String ->
|
||||
var applied = true
|
||||
when (name) {
|
||||
"completionHint" -> completionHint = parseString(value)
|
||||
"completionThreshold" -> threshold = parseInteger(value, 1)
|
||||
"dropDownAnchor" -> dropDownAnchor = parseId(file.resName, value)
|
||||
"dropDownWidth" -> dropDownWidth = parseDimension(context, value)
|
||||
"dropDownHeight" -> dropDownHeight = parseDimension(context, value)
|
||||
else -> applied = false
|
||||
}
|
||||
if (!applied) {
|
||||
applied = super.apply(view, attribute)
|
||||
}
|
||||
|
||||
return@doApply applied
|
||||
}
|
||||
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
|
||||
super.createAttrHandlers(create)
|
||||
create("completionHint") { view.completionHint = parseString(value) }
|
||||
create("completionThreshold") { view.threshold = parseInteger(value, 1) }
|
||||
create("dropDownAnchor") { view.dropDownAnchor = parseId(file.resName, value) }
|
||||
create("dropDownWidth") { view.dropDownWidth = parseDimension(context, value) }
|
||||
create("dropDownHeight") { view.dropDownHeight = parseDimension(context, value) }
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -25,4 +25,4 @@ import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(Button::class) open class ButtonAttrAdapter : TextViewAttrAdapter()
|
||||
@ViewAdapter(Button::class) open class ButtonAttrAdapter<T : Button> : TextViewAttrAdapter<T>()
|
||||
|
||||
+1
-1
@@ -25,4 +25,4 @@ import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(CheckBox::class) class CheckBoxAttrAdapter : CompoundButtonAttrAdapter()
|
||||
@ViewAdapter(CheckBox::class) open class CheckBoxAttrAdapter<T : CheckBox> : CompoundButtonAttrAdapter<T>()
|
||||
+6
-20
@@ -19,8 +19,7 @@ package com.itsaky.androidide.inflater.internal.adapters
|
||||
|
||||
import android.widget.CheckedTextView
|
||||
import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import com.itsaky.androidide.inflater.AttributeHandlerScope
|
||||
|
||||
/**
|
||||
* Attribute adapter for [CheckedTextView].
|
||||
@@ -28,24 +27,11 @@ import com.itsaky.androidide.inflater.IView
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(CheckedTextView::class)
|
||||
class CheckedTextViewAttrAdapter : TextViewAttrAdapter() {
|
||||
open class CheckedTextViewAttrAdapter<T : CheckedTextView> : TextViewAttrAdapter<T>() {
|
||||
|
||||
override fun apply(view: IView, attribute: IAttribute): Boolean {
|
||||
return doApply<CheckedTextView>(view, attribute) { _, context, _, _, name, value ->
|
||||
var applied = true
|
||||
|
||||
when (name) {
|
||||
"checkMarkTintMode" -> checkMarkTintMode = parsePorterDuffMode(value)
|
||||
"checkMarkTint" -> checkMarkTintList = parseColorStateList(context, value)
|
||||
"checkMark" -> {} // ignored
|
||||
else -> applied = false
|
||||
}
|
||||
|
||||
if (!applied) {
|
||||
applied = super.apply(view, attribute)
|
||||
}
|
||||
|
||||
return@doApply applied
|
||||
}
|
||||
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
|
||||
super.createAttrHandlers(create)
|
||||
create("checkMarkTintMode") { view.checkMarkTintMode = parsePorterDuffMode(value) }
|
||||
create("checkMarkTint") { view.checkMarkTintList = parseColorStateList(context, value) }
|
||||
}
|
||||
}
|
||||
|
||||
+8
-30
@@ -17,45 +17,23 @@
|
||||
|
||||
package com.itsaky.androidide.inflater.internal.adapters
|
||||
|
||||
import android.content.Context
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import android.widget.CompoundButton
|
||||
import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.INamespace
|
||||
import com.itsaky.androidide.inflater.AttributeHandlerScope
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
|
||||
/**
|
||||
* Attribute adapter for [CompoundButton].
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
abstract class CompoundButtonAttrAdapter : ButtonAttrAdapter() {
|
||||
abstract class CompoundButtonAttrAdapter<T : CompoundButton> : ButtonAttrAdapter<T>() {
|
||||
|
||||
override fun apply(view: IView, attribute: IAttribute): Boolean {
|
||||
return doApply<CompoundButton>(view, attribute) {
|
||||
_: LayoutFile,
|
||||
context: Context,
|
||||
_: LayoutParams,
|
||||
_: INamespace,
|
||||
name: String,
|
||||
value: String ->
|
||||
var applied = true
|
||||
|
||||
when (name) {
|
||||
"buttonTint" -> buttonTintList = parseColorStateList(context, value)
|
||||
"button" -> buttonDrawable = parseDrawable(context, value)
|
||||
"buttonTintMode" -> buttonTintMode = parsePorterDuffMode(value)
|
||||
"checked" -> isChecked = parseBoolean(value = value, def = true)
|
||||
else -> applied = false
|
||||
}
|
||||
|
||||
if (!applied) {
|
||||
applied = super.apply(view, attribute)
|
||||
}
|
||||
|
||||
return@doApply applied
|
||||
}
|
||||
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
|
||||
super.createAttrHandlers(create)
|
||||
create("buttonTint") { view.buttonTintList = parseColorStateList(context, value) }
|
||||
create("button") { view.buttonDrawable = parseDrawable(context, value) }
|
||||
create("buttonTintMode") { view.buttonTintMode = parsePorterDuffMode(value) }
|
||||
create("checked") { view.isChecked = parseBoolean(value = value, def = true) }
|
||||
}
|
||||
|
||||
override fun applyBasic(view: IView) {
|
||||
|
||||
+1
-1
@@ -26,4 +26,4 @@ import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(EditText::class)
|
||||
open class EditTextAttrAdapter : TextViewAttrAdapter()
|
||||
open class EditTextAttrAdapter<T : EditText> : TextViewAttrAdapter<T>()
|
||||
|
||||
+7
-24
@@ -21,6 +21,7 @@ import android.content.Context
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import android.widget.FrameLayout
|
||||
import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
import com.itsaky.androidide.inflater.AttributeHandlerScope
|
||||
import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.INamespace
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
@@ -32,29 +33,11 @@ import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(FrameLayout::class)
|
||||
open class FrameLayoutAttrAdapter : ViewGroupAttrAdapter() {
|
||||
|
||||
override fun apply(view: IView, attribute: IAttribute): Boolean {
|
||||
return doApply<FrameLayout>(view, attribute) {
|
||||
_: LayoutFile,
|
||||
_: Context,
|
||||
_: LayoutParams,
|
||||
_: INamespace,
|
||||
name: String,
|
||||
value: String ->
|
||||
|
||||
var applied = true
|
||||
when (name) {
|
||||
"foregroundGravity" -> foregroundGravity = parseGravity(value)
|
||||
"measureAllChildren" -> measureAllChildren = parseBoolean(value)
|
||||
else -> applied = false
|
||||
}
|
||||
|
||||
if (!applied) {
|
||||
applied = super.apply(view, attribute)
|
||||
}
|
||||
|
||||
return@doApply applied
|
||||
}
|
||||
open class FrameLayoutAttrAdapter<T : FrameLayout> : ViewGroupAttrAdapter<T>() {
|
||||
|
||||
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
|
||||
super.createAttrHandlers(create)
|
||||
create("foregroundGravity") { view.foregroundGravity = parseGravity(value) }
|
||||
create("measureAllChildren") { view.measureAllChildren = parseBoolean(value) }
|
||||
}
|
||||
}
|
||||
|
||||
+18
-35
@@ -22,6 +22,7 @@ import android.gesture.GestureOverlayView
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import com.blankj.utilcode.util.ReflectUtils
|
||||
import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
import com.itsaky.androidide.inflater.AttributeHandlerScope
|
||||
import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.INamespace
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
@@ -33,42 +34,24 @@ import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(GestureOverlayView::class)
|
||||
open class GestureOverlayViewAttrAdapter : FrameLayoutAttrAdapter() {
|
||||
|
||||
override fun apply(view: IView, attribute: IAttribute): Boolean {
|
||||
return doApply<GestureOverlayView>(view, attribute) {
|
||||
_: LayoutFile,
|
||||
context: Context,
|
||||
_: LayoutParams,
|
||||
_: INamespace,
|
||||
name: String,
|
||||
value: String ->
|
||||
var applied = true
|
||||
when (name) {
|
||||
"eventsInterceptionEnabled" -> isEventsInterceptionEnabled = parseBoolean(value)
|
||||
"fadeDuration" ->
|
||||
ReflectUtils.reflect(gesture).field("mFadeDuration", parseLong(value, 150))
|
||||
"fadeEnabled" -> isFadeEnabled = parseBoolean(value)
|
||||
"fadeOffset" -> fadeOffset = parseLong(value, 420)
|
||||
"gestureColor" -> gestureColor = parseColor(context, value)
|
||||
"gestureStrokeAngleThreshold" -> gestureStrokeAngleThreshold = parseFloat(value)
|
||||
"gestureStrokeLengthThreshold" -> gestureStrokeLengthThreshold = parseFloat(value)
|
||||
"gestureStrokeSquarenessThreshold" -> gestureStrokeSquarenessTreshold = parseFloat(value)
|
||||
"gestureStrokeType" -> gestureStrokeType = parseGestureStrokeType(value)
|
||||
"gestureStrokeWidth" -> gestureStrokeWidth = parseFloat(value)
|
||||
"orientation" -> orientation = parseOrientation(value)
|
||||
"uncertainGestureColor" -> uncertainGestureColor = parseColor(context, value)
|
||||
else -> applied = false
|
||||
}
|
||||
|
||||
if (!applied) {
|
||||
applied = super.apply(view, attribute)
|
||||
}
|
||||
|
||||
return@doApply applied
|
||||
}
|
||||
open class GestureOverlayViewAttrAdapter<T : GestureOverlayView> : FrameLayoutAttrAdapter<T>() {
|
||||
|
||||
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
|
||||
super.createAttrHandlers(create)
|
||||
create("eventsInterceptionEnabled") { view.isEventsInterceptionEnabled = parseBoolean(value) }
|
||||
create("fadeDuration") { ReflectUtils.reflect(view).field("mFadeDuration", parseLong(value, 150)) }
|
||||
create("fadeEnabled") { view.isFadeEnabled = parseBoolean(value) }
|
||||
create("fadeOffset") { view.fadeOffset = parseLong(value, 420) }
|
||||
create("gestureColor") { view.gestureColor = parseColor(context, value) }
|
||||
create("gestureStrokeAngleThreshold") { view.gestureStrokeAngleThreshold = parseFloat(value) }
|
||||
create("gestureStrokeLengthThreshold") { view.gestureStrokeLengthThreshold = parseFloat(value) }
|
||||
create("gestureStrokeSquarenessThreshold") { view.gestureStrokeSquarenessTreshold = parseFloat(value) }
|
||||
create("gestureStrokeType") { view.gestureStrokeType = parseGestureStrokeType(value) }
|
||||
create("gestureStrokeWidth") { view.gestureStrokeWidth = parseFloat(value) }
|
||||
create("orientation") { view.orientation = parseOrientation(value) }
|
||||
create("uncertainGestureColor") { view.uncertainGestureColor = parseColor(context, value) }
|
||||
}
|
||||
|
||||
|
||||
protected open fun parseOrientation(value: String): Int {
|
||||
return if ("horizontal" == value) {
|
||||
GestureOverlayView.ORIENTATION_HORIZONTAL
|
||||
|
||||
+11
-33
@@ -17,14 +17,9 @@
|
||||
|
||||
package com.itsaky.androidide.inflater.internal.adapters
|
||||
|
||||
import android.content.Context
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import android.widget.GridLayout
|
||||
import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.INamespace
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
import com.itsaky.androidide.inflater.AttributeHandlerScope
|
||||
|
||||
/**
|
||||
* Attribute adapter for [GridLayout].
|
||||
@@ -32,33 +27,16 @@ import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(GridLayout::class)
|
||||
open class GridLayoutAttrAdapter : ViewGroupAttrAdapter() {
|
||||
override fun apply(view: IView, attribute: IAttribute): Boolean {
|
||||
return doApply<GridLayout>(view, attribute) {
|
||||
_: LayoutFile,
|
||||
_: Context,
|
||||
_: LayoutParams,
|
||||
_: INamespace,
|
||||
name: String,
|
||||
value: String ->
|
||||
var applied = true
|
||||
when (name) {
|
||||
"alignmentMode" -> alignmentMode = parseAlignmentMode(value)
|
||||
"columnCount" -> columnCount = parseInteger(value, Int.MIN_VALUE)
|
||||
"columnOrderPreserved" -> isColumnOrderPreserved = parseBoolean(value)
|
||||
"orientation" -> orientation = parseOrientation(value)
|
||||
"rowCount" -> rowCount = parseInteger(value, Int.MIN_VALUE)
|
||||
"rowOrderPreserved" -> isRowOrderPreserved = parseBoolean(value)
|
||||
"useDefaultMargins" -> useDefaultMargins = parseBoolean(value)
|
||||
else -> applied = false
|
||||
}
|
||||
|
||||
if (!applied) {
|
||||
applied = super.apply(view, attribute)
|
||||
}
|
||||
|
||||
return@doApply applied
|
||||
}
|
||||
open class GridLayoutAttrAdapter<T : GridLayout> : ViewGroupAttrAdapter<T>() {
|
||||
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
|
||||
super.createAttrHandlers(create)
|
||||
create("alignmentMode") { view.alignmentMode = parseAlignmentMode(value) }
|
||||
create("columnCount") { view.columnCount = parseInteger(value, Int.MIN_VALUE) }
|
||||
create("columnOrderPreserved") { view.isColumnOrderPreserved = parseBoolean(value) }
|
||||
create("orientation") { view.orientation = parseOrientation(value) }
|
||||
create("rowCount") { view.rowCount = parseInteger(value, Int.MIN_VALUE) }
|
||||
create("rowOrderPreserved") { view.isRowOrderPreserved = parseBoolean(value) }
|
||||
create("useDefaultMargins") { view.useDefaultMargins = parseBoolean(value) }
|
||||
}
|
||||
|
||||
protected open fun parseOrientation(value: String): Int {
|
||||
|
||||
+2
-1
@@ -25,4 +25,5 @@ import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(ImageButton::class) class ImageButtonAttrAdapter : ImageViewAttrAdapter()
|
||||
@ViewAdapter(ImageButton::class)
|
||||
open class ImageButtonAttrAdapter<T : ImageButton> : ImageViewAttrAdapter<T>()
|
||||
|
||||
+14
-36
@@ -17,8 +17,6 @@
|
||||
|
||||
package com.itsaky.androidide.inflater.internal.adapters
|
||||
|
||||
import android.content.Context
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import android.widget.ImageView
|
||||
import android.widget.ImageView.ScaleType
|
||||
import android.widget.ImageView.ScaleType.CENTER
|
||||
@@ -30,11 +28,9 @@ import android.widget.ImageView.ScaleType.FIT_START
|
||||
import android.widget.ImageView.ScaleType.FIT_XY
|
||||
import android.widget.ImageView.ScaleType.MATRIX
|
||||
import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.INamespace
|
||||
import com.itsaky.androidide.inflater.AttributeHandlerScope
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import com.itsaky.androidide.inflater.R
|
||||
import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
|
||||
/**
|
||||
* Attribute adpater [ImageView]s.
|
||||
@@ -42,38 +38,20 @@ import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(ImageView::class)
|
||||
open class ImageViewAttrAdapter : ViewAttrAdapter() {
|
||||
open class ImageViewAttrAdapter<T : ImageView> : ViewAttrAdapter<T>() {
|
||||
|
||||
override fun apply(view: IView, attribute: IAttribute): Boolean {
|
||||
return doApply<ImageView>(view, attribute) {
|
||||
_: LayoutFile,
|
||||
context: Context,
|
||||
_: LayoutParams,
|
||||
_: INamespace,
|
||||
name: String,
|
||||
value: String ->
|
||||
var applied = true
|
||||
|
||||
when (name) {
|
||||
"adjustViewBounds" -> adjustViewBounds = parseBoolean(value)
|
||||
"baseline" -> baseline = parseDimension(context, value, 0)
|
||||
"baselineAlignBottom" -> baselineAlignBottom = parseBoolean(value)
|
||||
"cropToPadding" -> cropToPadding = parseBoolean(value)
|
||||
"maxHeight" -> maxHeight = parseDimension(context, value, 0)
|
||||
"maxWidth" -> maxWidth = parseDimension(context, value, 0)
|
||||
"scaleType" -> scaleType = parseScaleType(value)
|
||||
"src" -> setImageDrawable(parseDrawable(context, value))
|
||||
"tint" -> imageTintList = parseColorStateList(context, value)
|
||||
"tintMode" -> imageTintMode = parsePorterDuffMode(value)
|
||||
else -> applied = false
|
||||
}
|
||||
|
||||
if (!applied) {
|
||||
applied = super.apply(view, attribute)
|
||||
}
|
||||
|
||||
return@doApply applied
|
||||
}
|
||||
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
|
||||
super.createAttrHandlers(create)
|
||||
create("adjustViewBounds") { view.adjustViewBounds = parseBoolean(value) }
|
||||
create("baseline") { view.baseline = parseDimension(context, value, 0) }
|
||||
create("baselineAlignBottom") { view.baselineAlignBottom = parseBoolean(value) }
|
||||
create("cropToPadding") { view.cropToPadding = parseBoolean(value) }
|
||||
create("maxHeight") { view.maxHeight = parseDimension(context, value, 0) }
|
||||
create("maxWidth") { view.maxWidth = parseDimension(context, value, 0) }
|
||||
create("scaleType") { view.scaleType = parseScaleType(value) }
|
||||
create("src") { view.setImageDrawable(parseDrawable(context, value)) }
|
||||
create("tint") { view.imageTintList = parseColorStateList(context, value) }
|
||||
create("tintMode") { view.imageTintMode = parsePorterDuffMode(value) }
|
||||
}
|
||||
|
||||
override fun applyBasic(view: IView) {
|
||||
|
||||
+13
-30
@@ -17,18 +17,14 @@
|
||||
|
||||
package com.itsaky.androidide.inflater.internal.adapters
|
||||
|
||||
import android.content.Context
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import android.widget.LinearLayout
|
||||
import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.AttributeHandlerScope
|
||||
import com.itsaky.androidide.inflater.INamespace
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import com.itsaky.androidide.inflater.IViewGroup
|
||||
import com.itsaky.androidide.inflater.LayoutBehavior
|
||||
import com.itsaky.androidide.inflater.LayoutBehavior.HORIZONTAL
|
||||
import com.itsaky.androidide.inflater.LayoutBehavior.VERTICAL
|
||||
import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
|
||||
/**
|
||||
* Attribute adapter for [LinearLayout].
|
||||
@@ -36,34 +32,21 @@ import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(LinearLayout::class)
|
||||
open class LinearLayoutAttrAdapter : ViewGroupAttrAdapter() {
|
||||
open class LinearLayoutAttrAdapter<T : LinearLayout> : ViewGroupAttrAdapter<T>() {
|
||||
|
||||
override fun apply(view: IView, attribute: IAttribute): Boolean {
|
||||
return doApply<LinearLayout>(view, attribute) {
|
||||
_: LayoutFile,
|
||||
_: Context,
|
||||
_: LayoutParams,
|
||||
_: INamespace,
|
||||
name: String,
|
||||
value: String ->
|
||||
var applied = true
|
||||
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
|
||||
super.createAttrHandlers(create)
|
||||
|
||||
when (name) {
|
||||
"baselineAligned" -> isBaselineAligned = parseBoolean(value)
|
||||
"baselineAlignedChildIndex" -> baselineAlignedChildIndex = parseInteger(value, childCount)
|
||||
"gravity" -> gravity = parseGravity(value)
|
||||
"measureWithLargestChild" -> isMeasureWithLargestChildEnabled = parseBoolean(value)
|
||||
"orientation" -> orientation = parseOrientation(value)
|
||||
"weightSum" -> weightSum = parseFloat(value)
|
||||
else -> applied = false
|
||||
}
|
||||
|
||||
if (!applied) {
|
||||
applied = super.apply(view, attribute)
|
||||
}
|
||||
|
||||
return@doApply applied
|
||||
create("baselineAligned") { view.isBaselineAligned = parseBoolean(value) }
|
||||
create("baselineAlignedChildIndex") {
|
||||
view.baselineAlignedChildIndex = parseInteger(value, view.childCount)
|
||||
}
|
||||
create("gravity") { view.gravity = parseGravity(value) }
|
||||
create("measureWithLargestChild") {
|
||||
view.isMeasureWithLargestChildEnabled = parseBoolean(value)
|
||||
}
|
||||
create("orientation") { view.orientation = parseOrientation(value) }
|
||||
create("weightSum") { view.weightSum = parseFloat(value) }
|
||||
}
|
||||
|
||||
override fun getLayoutBehavior(group: IViewGroup): LayoutBehavior {
|
||||
|
||||
+13
-33
@@ -18,16 +18,11 @@
|
||||
package com.itsaky.androidide.inflater.internal.adapters
|
||||
|
||||
import android.R.layout
|
||||
import android.content.Context
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.ListView
|
||||
import com.blankj.utilcode.util.SizeUtils
|
||||
import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.INamespace
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
import com.itsaky.androidide.inflater.AttributeHandlerScope
|
||||
|
||||
/**
|
||||
* Attribute adapter for [ListView].
|
||||
@@ -35,34 +30,19 @@ import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(ListView::class)
|
||||
class ListViewAttrAdapter : AbsListViewAttrAdapter() {
|
||||
open class ListViewAttrAdapter<T : ListView> : AbsListViewAttrAdapter<T>() {
|
||||
|
||||
override fun apply(view: IView, attribute: IAttribute): Boolean {
|
||||
return doApply<ListView>(view, attribute) {
|
||||
_: LayoutFile,
|
||||
context: Context,
|
||||
_: LayoutParams,
|
||||
_: INamespace,
|
||||
name: String,
|
||||
value: String ->
|
||||
|
||||
var applied = true
|
||||
when (name) {
|
||||
"divider" -> divider = parseDrawable(context, value)
|
||||
"dividerHeight" -> dividerHeight = parseDimension(context, value, SizeUtils.dp2px(1f))
|
||||
"entries" -> {
|
||||
val entries = parseStringArray(value)
|
||||
adapter = ArrayAdapter(context, layout.simple_list_item_1, entries)
|
||||
}
|
||||
"footerDividersEnabled" -> setFooterDividersEnabled(parseBoolean(value))
|
||||
"headerDividersEnabled" -> setHeaderDividersEnabled(parseBoolean(value))
|
||||
else -> applied = false
|
||||
}
|
||||
|
||||
if (!applied) {
|
||||
applied = super.apply(view, attribute)
|
||||
}
|
||||
return@doApply applied
|
||||
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
|
||||
super.createAttrHandlers(create)
|
||||
create("divider") { view.divider = parseDrawable(context, value) }
|
||||
create("dividerHeight") {
|
||||
view.dividerHeight = parseDimension(context, value, SizeUtils.dp2px(1f))
|
||||
}
|
||||
create("entries") {
|
||||
val entries = parseStringArray(value)
|
||||
view.adapter = ArrayAdapter(context, layout.simple_list_item_1, entries)
|
||||
}
|
||||
create("footerDividersEnabled") { view.setFooterDividersEnabled(parseBoolean(value)) }
|
||||
create("headerDividersEnabled") { view.setHeaderDividersEnabled(parseBoolean(value)) }
|
||||
}
|
||||
}
|
||||
|
||||
+44
-49
@@ -21,6 +21,7 @@ import android.content.Context
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import android.widget.ProgressBar
|
||||
import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
import com.itsaky.androidide.inflater.AttributeHandlerScope
|
||||
import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.INamespace
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
@@ -32,58 +33,52 @@ import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(ProgressBar::class)
|
||||
open class ProgressBarAttrAdapter : ViewAttrAdapter() {
|
||||
open class ProgressBarAttrAdapter<T : ProgressBar> : ViewAttrAdapter<T>() {
|
||||
|
||||
override fun apply(view: IView, attribute: IAttribute): Boolean {
|
||||
return doApply<ProgressBar>(view, attribute) {
|
||||
_: LayoutFile,
|
||||
context: Context,
|
||||
_: LayoutParams,
|
||||
_: INamespace,
|
||||
name: String,
|
||||
value: String ->
|
||||
var applied = true
|
||||
|
||||
when (name) {
|
||||
"indeterminate" -> isIndeterminate = parseBoolean(value)
|
||||
"indeterminateDrawable" -> indeterminateDrawable = parseDrawable(context, value)
|
||||
"indeterminateTint" -> indeterminateTintList = parseColorStateList(context, value)
|
||||
"indeterminateTintMode" -> indeterminateTintMode = parsePorterDuffMode(value)
|
||||
"max" -> max = parseInteger(value, 100)
|
||||
"maxHeight" ->
|
||||
if (isApi29()) {
|
||||
maxHeight = parseDimension(context, value, Int.MAX_VALUE)
|
||||
}
|
||||
"maxWidth" ->
|
||||
if (isApi29()) {
|
||||
maxWidth = parseDimension(context, value, Int.MAX_VALUE)
|
||||
}
|
||||
"min" -> min = parseInteger(value, 0)
|
||||
"minHeight" ->
|
||||
if (isApi29()) {
|
||||
minHeight = parseDimension(context, value, 0)
|
||||
}
|
||||
"minWidth" ->
|
||||
if (isApi29()) {
|
||||
minWidth = parseDimension(context, value, 0)
|
||||
}
|
||||
"progress" -> progress = parseInteger(value, 50)
|
||||
"progressBackgroundTint" -> progressBackgroundTintList = parseColorStateList(context, value)
|
||||
"progressBackgroundTintMode" -> progressBackgroundTintMode = parsePorterDuffMode(value)
|
||||
"progressDrawable" -> progressDrawable = parseDrawable(context, value)
|
||||
"progressTint" -> progressTintList = parseColorStateList(context, value)
|
||||
"progressTintMode" -> progressTintMode = parsePorterDuffMode(value)
|
||||
"secondaryProgress" -> secondaryProgress = parseInteger(value, 0)
|
||||
"secondaryProgressTint" -> secondaryProgressTintList = parseColorStateList(context, value)
|
||||
"secondaryProgressTintMode" -> secondaryProgressTintMode = parsePorterDuffMode(value)
|
||||
else -> applied = false
|
||||
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
|
||||
super.createAttrHandlers(create)
|
||||
create("indeterminate") { view.isIndeterminate = parseBoolean(value) }
|
||||
create("indeterminateDrawable") { view.indeterminateDrawable = parseDrawable(context, value) }
|
||||
create("indeterminateTint") { view.indeterminateTintList = parseColorStateList(context, value) }
|
||||
create("indeterminateTintMode") { view.indeterminateTintMode = parsePorterDuffMode(value) }
|
||||
create("max") { view.max = parseInteger(value, 100) }
|
||||
create("maxHeight") {
|
||||
if (isApi29()) {
|
||||
view.maxHeight = parseDimension(context, value, Int.MAX_VALUE)
|
||||
}
|
||||
|
||||
if (!applied) {
|
||||
applied = super.apply(view, attribute)
|
||||
}
|
||||
create("maxWidth") {
|
||||
if (isApi29()) {
|
||||
view.maxWidth = parseDimension(context, value, Int.MAX_VALUE)
|
||||
}
|
||||
|
||||
return@doApply applied
|
||||
}
|
||||
create("min") { view.min = parseInteger(value, 0) }
|
||||
create("minHeight") {
|
||||
if (isApi29()) {
|
||||
view.minHeight = parseDimension(context, value, 0)
|
||||
}
|
||||
}
|
||||
create("minWidth") {
|
||||
if (isApi29()) {
|
||||
view.minWidth = parseDimension(context, value, 0)
|
||||
}
|
||||
}
|
||||
create("progress") { view.progress = parseInteger(value, 50) }
|
||||
create("progressBackgroundTint") {
|
||||
view.progressBackgroundTintList = parseColorStateList(context, value)
|
||||
}
|
||||
create("progressBackgroundTintMode") {
|
||||
view.progressBackgroundTintMode = parsePorterDuffMode(value)
|
||||
}
|
||||
create("progressDrawable") { view.progressDrawable = parseDrawable(context, value) }
|
||||
create("progressTint") { view.progressTintList = parseColorStateList(context, value) }
|
||||
create("progressTintMode") { view.progressTintMode = parsePorterDuffMode(value) }
|
||||
create("secondaryProgress") { view.secondaryProgress = parseInteger(value, 0) }
|
||||
create("secondaryProgressTint") {
|
||||
view.secondaryProgressTintList = parseColorStateList(context, value)
|
||||
}
|
||||
create("secondaryProgressTintMode") {
|
||||
view.secondaryProgressTintMode = parsePorterDuffMode(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -25,4 +25,5 @@ import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(RadioButton::class) class RadioButtonAttrAdapter : CompoundButtonAttrAdapter()
|
||||
@ViewAdapter(RadioButton::class)
|
||||
open class RadioButtonAttrAdapter<T : RadioButton> : CompoundButtonAttrAdapter<T>()
|
||||
|
||||
+6
-29
@@ -17,14 +17,9 @@
|
||||
|
||||
package com.itsaky.androidide.inflater.internal.adapters
|
||||
|
||||
import android.content.Context
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import android.widget.RelativeLayout
|
||||
import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.INamespace
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
import com.itsaky.androidide.inflater.AttributeHandlerScope
|
||||
|
||||
/**
|
||||
* Attribute adapter for [RelativeLayout].
|
||||
@@ -32,29 +27,11 @@ import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(RelativeLayout::class)
|
||||
class RelativeLayoutAttrAdapter : ViewGroupAttrAdapter() {
|
||||
open class RelativeLayoutAttrAdapter<T : RelativeLayout> : ViewGroupAttrAdapter<T>() {
|
||||
|
||||
override fun apply(view: IView, attribute: IAttribute): Boolean {
|
||||
return doApply<RelativeLayout>(view, attribute) {
|
||||
file: LayoutFile,
|
||||
_: Context,
|
||||
_: LayoutParams,
|
||||
_: INamespace,
|
||||
name: String,
|
||||
value: String ->
|
||||
var applied = true
|
||||
|
||||
when (name) {
|
||||
"gravity" -> gravity = parseGravity(value)
|
||||
"ignoreGravity" -> ignoreGravity = parseId(file.resName, value)
|
||||
else -> applied = false
|
||||
}
|
||||
|
||||
if (!applied) {
|
||||
applied = super.apply(view, attribute)
|
||||
}
|
||||
|
||||
return@doApply applied
|
||||
}
|
||||
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
|
||||
super.createAttrHandlers(create)
|
||||
create("gravity") { view.gravity = parseGravity(value) }
|
||||
create("ignoreGravity") { view.ignoreGravity = parseId(file.resName, value) }
|
||||
}
|
||||
}
|
||||
|
||||
+5
-17
@@ -19,8 +19,7 @@ package com.itsaky.androidide.inflater.internal.adapters
|
||||
|
||||
import android.widget.SeekBar
|
||||
import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import com.itsaky.androidide.inflater.AttributeHandlerScope
|
||||
|
||||
/**
|
||||
* Attribute adapter for [SeekBar].
|
||||
@@ -28,22 +27,11 @@ import com.itsaky.androidide.inflater.IView
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(SeekBar::class)
|
||||
class SeekBarAttrAdapter : AbsSeekBarAttrAdapter() {
|
||||
open class SeekBarAttrAdapter<T : SeekBar> : AbsSeekBarAttrAdapter<T>() {
|
||||
|
||||
override fun apply(view: IView, attribute: IAttribute): Boolean {
|
||||
return doApply<SeekBar>(view, attribute) { _, context, _, _, name, value ->
|
||||
var applied = true
|
||||
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
|
||||
super.createAttrHandlers(create)
|
||||
|
||||
when (name) {
|
||||
"thumb" -> thumb = parseDrawable(context, value)
|
||||
else -> applied = false
|
||||
}
|
||||
|
||||
if (!applied) {
|
||||
applied = super.apply(view, attribute)
|
||||
}
|
||||
|
||||
return@doApply applied
|
||||
}
|
||||
create("thumb") { view.thumb = parseDrawable(context, value) }
|
||||
}
|
||||
}
|
||||
|
||||
+12
-31
@@ -17,14 +17,9 @@
|
||||
|
||||
package com.itsaky.androidide.inflater.internal.adapters
|
||||
|
||||
import android.content.Context
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import android.widget.Spinner
|
||||
import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.INamespace
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
import com.itsaky.androidide.inflater.AttributeHandlerScope
|
||||
|
||||
/**
|
||||
* Attribute adapter for [Spinner].
|
||||
@@ -32,31 +27,17 @@ import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(Spinner::class)
|
||||
class SpinnerAttrAdapter : AbsSpinnerAttrAdapter() {
|
||||
override fun apply(view: IView, attribute: IAttribute): Boolean {
|
||||
return doApply<Spinner>(view, attribute) {
|
||||
_: LayoutFile,
|
||||
context: Context,
|
||||
_: LayoutParams,
|
||||
_: INamespace,
|
||||
name: String,
|
||||
value: String ->
|
||||
var applied = true
|
||||
|
||||
when (name) {
|
||||
"dropDownHorizontalOffset" -> dropDownHorizontalOffset = parseDimension(context, value, 0)
|
||||
"dropDownVerticalOffset" -> dropDownVerticalOffset = parseDimension(context, value, 0)
|
||||
"dropDownWidth" -> dropDownWidth = parseDimension(context, value, 0)
|
||||
"gravity" -> gravity = parseGravity(value)
|
||||
"popupBackground" -> setPopupBackgroundDrawable(parseDrawable(context, value))
|
||||
else -> applied = false
|
||||
}
|
||||
|
||||
if (!applied) {
|
||||
applied = super.apply(view, attribute)
|
||||
}
|
||||
|
||||
return@doApply applied
|
||||
open class SpinnerAttrAdapter<T : Spinner> : AbsSpinnerAttrAdapter<T>() {
|
||||
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
|
||||
super.createAttrHandlers(create)
|
||||
create("dropDownHorizontalOffset") {
|
||||
view.dropDownHorizontalOffset = parseDimension(context, value, 0)
|
||||
}
|
||||
create("dropDownVerticalOffset") {
|
||||
view.dropDownVerticalOffset = parseDimension(context, value, 0)
|
||||
}
|
||||
create("dropDownWidth") { view.dropDownWidth = parseDimension(context, value, 0) }
|
||||
create("gravity") { view.gravity = parseGravity(value) }
|
||||
create("popupBackground") { view.setPopupBackgroundDrawable(parseDrawable(context, value)) }
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -24,4 +24,5 @@ import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
* Attribute adapter for [SurfaceView].
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(SurfaceView::class) class SurfaceViewAttrAdapter : ViewAttrAdapter()
|
||||
@ViewAdapter(SurfaceView::class)
|
||||
open class SurfaceViewAttrAdapter<T : SurfaceView> : ViewAttrAdapter<T>()
|
||||
|
||||
+19
-41
@@ -17,15 +17,10 @@
|
||||
|
||||
package com.itsaky.androidide.inflater.internal.adapters
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Typeface.DEFAULT
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import android.widget.Switch
|
||||
import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.INamespace
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
import com.itsaky.androidide.inflater.AttributeHandlerScope
|
||||
|
||||
/**
|
||||
* Attribute adapter for [Switch].
|
||||
@@ -33,40 +28,23 @@ import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(Switch::class)
|
||||
class SwitchAttrAdapter : CompoundButtonAttrAdapter() {
|
||||
override fun apply(view: IView, attribute: IAttribute): Boolean {
|
||||
return doApply<Switch>(view, attribute) {
|
||||
_: LayoutFile,
|
||||
context: Context,
|
||||
_: LayoutParams,
|
||||
_: INamespace,
|
||||
name: String,
|
||||
value: String ->
|
||||
var applied = true
|
||||
when (name) {
|
||||
"showText" -> showText = parseBoolean(value)
|
||||
"splitTrack" -> splitTrack = parseBoolean(value)
|
||||
"switchMinWidth" -> switchMinWidth = parseDimension(context, value, 0)
|
||||
"switchPadding" -> switchPadding = parseDimension(context, value, 0)
|
||||
"textOff" -> textOff = parseString(value)
|
||||
"textOn" -> textOn = parseString(value)
|
||||
"textStyle" -> setSwitchTypeface(DEFAULT, parseTextStyle(value))
|
||||
"thumb" -> thumbDrawable = parseDrawable(context, value)
|
||||
"thumbTextPadding" -> thumbTextPadding = parseDimension(context, value, 0)
|
||||
"thumbTint" -> thumbTintList = parseColorStateList(context, value)
|
||||
"thumbTintMode" -> thumbTintMode = parsePorterDuffMode(value)
|
||||
"track" -> trackDrawable = parseDrawable(context, value)
|
||||
"trackTint" -> trackTintList = parseColorStateList(context, value)
|
||||
"trackTintMode" -> trackTintMode = parsePorterDuffMode(value)
|
||||
"typeface" -> setSwitchTypeface(parseTypeface(value))
|
||||
else -> applied = false
|
||||
}
|
||||
|
||||
if (!applied) {
|
||||
applied = super.apply(view, attribute)
|
||||
}
|
||||
|
||||
return@doApply applied
|
||||
}
|
||||
open class SwitchAttrAdapter<T : Switch> : CompoundButtonAttrAdapter<T>() {
|
||||
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
|
||||
super.createAttrHandlers(create)
|
||||
create("showText") { view.showText = parseBoolean(value) }
|
||||
create("splitTrack") { view.splitTrack = parseBoolean(value) }
|
||||
create("switchMinWidth") { view.switchMinWidth = parseDimension(context, value, 0) }
|
||||
create("switchPadding") { view.switchPadding = parseDimension(context, value, 0) }
|
||||
create("textOff") { view.textOff = parseString(value) }
|
||||
create("textOn") { view.textOn = parseString(value) }
|
||||
create("textStyle") { view.setSwitchTypeface(DEFAULT, parseTextStyle(value)) }
|
||||
create("thumb") { view.thumbDrawable = parseDrawable(context, value) }
|
||||
create("thumbTextPadding") { view.thumbTextPadding = parseDimension(context, value, 0) }
|
||||
create("thumbTint") { view.thumbTintList = parseColorStateList(context, value) }
|
||||
create("thumbTintMode") { view.thumbTintMode = parsePorterDuffMode(value) }
|
||||
create("track") { view.trackDrawable = parseDrawable(context, value) }
|
||||
create("trackTint") { view.trackTintList = parseColorStateList(context, value) }
|
||||
create("trackTintMode") { view.trackTintMode = parsePorterDuffMode(value) }
|
||||
create("typeface") { view.setSwitchTypeface(parseTypeface(value)) }
|
||||
}
|
||||
}
|
||||
|
||||
+81
-90
@@ -17,19 +17,15 @@
|
||||
|
||||
package com.itsaky.androidide.inflater.internal.adapters
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Typeface
|
||||
import android.text.TextUtils
|
||||
import android.text.util.Linkify
|
||||
import android.util.TypedValue
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import android.widget.TextView
|
||||
import com.blankj.utilcode.util.SizeUtils
|
||||
import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.INamespace
|
||||
import com.itsaky.androidide.inflater.AttributeHandlerScope
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
import com.itsaky.androidide.inflater.utils.newAttribute
|
||||
import java.util.regex.Pattern
|
||||
|
||||
@@ -39,93 +35,88 @@ import java.util.regex.Pattern
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(TextView::class)
|
||||
open class TextViewAttrAdapter : ViewAttrAdapter() {
|
||||
open class TextViewAttrAdapter<T : TextView> : ViewAttrAdapter<T>() {
|
||||
|
||||
override fun apply(view: IView, attribute: IAttribute): Boolean {
|
||||
return doApply<TextView>(view, attribute) {
|
||||
_: LayoutFile,
|
||||
context: Context,
|
||||
_: LayoutParams,
|
||||
_: INamespace,
|
||||
name: String,
|
||||
value: String ->
|
||||
val drawables = compoundDrawables
|
||||
val drawablesRelative = compoundDrawablesRelative
|
||||
var applied = true
|
||||
when (name) {
|
||||
"autoLink" -> autoLinkMask = parseAutoLinkMask(value)
|
||||
"drawableLeft" ->
|
||||
setCompoundDrawables(
|
||||
parseDrawable(context, value),
|
||||
drawables[1],
|
||||
drawables[2],
|
||||
drawables[3]
|
||||
)
|
||||
"drawableTop" ->
|
||||
setCompoundDrawables(
|
||||
drawables[0],
|
||||
parseDrawable(context, value),
|
||||
drawables[2],
|
||||
drawables[3]
|
||||
)
|
||||
"drawableRight" ->
|
||||
setCompoundDrawables(
|
||||
drawables[0],
|
||||
drawables[1],
|
||||
parseDrawable(context, value),
|
||||
drawables[3]
|
||||
)
|
||||
"drawableBottom" ->
|
||||
setCompoundDrawables(
|
||||
drawables[0],
|
||||
drawables[1],
|
||||
drawables[2],
|
||||
parseDrawable(context, value)
|
||||
)
|
||||
"drawableStart" ->
|
||||
setCompoundDrawables(
|
||||
parseDrawable(context, value),
|
||||
drawablesRelative[1],
|
||||
drawablesRelative[2],
|
||||
drawablesRelative[3]
|
||||
)
|
||||
"drawableEnd" ->
|
||||
setCompoundDrawables(
|
||||
drawablesRelative[0],
|
||||
drawablesRelative[1],
|
||||
parseDrawable(context, value),
|
||||
drawablesRelative[3]
|
||||
)
|
||||
"drawablePadding" -> compoundDrawablePadding = parseDimension(context, value, 0)
|
||||
"ellipsize" -> ellipsize = parseEllipsize(value)
|
||||
"gravity" -> gravity = parseGravity(value)
|
||||
"hint" -> hint = parseString(value)
|
||||
"letterSpacing" -> letterSpacing = parseFloat(value)
|
||||
"lineHeight" -> setLines(parseInteger(value, Int.MAX_VALUE))
|
||||
"linksClickable" -> linksClickable = parseBoolean(value)
|
||||
"marqueeRepeatLimit" -> marqueeRepeatLimit = parseInteger(value, Int.MAX_VALUE)
|
||||
"maxLines" -> maxLines = parseInteger(value, Int.MAX_VALUE)
|
||||
"minLines" -> minLines = parseInteger(value, 1)
|
||||
"singleLine" -> isSingleLine = parseBoolean(value)
|
||||
"text" -> text = parseString(value)
|
||||
"textAllCaps" -> isAllCaps = parseBoolean(value)
|
||||
"textColor" -> setTextColor(parseColor(context, value))
|
||||
"textColorHint" -> setHintTextColor(parseColor(context, value))
|
||||
"textSize" ->
|
||||
setTextSize(
|
||||
TypedValue.COMPLEX_UNIT_PX,
|
||||
parseDimensionF(context, value, SizeUtils.sp2px(14f).toFloat())
|
||||
)
|
||||
"textStyle" -> setTypeface(typeface, parseTextStyle(value))
|
||||
"typeface" -> typeface = parseTypeface(value)
|
||||
else -> applied = false
|
||||
}
|
||||
|
||||
if (!applied) {
|
||||
applied = super.apply(view, attribute)
|
||||
}
|
||||
return@doApply applied
|
||||
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
|
||||
super.createAttrHandlers(create)
|
||||
create("autoLink") { view.autoLinkMask = parseAutoLinkMask(value) }
|
||||
create("drawableLeft") {
|
||||
val drawables = view.compoundDrawables
|
||||
view.setCompoundDrawables(
|
||||
parseDrawable(context, value),
|
||||
drawables[1],
|
||||
drawables[2],
|
||||
drawables[3]
|
||||
)
|
||||
}
|
||||
create("drawableTop") {
|
||||
val drawables = view.compoundDrawables
|
||||
view.setCompoundDrawables(
|
||||
drawables[0],
|
||||
parseDrawable(context, value),
|
||||
drawables[2],
|
||||
drawables[3]
|
||||
)
|
||||
}
|
||||
create("drawableRight") {
|
||||
val drawables = view.compoundDrawables
|
||||
view.setCompoundDrawables(
|
||||
drawables[0],
|
||||
drawables[1],
|
||||
parseDrawable(context, value),
|
||||
drawables[3]
|
||||
)
|
||||
}
|
||||
create("drawableBottom") {
|
||||
val drawables = view.compoundDrawables
|
||||
view.setCompoundDrawables(
|
||||
drawables[0],
|
||||
drawables[1],
|
||||
drawables[2],
|
||||
parseDrawable(context, value)
|
||||
)
|
||||
}
|
||||
create("drawableStart") {
|
||||
val drawablesRelative = view.compoundDrawablesRelative
|
||||
view.setCompoundDrawables(
|
||||
parseDrawable(context, value),
|
||||
drawablesRelative[1],
|
||||
drawablesRelative[2],
|
||||
drawablesRelative[3]
|
||||
)
|
||||
}
|
||||
create("drawableEnd") {
|
||||
val drawablesRelative = view.compoundDrawablesRelative
|
||||
view.setCompoundDrawables(
|
||||
drawablesRelative[0],
|
||||
drawablesRelative[1],
|
||||
parseDrawable(context, value),
|
||||
drawablesRelative[3]
|
||||
)
|
||||
}
|
||||
create("drawablePadding") { view.compoundDrawablePadding = parseDimension(context, value, 0) }
|
||||
create("ellipsize") { view.ellipsize = parseEllipsize(value) }
|
||||
create("gravity") { view.gravity = parseGravity(value) }
|
||||
create("hint") { view.hint = parseString(value) }
|
||||
create("letterSpacing") { view.letterSpacing = parseFloat(value) }
|
||||
create("lineHeight") { view.setLines(parseInteger(value, Int.MAX_VALUE)) }
|
||||
create("linksClickable") { view.linksClickable = parseBoolean(value) }
|
||||
create("marqueeRepeatLimit") { view.marqueeRepeatLimit = parseInteger(value, Int.MAX_VALUE) }
|
||||
create("maxLines") { view.maxLines = parseInteger(value, Int.MAX_VALUE) }
|
||||
create("minLines") { view.minLines = parseInteger(value, 1) }
|
||||
create("singleLine") { view.isSingleLine = parseBoolean(value) }
|
||||
create("text") { view.text = parseString(value) }
|
||||
create("textAllCaps") { view.isAllCaps = parseBoolean(value) }
|
||||
create("textColor") { view.setTextColor(parseColor(context, value)) }
|
||||
create("textColorHint") { view.setHintTextColor(parseColor(context, value)) }
|
||||
create("textSize") {
|
||||
view.setTextSize(
|
||||
TypedValue.COMPLEX_UNIT_PX,
|
||||
parseDimensionF(context, value, SizeUtils.sp2px(14f).toFloat())
|
||||
)
|
||||
}
|
||||
create("textStyle") { view.setTypeface(view.typeface, parseTextStyle(value)) }
|
||||
create("typeface") { view.typeface = parseTypeface(value) }
|
||||
}
|
||||
|
||||
override fun applyBasic(view: IView) {
|
||||
|
||||
+1
-1
@@ -26,4 +26,4 @@ import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(TextureView::class)
|
||||
class TextureViewAttrAdapter : ViewAttrAdapter()
|
||||
open class TextureViewAttrAdapter<T : TextureView> : ViewAttrAdapter<T>()
|
||||
+7
-30
@@ -17,16 +17,10 @@
|
||||
|
||||
package com.itsaky.androidide.inflater.internal.adapters
|
||||
|
||||
import android.R.attr.button
|
||||
import android.content.Context
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import android.widget.ToggleButton
|
||||
import com.blankj.utilcode.util.ReflectUtils.reflect
|
||||
import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.INamespace
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
import com.itsaky.androidide.inflater.AttributeHandlerScope
|
||||
|
||||
/**
|
||||
* Attribute adapter for [ToggleButton].
|
||||
@@ -34,29 +28,12 @@ import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(ToggleButton::class)
|
||||
class ToggleButtonAttrAdapter : CompoundButtonAttrAdapter() {
|
||||
open class ToggleButtonAttrAdapter<T : ToggleButton> : CompoundButtonAttrAdapter<T>() {
|
||||
|
||||
override fun apply(view: IView, attribute: IAttribute): Boolean {
|
||||
return doApply<ToggleButton>(view, attribute) {
|
||||
_: LayoutFile,
|
||||
_: Context,
|
||||
_: LayoutParams,
|
||||
_: INamespace,
|
||||
name: String,
|
||||
value: String ->
|
||||
var applied = true
|
||||
when (name) {
|
||||
"disabledAlpha" -> reflect(button).field("mDisabledAlpha", parseFloat(value, 0.5f))
|
||||
"textOff" -> textOff = parseString(value)
|
||||
"textOn" -> textOn = parseString(value)
|
||||
else -> applied = false
|
||||
}
|
||||
|
||||
if (!applied) {
|
||||
applied = super.apply(view, attribute)
|
||||
}
|
||||
|
||||
return@doApply applied
|
||||
}
|
||||
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
|
||||
super.createAttrHandlers(create)
|
||||
create("disabledAlpha") { reflect(view).field("mDisabledAlpha", parseFloat(value, 0.5f)) }
|
||||
create("textOff") { view.textOff = parseString(value) }
|
||||
create("textOn") { view.textOn = parseString(value) }
|
||||
}
|
||||
}
|
||||
|
||||
+86
-127
@@ -30,14 +30,12 @@ import android.widget.RelativeLayout.*
|
||||
import androidx.annotation.ChecksSdkIntAtLeast
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.core.view.updatePaddingRelative
|
||||
import com.android.SdkConstants
|
||||
import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
import com.itsaky.androidide.inflater.AttributeHandlerScope
|
||||
import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.INamespace
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import com.itsaky.androidide.inflater.IViewAdapter
|
||||
import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
import com.itsaky.androidide.inflater.internal.ViewImpl
|
||||
import com.itsaky.androidide.inflater.utils.newAttribute
|
||||
|
||||
/**
|
||||
@@ -46,89 +44,93 @@ import com.itsaky.androidide.inflater.utils.newAttribute
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(forView = View::class)
|
||||
open class ViewAttrAdapter : IViewAdapter() {
|
||||
open class ViewAttrAdapter<T : View> : IViewAdapter<T>() {
|
||||
|
||||
override fun apply(view: IView, attribute: IAttribute): Boolean {
|
||||
return doApply<View>(view, attribute) { file, context, layoutParams, _, name, value ->
|
||||
var applied = true
|
||||
@Suppress("DEPRECATION")
|
||||
when (name) {
|
||||
"alpha" -> alpha = parseFloat(value)
|
||||
"background" -> background = parseDrawable(context, value)
|
||||
"backgroundTint" -> backgroundTintList = parseColorStateList(context, value)
|
||||
"backgroundTintMode" -> backgroundTintMode = parsePorterDuffMode(value)
|
||||
"clipToOutline" -> clipToOutline = parseBoolean(value)
|
||||
"contentDescription" -> contentDescription = parseString(value)
|
||||
"contextClickable" -> isContextClickable = parseBoolean(value)
|
||||
"defaultFocusHighlightEnabled" -> defaultFocusHighlightEnabled = parseBoolean(value)
|
||||
"drawingCacheQuality" -> drawingCacheQuality = parseDrawingCacheQuality(value)
|
||||
"duplicateParentState" -> isDuplicateParentStateEnabled = parseBoolean(value)
|
||||
"elevation" -> elevation = parseDimensionF(context, value)
|
||||
"fadeScrollbars" -> isScrollbarFadingEnabled = parseBoolean(value)
|
||||
"fadingEdgeLength" -> setFadingEdgeLength(parseDimension(context, value))
|
||||
"filterTouchesWhenObscured" -> filterTouchesWhenObscured = parseBoolean(value)
|
||||
"foreground" -> foreground = parseDrawable(context, value)
|
||||
"foregroundGravity" -> foregroundGravity = parseGravity(value)
|
||||
"foregroundTint" -> foregroundTintList = parseColorStateList(context, value)
|
||||
"foregroundTintMode" -> foregroundTintMode = parsePorterDuffMode(value)
|
||||
"id" -> id = parseId(file.resName, value)
|
||||
"minHeight" -> minimumWidth = parseDimension(context, value)
|
||||
"minWidth" -> minimumHeight = parseDimension(context, value)
|
||||
"padding" ->
|
||||
parseDimension(context, value).also {
|
||||
updatePadding(left = it, top = it, right = it, bottom = it)
|
||||
}
|
||||
"paddingLeft" -> updatePadding(left = parseDimension(context, value))
|
||||
"paddingTop" -> updatePadding(top = parseDimension(context, value))
|
||||
"paddingRight" -> updatePadding(right = parseDimension(context, value))
|
||||
"paddingBottom" -> updatePadding(bottom = parseDimension(context, value))
|
||||
"paddingStart" -> updatePaddingRelative(start = parseDimension(context, value))
|
||||
"paddingEnd" -> updatePaddingRelative(end = parseDimension(context, value))
|
||||
"rotation" -> rotation = parseFloat(value)
|
||||
"rotationX" -> rotationX = parseFloat(value)
|
||||
"rotationY" -> rotationY = parseFloat(value)
|
||||
"scaleX" -> scaleX = parseFloat(value)
|
||||
"scaleY" -> scaleY = parseFloat(value)
|
||||
"scrollX" -> scrollX = parseInteger(value)
|
||||
"scrollY" -> scrollY = parseInteger(value)
|
||||
"textAlignment" -> textAlignment = parseTextAlignment(value)
|
||||
"textDirection" -> textDirection = parseTextDirection(value)
|
||||
"tooltipText" -> tooltipText = parseString(value)
|
||||
"transformPivotX" -> pivotX = parseFloat(value)
|
||||
"transformPivotY" -> pivotY = parseFloat(value)
|
||||
"translationX" -> translationX = parseFloat(value)
|
||||
"translationY" -> translationY = parseFloat(value)
|
||||
"translationZ" -> translationZ = parseFloat(value)
|
||||
"visibility" -> visibility = parseVisibility(value)
|
||||
else -> applied = false
|
||||
}
|
||||
|
||||
if (!applied && layoutParams is LinearLayout.LayoutParams) {
|
||||
applied = applyLinearLayoutParams(layoutParams, name, value)
|
||||
}
|
||||
|
||||
if (!applied && layoutParams is RelativeLayout.LayoutParams) {
|
||||
applied = applyRelativeLayoutParams(layoutParams, file.resName, name, value)
|
||||
}
|
||||
|
||||
if (!applied && layoutParams is FrameLayout.LayoutParams) {
|
||||
applied = applyFrameLayoutParams(layoutParams, name, value)
|
||||
}
|
||||
|
||||
if (!applied && layoutParams is MarginLayoutParams) {
|
||||
applied = applyMarginParams(context, layoutParams, name, value)
|
||||
}
|
||||
|
||||
if (!applied) {
|
||||
applied = applyLayoutParams(context, layoutParams, name, value)
|
||||
}
|
||||
|
||||
if (applied) {
|
||||
this.layoutParams = layoutParams
|
||||
}
|
||||
|
||||
return@doApply applied
|
||||
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
|
||||
create("alpha") { view.alpha = parseFloat(value) }
|
||||
create("background") { view.background = parseDrawable(context, value) }
|
||||
create("backgroundTint") { view.backgroundTintList = parseColorStateList(context, value) }
|
||||
create("backgroundTintMode") { view.backgroundTintMode = parsePorterDuffMode(value) }
|
||||
create("clipToOutline") { view.clipToOutline = parseBoolean(value) }
|
||||
create("contentDescription") { view.contentDescription = parseString(value) }
|
||||
create("contextClickable") { view.isContextClickable = parseBoolean(value) }
|
||||
create("defaultFocusHighlightEnabled") {
|
||||
view.defaultFocusHighlightEnabled = parseBoolean(value)
|
||||
}
|
||||
create("drawingCacheQuality") {
|
||||
@Suppress("DEPRECATION")
|
||||
view.drawingCacheQuality = parseDrawingCacheQuality(value)
|
||||
}
|
||||
create("duplicateParentState") { view.isDuplicateParentStateEnabled = parseBoolean(value) }
|
||||
create("elevation") { view.elevation = parseDimensionF(context, value) }
|
||||
create("fadeScrollbars") { view.isScrollbarFadingEnabled = parseBoolean(value) }
|
||||
create("fadingEdgeLength") { view.setFadingEdgeLength(parseDimension(context, value)) }
|
||||
create("filterTouchesWhenObscured") { view.filterTouchesWhenObscured = parseBoolean(value) }
|
||||
create("foreground") { view.foreground = parseDrawable(context, value) }
|
||||
create("foregroundGravity") { view.foregroundGravity = parseGravity(value) }
|
||||
create("foregroundTint") { view.foregroundTintList = parseColorStateList(context, value) }
|
||||
create("foregroundTintMode") { view.foregroundTintMode = parsePorterDuffMode(value) }
|
||||
create("id") { view.id = parseId(file.resName, value) }
|
||||
create("minHeight") { view.minimumWidth = parseDimension(context, value) }
|
||||
create("minWidth") { view.minimumHeight = parseDimension(context, value) }
|
||||
create("padding") {
|
||||
parseDimension(context, value).also {
|
||||
view.updatePadding(left = it, top = it, right = it, bottom = it)
|
||||
}
|
||||
}
|
||||
create("paddingLeft") { view.updatePadding(left = parseDimension(context, value)) }
|
||||
create("paddingTop") { view.updatePadding(top = parseDimension(context, value)) }
|
||||
create("paddingRight") { view.updatePadding(right = parseDimension(context, value)) }
|
||||
create("paddingBottom") { view.updatePadding(bottom = parseDimension(context, value)) }
|
||||
create("paddingStart") { view.updatePaddingRelative(start = parseDimension(context, value)) }
|
||||
create("paddingEnd") { view.updatePaddingRelative(end = parseDimension(context, value)) }
|
||||
create("rotation") { view.rotation = parseFloat(value) }
|
||||
create("rotationX") { view.rotationX = parseFloat(value) }
|
||||
create("rotationY") { view.rotationY = parseFloat(value) }
|
||||
create("scaleX") { view.scaleX = parseFloat(value) }
|
||||
create("scaleY") { view.scaleY = parseFloat(value) }
|
||||
create("scrollX") { view.scrollX = parseInteger(value) }
|
||||
create("scrollY") { view.scrollY = parseInteger(value) }
|
||||
create("textAlignment") { view.textAlignment = parseTextAlignment(value) }
|
||||
create("textDirection") { view.textDirection = parseTextDirection(value) }
|
||||
create("tooltipText") { view.tooltipText = parseString(value) }
|
||||
create("transformPivotX") { view.pivotX = parseFloat(value) }
|
||||
create("transformPivotY") { view.pivotY = parseFloat(value) }
|
||||
create("translationX") { view.translationX = parseFloat(value) }
|
||||
create("translationY") { view.translationY = parseFloat(value) }
|
||||
create("translationZ") { view.translationZ = parseFloat(value) }
|
||||
create("visibility") { view.visibility = parseVisibility(value) }
|
||||
}
|
||||
|
||||
override fun AttributeHandlerScope<T>.applyLayoutParams() : Boolean {
|
||||
|
||||
var applied = false
|
||||
|
||||
if (layoutParams is LinearLayout.LayoutParams) {
|
||||
applied = applyLinearLayoutParams(layoutParams, name, value)
|
||||
}
|
||||
|
||||
if (!applied && layoutParams is RelativeLayout.LayoutParams) {
|
||||
applied = applyRelativeLayoutParams(layoutParams, file.resName, name, value)
|
||||
}
|
||||
|
||||
if (!applied && layoutParams is FrameLayout.LayoutParams) {
|
||||
applied = applyFrameLayoutParams(layoutParams, name, value)
|
||||
}
|
||||
|
||||
if (!applied && layoutParams is MarginLayoutParams) {
|
||||
applied = applyMarginParams(context, layoutParams, name, value)
|
||||
}
|
||||
|
||||
if (!applied) {
|
||||
applied = applyLayoutParams(context, layoutParams, name, value)
|
||||
}
|
||||
|
||||
if (applied) {
|
||||
view.layoutParams = layoutParams
|
||||
}
|
||||
|
||||
return applied
|
||||
}
|
||||
|
||||
override fun applyBasic(view: IView) {
|
||||
@@ -250,49 +252,6 @@ open class ViewAttrAdapter : IViewAdapter() {
|
||||
return applied
|
||||
}
|
||||
|
||||
protected open fun canHandleNamespace(namespace: INamespace): Boolean {
|
||||
return this.canHandleNamespace(namespace.uri)
|
||||
}
|
||||
protected open fun canHandleNamespace(nsUri: String): Boolean {
|
||||
return SdkConstants.ANDROID_URI == nsUri
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides easy access to various properties related to the view and attribute when applying an
|
||||
* attributes.
|
||||
*/
|
||||
protected open fun <T : View> doApply(
|
||||
view: IView,
|
||||
attribute: IAttribute,
|
||||
block:
|
||||
T.(
|
||||
file: LayoutFile,
|
||||
context: Context,
|
||||
layoutParams: LayoutParams,
|
||||
namespace: INamespace,
|
||||
name: String,
|
||||
value: String,
|
||||
) -> Boolean,
|
||||
): Boolean {
|
||||
if (!canHandleNamespace(attribute.namespace)) {
|
||||
return false
|
||||
}
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return (view.view as T).let {
|
||||
val file = (view as ViewImpl).file
|
||||
val applied =
|
||||
it.block(
|
||||
file,
|
||||
it.context,
|
||||
it.layoutParams,
|
||||
attribute.namespace,
|
||||
attribute.name,
|
||||
attribute.value
|
||||
)
|
||||
return@let applied
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun parseDrawingCacheQuality(value: String): Int {
|
||||
return com.itsaky.androidide.inflater.internal.utils.parseDrawingCacheQuality(value)
|
||||
}
|
||||
|
||||
+11
-27
@@ -21,6 +21,7 @@ import android.animation.LayoutTransition
|
||||
import android.content.Context
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import com.itsaky.androidide.inflater.AttributeHandlerScope
|
||||
import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.INamespace
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
@@ -35,34 +36,17 @@ import com.itsaky.androidide.inflater.internal.LayoutFile
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
abstract class ViewGroupAttrAdapter : ViewAttrAdapter(), IViewGroupAdapter {
|
||||
|
||||
override fun apply(view: IView, attribute: IAttribute): Boolean {
|
||||
return doApply<ViewGroup>(view, attribute) {
|
||||
_: LayoutFile,
|
||||
_: Context,
|
||||
_: LayoutParams,
|
||||
_: INamespace,
|
||||
name: String,
|
||||
value: String ->
|
||||
var applied = true
|
||||
when (name) {
|
||||
"animateLayoutChanges" -> layoutTransition = LayoutTransition()
|
||||
"clipChildren" -> clipChildren = parseBoolean(value)
|
||||
"clipToPadding" -> clipToPadding = parseBoolean(value)
|
||||
"descendantFocusability" -> descendantFocusability = parseDescendantsFocusability(value)
|
||||
"layoutMode" -> layoutMode = parseLayoutMode(value)
|
||||
else -> applied = false
|
||||
}
|
||||
|
||||
if (!applied) {
|
||||
applied = super.apply(view, attribute)
|
||||
}
|
||||
|
||||
return@doApply applied
|
||||
}
|
||||
abstract class ViewGroupAttrAdapter<T : ViewGroup> : ViewAttrAdapter<T>(), IViewGroupAdapter {
|
||||
|
||||
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
|
||||
super.createAttrHandlers(create)
|
||||
create("animateLayoutChanges") { view.layoutTransition = LayoutTransition() }
|
||||
create("clipChildren") { view.clipChildren = parseBoolean(value) }
|
||||
create("clipToPadding") { view.clipToPadding = parseBoolean(value) }
|
||||
create("descendantFocusability") { view.descendantFocusability = parseDescendantsFocusability(value) }
|
||||
create("layoutMode") { view.layoutMode = parseLayoutMode(value) }
|
||||
}
|
||||
|
||||
|
||||
override fun getLayoutBehavior(group: IViewGroup): LayoutBehavior {
|
||||
return TOP_LEFT
|
||||
}
|
||||
|
||||
+1
-1
@@ -26,4 +26,4 @@ import com.itsaky.androidide.annotations.inflater.ViewAdapter
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
@ViewAdapter(WebView::class)
|
||||
class WebViewAttrAdapter : AbsoluteLayoutAttrAdapter()
|
||||
open class WebViewAttrAdapter<T : WebView> : AbsoluteLayoutAttrAdapter<T>()
|
||||
Reference in New Issue
Block a user