Con el nuevo soporte para android update, vector dibujables obtener compatibilidad con versiones anteriores. Tengo un vector de la imagen con varias rutas de acceso. Quiero que el color de los caminos para el cambio en el clic de un botón o mediante programación basado en un valor de entrada. Es posible acceder al parámetro nombre del trazado de vectores? Y, a continuación, cambiar el color.

  • puede teñir todo el vector, pero no solo los componentes de la trayectoria
InformationsquelleAutor suku | 2016-02-25

8 Comentarios

  1. 16

    Utilice esta opción para cambiar un camino de color en su vector de la imagen

    VectorChildFinder vector = new VectorChildFinder(this, R.drawable.my_vector, imageView);
    
    VectorDrawableCompat.VFullPath path1 = vector.findPathByName("path1");
    path1.setFillColor(Color.RED); 

    Biblioteca está aquí: https://github.com/devsideal/VectorChildFinder

    • Pero ya no en Maven?
    • A su disposición, en Maven jitpack.io/#devsideal/VectorChildFinder/1.0.0
    • Ahh, no me han jitpack.io añadido. Ahora la encuentra, saludos!
    • No hay una forma de cambiar el color de algo dentro de la VectorDrawable, sin una biblioteca? No hay nada en la biblioteca de compatibilidad para esto?
    • No, no he encontrado ninguna manera, sin embargo, que la empecé a usar este.
    • Yo couldnot encontrar la forma de cambiar la ruta de acceso en el interior del grupo. Alguna solución?

  2. 51

    El color de todo el vector puede ser cambiado usando setTint.

    Usted tiene que configurar su ImageView en su archivo de diseño como este:

    <ImageView
        android:id="@+id/myImageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:tint="@color/my_nice_color"
        android:src="@drawable/ic_my_drawable"
        android:scaleType="fitCenter" />

    A continuación, cambiar el color de la imagen:

    DrawableCompat.setTint(myImageView.getDrawable(), ContextCompat.getColor(context, R.color.another_nice_color));

    Nota: myImageView.getDrawable() da nullpointerexception si el vector de la imagen se establece en el imageView como telón de fondo.

    • Esto establece un color a toda la imagen, pero no de una determinada ruta de acceso del vector de la imagen.
    • android:tint debe ser establecido después de la configuración de android:src
    • Increíble! gracias.
    • ¿Qué acerca de Button? No hay android:tint para Button.
    • No sé el alcance de esta operación, pero tuve un problema en el ámbito de la Actividad; cuando puedo reemplazar Fragmentos, el tono cambio de no invalidar. He resuelto mi problema con imageView.setColorFilter
    • Esto sólo funciona para teñir todo el dibujable! +1

  3. 5

    Puede utilizar este método para cambiar el color en el bajo de la API para cambiar el vector de color en el fragmento

    int myVectorColor = ContextCompat.getColor(getActivity(), R.color.colorBlack);
                        myButton.getIcon().setColorFilter(myVectorColor, PorterDuff.Mode.SRC_IN);

    en lugar de getActivity debe utilizar MainActivity.esta para el cambio de vector de color en la actividad

  4. 2

    Que puede cambiar el color de camino individual en tiempo de ejecución, sin el uso de la reflexión.

    VectorMaster introduce un control dinámico sobre el vector dibujables. Cada aspecto de un vector de la imagen puede ser controlado de forma dinámica (a través de Java casos), el uso de esta biblioteca.

    Basta con agregar la siguiente dependencia de la aplicación a construir.gradle

    dependencies {
        compile 'com.sdsmdg.harjot:vectormaster:1.0.9'
    }

    En su caso, usted necesita un simple cambio de color:

    Vector ejemplo: your_vector.xml

    <vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:name="outline"
        android:pathData="M20.84,4..."
        android:strokeColor="#5D5D5D"
        android:fillColor="#00000000"
        android:strokeWidth="2"/>

    XML:

    <com.sdsmdg.harjot.vectormaster.VectorMasterView
        android:id="@+id/your_vector"
        android:layout_width="150dp"
        android:layout_height="150dp"
        app:vector_src="@drawable/your_drawable" />

    Java:

    VectorMasterView heartVector = (VectorMasterView) 
    findViewById(R.id.your_drawable);
    
    //find the correct path using name
    PathModel outline = heartVector.getPathModelByName("outline");
    
    //set the stroke color
    outline.setStrokeColor(Color.parseColor("#ED4337"));
    
    //set the fill color (if fill color is not set or is TRANSPARENT, then no fill is drawn)
    outline.setFillColor(Color.parseColor("#ED4337"));

    De: https://github.com/harjot-oberai/VectorMaster, bajo licencia MIT.

    Que tiene ahora el completo control sobre el vector dibujables.

    • Muy bonito. Mi svg no el uso de nombres y sería inpractical para editar y agregar nombres a mano.Iis es posible getPathModel por el índice en el array?
    • Se puede, pero necesitas al menos un nombre de grupo: el grupo que contiene las rutas de acceso, e.g: GroupModel groupModel = getVectorMasterDrawable().getGroupModelByName("groupName"); ArrayList<PathModel> pathModelArrayList = groupModel.getPathModels();
  5. 2

    Hay varias formas de hacer las mismas cosas, pero esto funciona para ambos Vector Dibujables así como SVG (Local/Red).

    imageView.setColorFilter(ContextCompat.getColor(context, 
    R.color.headPink), android.graphics.PorterDuff.Mode.SRC_IN);

    (cambiar R. de color.headPink con el color de su elección)

  6. 0

    Como dijo @Eyal en este post
    https://stackoverflow.com/a/32007436/4969047

    Que no cambiar el color de camino individual en tiempo de ejecución.
    Mirando el código fuente de VectorDrawableCompat, el único método para exponer el interior de elemento por su nombre es getTargetByName que está presente en el interior de la privado clase del estado VectorDrawableCompatState de VectorDrawableCompat.

    Ya que es un paquete privado (predeterminado): no se puede usar (a menos que utilice la reflexión).

    • por favor, puedes elaborar con el código de cómo la reflexión puede ser utilizado para lograr esto? Puede tomar tiempo, pero ayuda un montón de personas.
  7. 0

    Usted puede lograr esto sin una biblioteca, y combinar los Datos de Unión con Kotlin.

    ButtonBinding.kt

        @SuppressLint("PrivateResource")
        @BindingAdapter("drawable:start", "drawable:color", "button:isClicked", requireAll = false)
        @JvmStatic
        fun Button.setDrawableStartColor(@DrawableRes start: Int, @ColorRes color: Int, isClicked: Boolean) {
            this.apply [email protected]{
            context.apply [email protected]{
                val drawable = ContextCompat
                        .getDrawable(this, start)
                        ?.apply {
                            if (isClicked) {
                                setColorFilter(
                                        ContextCompat.getColor(this@ctx, color),
                                        PorterDuff.Mode.SRC_ATOP)
                            }
                        }
    
                setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null)
            }
            }
        }

    Puede utilizar directamente setCompoundDrawablesWithIntrinsicbounds o setCompoundDrawables( pero tiene que definir el actual intrínseca obligado, echa un vistazo a este artículo aquí

    my_fragment.xml

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            xmlns:drawable="http://schemas.android.com/apk/res-auto">
    
        <data>
    
            <import type="your.package.R"/>
    
            <variable
                name="actionListener"
                type="your.package.mvvmV2.account.profile.ProfileActionListener"/>
    
            <variable
                name="profileResponse"
                type="your.package.data.model.ProfileResponse"/>
    
            <variable
                name="viewModel"
                type="your.package.mvvmV2.home.HomeViewModel"/>
        </data>
                <Button
                    drawable:color="@{R.color.white}"
                    drawable:start="@{R.drawable.ic_person_blue}"
                    android:id="@+id/buttonProfile"
    </layout>

    Para la instalación haga clic en el oyente, usted puede hacer esto siguiendo así:

    YourFragment.kt

        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
            mViewBinding = AccountFragmentV2Binding
                    .inflate(inflater, container, false)
                    .apply {
                        viewModel = mViewModel //also, assign the correct view model to your xml
                        actionListener = this@AccountFragment
                        setLifecycleOwner(this@AccountFragment) //don't forget this
                    }
    
            return mViewBinding.root
        }
    
        override fun onProfileClicked(v: View) {
            mViewBinding.apply {
                mViewModel.let {
                    //change and store the state, but don't forget to reset to default
                    it.clickState[R.drawable.v2_ic_person_blue] = v.isPressed
                }
                executePendingBindings() //update ui directly, without delays
            }
        }
    

    ViewModel.kt

    val clickState = ObservableArrayMap<Int, Boolean>()
    
        init {
            clickState[R.drawable.ic_aktivitas_blue] = false
            clickState[R.drawable.ic_person_blue] = false
            clickState[R.drawable.ic_bookmark_blue] = false
        }
    

    Definir el adaptador de enlace con el entero de los recursos en lugar de utilizar @color/o @dibujable. Si usted prefiere usar la @ anotación (e.g: drawable:start="@{@drawable/id}") en el XML.

    Cambiar el enlace de datos como este

    fun Button.setDrawable(start: Drawable, color: Color) {
    //do the conversion to int id, it will be a mess. that's why I stick to receive int id from resource instead
    }

    También, no se olvide de configurar este de @aminography

    Punto importante en el Uso de Android Vector de la Imagen
    Cuando se utiliza un android vector de la imagen y quieres tener la compatibilidad de la API inferior a 21, agregar los siguientes códigos para

    En la aplicación a nivel de generación.gradle:

    android {
        defaultConfig {
            vectorDrawables.useSupportLibrary = true
        }
    }

    En la clase de Aplicación:

    class MyApplication : Application() {
    
        override fun onCreate() {
            super.onCreate()
    
            AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
        }
    
    }

    Gracias a este respuesta aquí, @Varun aquí se explica de otra alternativa, el original de la respuesta para mi caso aquí

Dejar respuesta

Please enter your comment!
Please enter your name here