Reputation: 115
I am trying to create a custom ImageView class by extending the Android core ImageView class using Xamarin.Android. Below is a piece of the code in Java and an incomplete implementation in C#. I need help with the last 2 methods.
ANDROID JAVA CODE
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.widget.ImageView;
public class IconViewView extends ImageView {
private ColorStateList tint;
public IconView(Context context) {
super(context);
}
public IconView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public IconView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs, defStyle);
}
private void init(Context context, AttributeSet attrs, int defStyle) {
TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.IconView, defStyle, 0);
tint = a.getColorStateList(R.styleable.IconView_iconTint);
a.recycle();
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
if (tint != null && tint.isStateful()) {
updateTintColor();
}
}
public void setColorFilter(ColorStateList tint) {
this.tint = tint;
super.setColorFilter(tint.getColorForState(getDrawableState(), 0));
}
private void updateTintColor() {
int color = tint.getColorForState(getDrawableState(), 0);
setColorFilter(color);
}
}
ANDROID XAMARIN C# CODE
using Android.Content;
using Android.Content.Res;
using Android.Graphics;
using Android.Support.V4.Content;
using Android.Support.V4.Graphics.Drawable;
using Android.Util;
using Android.Widget;
namespace Example.Droid.App.Views
{
public class IconView : ImageView
{
private ColorStateList tint;
private Context context;
public IconView(Context context) :base(context)
{
Initialize(context, null, 0);
}
public IconView(Context context, IAttributeSet attrs) :
base(context, attrs)
{
Initialize(context, attrs, 0);
}
public IconView(Context context, IAttributeSet attrs, int defStyle) :
base(context, attrs, defStyle)
{
Initialize(context, attrs, defStyle);
}
void Initialize(Context mContext, IAttributeSet attrs, int defStyle)
{
context = mContext;
TypedArray a = context.ObtainStyledAttributes(attrs, Resource.Styleable.IconView, defStyle, 0);
tint = a.GetColorStateList(Resource.Styleable.IconView_iconTint);
a.Recycle();
}
protected override void DrawableStateChanged()
{
base.DrawableStateChanged();
if (tint != null && tint.IsStateful)
UpdateTintColor();
}
private void UpdateTintColor() {
/* I NEED HELP HERE */
}
public void SetColorFilter(ColorStateList tint) {
/* I NEED HELP HERE */
}
}
}
I need some help with these methods in Xamarin C#
private void UpdateTintColor() {
/* I NEED HELP HERE */
}
public void SetColorFilter(ColorStateList tint) {
/* I NEED HELP HERE */
}
Upvotes: 0
Views: 607
Reputation: 115
Finally I got it working. I extended the AppCompatImageView instead and thanks to Jon Douglas. Here is my code
1. App/View/IconView.cs
using System;
using Android.Content;
using Android.Content.Res;
using Android.Graphics;
using Android.Support.V4.Content;
using Android.Support.V4.Graphics.Drawable;
using Android.Support.V7.Widget;
using Android.Util;
using Android.Widget;
namespace Example.Droid.App.Views
{
public class IconView : AppCompatImageView
{
private ColorStateList tint;
private Context context;
public IconView(Context context) :base(context)
{
Initialize(context, null, 0);
}
public IconView(Context context, IAttributeSet attrs) :
base(context, attrs)
{
Initialize(context, attrs, 0);
}
public IconView(Context context, IAttributeSet attrs, int defStyle) :
base(context, attrs, defStyle)
{
Initialize(context, attrs, defStyle);
}
void Initialize(Context mContext, IAttributeSet attrs, int defStyle)
{
context = mContext;
TypedArray a = context.ObtainStyledAttributes(attrs, Resource.Styleable.IconView, defStyle, 0);
tint = a.GetColorStateList(Resource.Styleable.IconView_iconTint);
a.Recycle();
}
protected override void DrawableStateChanged()
{
base.DrawableStateChanged();
if (tint != null && tint.IsStateful)
UpdateTintColor();
}
private void UpdateTintColor()
{
var color = new Color(tint.GetColorForState(GetDrawableState(), new Color(0)));
SetColorFilter(color);
}
public void SetColorFilter(ColorStateList tint)
{
this.tint = tint;
base.SetColorFilter(new Color(tint.GetColorForState(GetDrawableState(), new Color(0))));
}
}
}
2. Part of Resources/layout/activity_example.axml
<Example.Droid.App.Views.IconView
android:layout_width="30dp"
android:layout_height="30dp"
app:srcCompat="@drawable/ic_camera"
android:layout_margin="5dp"
android:duplicateParentState="true"
app:iconTint="@color/primary_selector"/>
3. Resources/color/primary_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:color="#FFFFFF"/> <!-- pressed -->
<item android:state_selected="true"
android:state_focused="true"
android:color="#FFFFFF"/> <!-- focused -->
<item android:color="#CCCCCC"/> <!-- default -->
</selector>
4. Resources/values/attrs.xml
<?xml version="1.0" encoding="UTF-8" ?>
<resources>
<declare-styleable name="IconView">
<attr name="iconTint" format="reference|color" />
</declare-styleable>
</resources>
5. Resources/drawable/ic_camera.xml
<?xml version="1.0" encoding="UTF-8" ?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#000" android:pathData="M4,4H7L9,2H15L17,4H20A2,2 0 0,1 22,6V18A2,2 0 0,1 20,20H4A2,2 0 0,1 2,18V6A2,2 0 0,1 4,4M12,7A5,5 0 0,0 7,12A5,5 0 0,0 12,17A5,5 0 0,0 17,12A5,5 0 0,0 12,7M12,9A3,3 0 0,1 15,12A3,3 0 0,1 12,15A3,3 0 0,1 9,12A3,3 0 0,1 12,9Z" />
Cheers...
Upvotes: 0
Reputation: 13176
Use new Color()
and it's overloads whenever you need to convert an int to a Color
.
https://developer.xamarin.com/api/constructor/Android.Graphics.Color.Color/p/System.Int32/
private void UpdateTintColor()
{
var color = new Color(tint.GetColorForState(GetDrawableState(), new Color(0)));
SetColorFilter(color);
}
public void SetColorFilter(ColorStateList tint)
{
this.tint = tint;
base.SetColorFilter(new Color(tint.GetColorForState(GetDrawableState(), new Color(0))));
}
There are multiple outstanding bugs on this issue here:
https://bugzilla.xamarin.com/show_bug.cgi?id=36396#c3 https://bugzilla.xamarin.com/show_bug.cgi?id=57521
Please CC yourself on this issue and add a comment to describe the difficulty using this API without the extension methods and we'll work on improving these.
Upvotes: 2