CornerCutLinearLayout
extiende LinearLayout
. Le permite cortar las esquinas de los padres con diferentes formas y crear una sombra adecuada para formas complejas. También le permite cortar las esquinas de cada niño.
Desarrollado por la compañía Devlight.
Además, utilizando las propiedades disponibles y los proveedores personalizados, estos cortes se pueden transformar en recortes de formas, tamaños, etc. Varios. El único propósito del widget es usarlo con niños sin transformaciones (como rotación, escala, transformaciones matriciales).
Características adicionales:
- Soporte RTL
- parámetros de diseño secundarios que le permiten anular los parámetros primarios predeterminados
- sombra personalizada
- divisores y proveedores personalizados
- recortes y proveedores personalizados
- proveedor de área visible con vista personalizada
Paso 1. Agregue el repositorio JitPack al archivo build.gradle
de su proyecto:
allprojects {
repositorio {
.. .
maven {url & # 39; https://jitpack.io & # 39; }
}
}
o
subproyectos {
repositorio {
.. .
{Experto
.. .
url = " https://jitpack.io "
}
}
}
Paso 2. Agregue la siguiente dependencia al archivo build.gradle
del módulo de destino:
dependencias {
Implementación & # 39; com.github.Devlight: CornerCutLinearLayout: 1.0.1 & # 39;
}
Para un uso rápido y simple que cubre la mayoría de los casos de uso, consulte la sección Conceptos básicos . Para una sección de uso más compleja Advanced podría ser útil.
Declaración XML
Todos los atributos del widget comienzan con el prefijo ccll_
. Los atributos de diseño para los niños comienzan con el prefijo layout_ccll_
respectivamente. Hay muchos atributos Para facilitar su uso, se separaron en algunas categorías con un prefijo inicial:
-
ccll_
occll_corner_cut
– atributos globales del widget -
ccll_child_
– atributos de corte secundarios globales -
ccll_custom_shadow
– atributos de sombra personalizados -
ccll_custom_divider
– atributos de divisor personalizados
< ioout 19orn90utLout.corn. .outcorn.outcorn.outcorn.outcorn.outcorn.outcorn.outcorn.outcorn.outcorn.outcorn.outcorn.outcorn.outcorn.outcorn.outcorn.outrorn.outcorn.outcorn.outcorn.outcorn.outrorn.outcorn.outcorn.outcorn.outcorn. .outcorn.outcorn.rc.
android : id = " @ + id / ccll_kotlin_synthetic_view "
android [ww= ] " match_parent "
android : layout_height = " wrap_content ] [19659022android: fondo = " #FFFFFF "
android : orientación = " vertical " [[[19659022]
aplicación : ccll_corner_cut_flag = " start_top | end_bottom "
[19459029[[65659031] [cc_90659031] 19659013] "" "
aplicación : ccll_corner_cut_type = " ovalado ]
aplicación : ccll_child_corner_cut_type = " oval_inverse "
aplicación : ccll_custom_shadow_color = " # FEB545 "
aplicación : 19 19909031 [cc65_31]] " 16dp "[19659074]>
< Ver
Android : layout_width = " match_parent "
Android : layout_height = " 50dp " [19659014] />
< Ver
Android : layout_width = " match_parent "
Android : layout_height = " 50dp " [19659014] />
</ io .devlight.xtreeivi.cornercutlinearlayout.CornerCutLinearLayout>
Declaración en código (Kotlin)
Todos los atributos XML corresponden a CornerCutLinearLayout
[propiedad] [19] (ccll_kotlin_synthetic_view) {
val densidad = resources.displayMetrics.density
cornerCutFlag = combine Flags ( CornerCutFlag . START_TOP CornerCutFlag . END_BOTTOM
setCornerCutSize (densidad * 24 )
setCornerCutType ( CornerCutType . OVAL )
setChildCornerCutType ( CornerCutType . OVAL_INVERSE )
customShadowColor = Color .parseColor ( " # FEB545 " )
customShadowRadius = densidad * 16
}
El resultado visual sería el siguiente:
Anatomía de corte de esquina
Por defecto CornerCutType.OVAL
se usa para cortes de esquina principales y secundarios. El corte angular está limitado a su tamaño personal: profundidad y longitud .
Profundidad – en relación con el ancho de la orientación de los bordes del recorte. Longitud: en relación con la orientación de altura de los límites de recorte.
Cada una de las 4 dimensiones de los cortes de ángulo principales se puede especificar individualmente. Los cortes de esquina para niños pueden tener tamaños de lados separados ChildSideCutFlag.START y
ChildSideCutFlag.END. Los cortes de las esquinas de los niños también podrían rotarse. El ángulo de rotación podría ser opcionalmente reflejado.
Como puede ver, los cortes de las esquinas de los padres están puramente delimitados en las esquinas, pero los bordes cortantes de las esquinas del niño están "reflejados". De hecho, cada corte de la esquina del niño forma un camino de espejo. Se eligió esta estrategia para que los niños pudieran ignorar por separado la parte de contacto del corte de esquina.
Además, tenga en cuenta que profundidad y longitud depende de la dirección del diseño del widget ( LinearLayout.LAYOUT_DIRECTION_LTR
o LinearLayout.LAYOUT_DIRECTION_AYTAR_DIRECTION_RAYOUT_DIRECTION_AYT_DIRECTION y orientación (
LinearLayout.VERTICAL
o Tipos [19659018] 1965945 Hay 5 tipos de ángulos predefinidos cortados para ángulos padre e hijo *.
- Óvalo.
- Óvalo inverso. [19659099] Rectángulo. **
- Rectángulo inverso. **
- Bisel.
* - Cada tipo de esquina del niño, de hecho, se refleja y combina en una trayectoria por los respectivos tipos de corte del ángulo del ángulo. contacto con los niños. ** - Los tipos de rectángulo admiten un radio de esquina interior. Hay atributos respectivos y propiedades de visualización para los cortes padre e hijo.
Parámetros de diseño
Cualquier hijo puede sobrescribir propiedades definido por el padre y los atribuyentes relacionado con cortes de esquina.
En los siguientes ejemplos, el padre CornerCutLinearLayout
tiene ccll_child_corner_cut_type
= oval_inverse
y los hijos del medio tienen prioridad sobre cada esquina (19659) [19659[19659] I I .
...
aplicación : ccll_child_corner_cut_type = " oval_inverse " >
...
< Ver
...
aplicación : layout_ccll_start_top_corner_cut_type = " ovalado "
aplicación : layout_ccll_end_top_c_corn_end_top_ " bisel "
aplicación : layout_ccll_end_bottom_corner_cut_type = " rectángulo "
aplicación : layout_ccll_start_bottom_corner_cut_type = " rectángulo_inverso " />
...
</ io .devlight.xtreeivi.cornercutlinearlayout.CornerCutLinearLayout>
Edge Child
También hay parámetros de diseño especiales para el primero y el último hijo. Por ejemplo, en una orientación vertical, cuando los elementos superiores e inferiores no están alineados con la parte superior e inferior del elemento primario respectivamente, pueden sobrescribir cortar contacto * con el elemento primario.
< I . devlight.xtreeivi.cornercutlinearlayout.CornerCutLinearLayout
...
android : gravedad = " centro "
aplicación : ccll_child_corner_cut_type [194590] = [194590] " oval_inverse " >
< Ver
...
aplicación : layout_ccll_edge_child_parent_contact_corner_cut_type = " ovalado " />
...
< Ver
...
aplicación : layout_ccll_edge_child_parent_contact_corner_cut_type = " rectangle_inverse " />
</ i .devlight. 19659119] < I .devlight.xtreeivi.cornercutlinearlayout.CornerCutLinearLayout
...
aplicación : ccll_corner_cut_type = " bisel " >
< Ver
...
aplicación : layout_ccll_start_top_corner_cut_type = " ovalado "
aplicación : layout_ccll_end_top_c_c_corn_end_top_ " rectángulo "
aplicación : layout_ccll_edge_child_could_override_parent_corner_cut_type_if_edge_aligned = = ] verdadero verdadero
...
< Ver
...
aplicación : layout_ccll_start_bottom_corner_cut_type = " rectangle_inverse "
aplicación : layout_ildedgecutc_ " verdadero " />
</ io .devlight.xtreeivi.cornercutlinearlayout. ) Permanecen sin cambios
Propiedades secundarias de corte de esquina secundario
Existen las siguientes propiedades adicionales de corte de esquina secundario:
- Desplazamiento de profundidad y longitud
- Rotación de corte de esquina
Desplazamiento de profundidad y longitud
Cada lado de los cortes angulares del niño puede tener diferentes desplazamientos de profundidad y longitud (ver anatomía arriba).
Ejemplo 1 - Desplazamiento de profundidad
< io .devlight.xtreeivi.cornercutlinearlayout.CornerCutLinearLayout
...
aplicación : ccll_child_corner_cut_depth_offset = " @ dimen / offset_24 "
] [196590] " oval_inverse " >
...
< Ver
...
aplicación : layout_ccll_end_bottom_corner_cut_type = " oval "
app : layout_ccll_end_top_top_corty_end_top_topty_corner_top_top_top_top_top_top_top_top_top_top_ " rectángulo_inverso "
aplicación : layout_ccll_start_bottom_corner_cut_type = " bisel [19452929: layout_ccll_start_top_corner_cut_type = " rectángulo " />
...
</ io .devlight.xtreeivi.cornercutlinearlayout.CornerCutLinearLayout>
Ejemplo 2 - Desplazamiento de profundidad y longitud
] ] ] ] ] ] ] . .xtreeivi.cornercutlinearlayout.CornerCutLinearLayout
...
aplicación : ccll_child_corner_cut_type = " bisel "
aplicación cc " @ dimen / depth_offset "
aplicación : ccll_child_start_side_corner_cut_length_offset = " ] [ [ [ [19659031] ccll_corner_cut_type = " bisel " >
< Ver
...
Android : layout_marginTop = " @ dimen / offset_8 " [19659018] Android : layout_marginBottom = " @ dimen / offset_8 " [19659074] />
< Ver
...
Android : layout_marginTop = " @ dimen / offset_8 " [19659018] Android : layout_marginBottom = " @ dimen / offset_8 " [19659074] />
< Ver
...
Android : layout_marginTop = " @ dimen / offset_8 " [19659018] Android : layout_marginBottom = " @ dimen / offset_8 " [19659074] />
</ io .devlight.xtreeivi.cornercutlinearlayout.CornerCutLinearLayout>
Rotación
Cada lado puede rotar los cortes de ángulo para especificar el grado. Los atributos correspondientes son:
-
ccll_child_start_side_corner_cut_rotation_degree
-
ccll_child_end_side_corner_cut_rotation_degree [angolo19659264] también deben estar en el mismo ángulo que el ángulo. Para este fin, el atributo ccll_is_child_corner_cut_end_rotation_mirrored_from_start_rotation
podría ser útil.
Cada atributo tiene la función correspondiente CornerCutLinear
[1945] / 1928 / 65/90 19/65 .devlight.xtreeivi.cornercutlinearlayout.CornerCutLinearLayout
...
aplicación : ccll_child_corner_cut_type = " ovalado "
aplicación cc [19659031] " oval_inverse "
aplicación : ccll_child_end_side_corner_cut_rotation_degree = ]
] [
] ccll_child_start_side_corner_cut_rotation_degree = " 45 " [19659074]>
...
</ me .devlight.xtreeivi.cornercutlinearlayout.CornerCutLinearLayout>
Shadow
Uno de los principales problemas de la sombra de Android es que el camino debe ser convexo.
* - Una ruta es convexa si solo tiene un contorno y curvas siempre y solo en una dirección.
Este widget le permite sortear esta limitación creando automáticamente sombras complejas (evento con recortes). Obviamente, la sombra es personalizada y tiene sus pros y sus contras.
Pro :
- Shadow tiene propiedades personalizadas, como desplazamiento y color (ARGB).
- Admite una ruta compleja no convexa.
Contras :
- La sombra es artificial en comparación con la naturaleza de la sombra de la elevación nativa. Por lo tanto, no es posible confiar en la fuente global en un parámetro de posición y elevación de luz.
- Shadow utiliza el área de vista (relleno), que debe tener en cuenta durante el proceso de diseño o el cambio dinámico del radio de la sombra.
- La sombra NO depende del fondo de la vista o de los elementos secundarios y sus transparencias, por lo tanto, no puede ser una sombra compuesta con la superposición de diferentes niveles de transparencia (opacidad).
Por defecto, las sombras se construyen en un área principal acolchada combinada con todos los datos de recorte. Significa que la sombra NO depende del fondo de la vista, la presencia del niño o el fondo del niño. Pero este comportamiento podría ser modificado por CustomViewAreaProvider
(ver sección Avanzado ).
Shadow Padding . También es posible habilitar el relleno automático de la sombra personalizada ( ccll_is_custom_shadow_auto_padding_enabled), para permitir o evitar la sombra personalizada con respecto al relleno definido por el usuario. (
ccll_could_draw_custom_shadow_over_user_defined_padding). El último atributo solo funciona junto con el primer atributo habilitado.
Ejemplos:
Divisor personalizado [19659103] El divisor personalizado tiene una anatomía y propiedades similares a aquellas el divisor LinearLayout predeterminado. Los divisores personalizados no cambian el tamaño de la vista a diferencia del divisor LinearLayout predeterminado (este último agrega espacio en la posición especificada por la bandera igual al ancho o la altura del divisor). Los divisores personalizados se ahogan en la vista y divisores predeterminados. Puede combinar el divisor predeterminado y personalizado.
Los divisores personalizados tienen varias ventajas:
- muestran banderas adicionales
- tapas de línea (REDONDAS, BUTT, CUADRADAS)
- separador de línea de puntos separado
- (ancho y espacio)
- gravedad divisor de líneas discontinuas (
CustomDividerGravity
:START
CENTER
END
) - proveedor (ver sección Advanced )
Show Flags ( CustomDividerShowFlag
):
-
container_beginning
- a 190000 empezando - entre el contacto del margen de la primera vista y el padre. -
medio
- entre los márgenes de contacto de los niños -
final
final - entre el contacto del margen de la primera vista y el padre. [19659006]
container_end
- fin de la vista
Por defecto, los divisores personalizados no se tienen en cuenta cuando se genera sombra.
Atributos del divisor personalizado:
< io .devlight.xtreeivi.cornercutlinearlayout.CornerCutLinearLayout
...
aplicación : ccll_custom_divider_color = " @ color / divisor "
aplicación cc_civid " @ dimen / divider_dash_gap "
aplicación :
ccll_custom_divider_dash_width = @ [] [] [: ccll_custom_divider_height = " @ dimen / divider_height [19659022__line_19659031_c[19659031_cc] ] = " butt "
app : ccll_custom_divider_show_flag = " aplicación : ccll_custom_divider_gravity = " centro "
" ]: ccll_custom_ ding = " @ dimen / divider_padding "
aplicación : ccll_custom_d ivider_padding_start [1945902020_] @ [19659013__pad] "
aplicación : ccll_custom_divider_padding_end = " @ dimen / divider_padding_end> 194588]
...
</ I .devlight.xtreeivi.cornercutlinearlayout.CornerCutLinearLayout>
Ejemplos:
A veces puede necesitar un área visible más compleja, divisor , recortes, etc. Para estos fines, hay proveedores personalizados para los temas antes mencionados. Todos ellos podrían especificarse mediante programación. Para mayor comodidad, también hay funciones de estilo lambda de Kotlin para la mayoría de los proveedores.
Proveedor de corte de esquina
CornerCutProvider
le permite omitir cada una de las 4 esquinas del widget. Veamos un ejemplo.
Ejemplo 1 .
- Como de costumbre, defina nuestra vista en xml (este escenario) o créelo y configúrelo mediante programación.
< io .devlight.xtreeivi.cornercutlinearlayout.CornerCutLinearLayout
...
android : id = " @ + id / ccll_corner_cut_provider "
app : [19659031] ccll_eper = " @ dimen / corner_cut_depth "
app :: 19659031] ccll_corner_cut_length
= " aplicación : ccll_corner_cut_type = " bisel " />
- Establecer un [19459378] CornerCut00 19659379] ccll_corner_Cider_cutcut_cutcutter_cutcut_cutcut_cutider_cutcut_cut_cutider , corte, corte de esquina, rectF - >
cuando (corte de esquina) {
CornerCutFlag . START_TOP - > {
rectF.inset (recuadro, recuadro) // recuadro - propiedad definida globalmente
cutout.moveTo (rectF.left, rectF.top)
cutout.lineTo (rectF.right, rectF.top)
cutout.lineTo (rectF.left, rectF.bottom)
verdadero // acepta la esquina superior izquierda
}CornerCutFlag . END_BOTTOM - > {
// ruta pacífica compleja
...
verdadero // acepta la esquina inferior derecha
}más - > falso // omita el resto de las esquinas y trátelas según la configuración predeterminada
}
}