Android:从另一个类中读取样式属性

时间:2014-05-04 01:32:52

标签: android

我有两个实现相同功能的View类(显示图像)。一个用于向后兼容并扩展ImageView,而另一个用于扩展TextureView,但仅在API 14+中可用。我设置了一个自定义工厂来选择在运行时使用的正确类(将MyViewProxy放在XML布局中)。

class View1 extends ImageView
{
    ...
}

class View2 extends TextureView // TextureView extends View (not ImageView)
{
    ...
}

class MyViewProxy extends ImageView
{
    ...
}

private static class MyViewFactory implements LayoutInflater.Factory
{
    @Override
    public View onCreateView( String name, Context context, AttributeSet attrs )
    {
        if( 0 == name.compareTo( "MyViewProxy" ) )
        {
            if( android.os.Build.VERSION.SDK_INT < 14 )
            {
                return new View1( context, attrs );
            }
            else
            {
                return new View2( context, attrs );
            }
        }
        return null;
    }
}

这一切都很好,除了View2(不扩展ImageView)应该检测到默认&#34; src&#34;要显示的图像,就像ImageView一样。 View1扩展了ImageView,因此它已经正常工作。

目标:能够转换&#34; src&#34;将XML属性转换为资源ID,并使用getResources()。openRawResource(resId)打开资源。 src属性的值通常采用&#34; @ drawable / image&#34;。

的形式

供参考,以下是ImageView如何设置其默认图像:

public ImageView(Context context, AttributeSet attrs, int defStyle)
{
    super(context, attrs, defStyle);
    initImageView();
    TypedArray a = context.obtainStyledAttributes(attrs,
        com.android.internal.R.styleable.ImageView, defStyle, 0);
    Drawable d = a.getDrawable(com.android.internal.R.styleable.ImageView_src);
    if (d != null)
    {
        setImageDrawable(d);
    }
    ...
}

我尝试在View2的构造函数中复制此代码,但得到了&#34;未定义的引用&#34;对于 com.android.internal.R 。我以为我可能会用反射来规避这一点,虽然这可能是一件粗略的事情。

这是我到目前为止所得到的。 此代码尚未生效

public View2( Context context, AttributeSet attrs, int defStyle )
{
    ...
    Class<?> clazz = Class.forName( "com.android.internal.R$styleable" );
    Field ImageView_field = clazz.getField( "ImageView" );
    Field ImageView_src_field = clazz.getField( "ImageView_src" );
    if( ImageView_field != null && ImageView_src_field != null )
    {
        if( ImageView_field.getType().isArray() )
        {
            Class<?> type = ImageView_field.getType().getComponentType();
            Object array = ImageView_field.get( clazz );
            if( type == Integer.TYPE )
            {
                int[] ImageView_intArray = (int[]) array;
                TypedArray aInternal = context.obtainStyledAttributes( attrs, ImageView_intArray, defStyle, 0 );

                int srcId = ImageView_src_field.getInt( clazz );
                String src = aInternal.getString( srcId );
                if( src != null )
                {
                    File testfile = new File( src );
                    boolean exists = testfile.exists();
                    //InputStream is = context.getAssets().open( src ); // throws FileNotFoundException
                    int resId = context.getResources().getIdentifier( src, "drawable", context.getPackageName() ); // returns 0
                    InputStream is = context.getResources().openRawResource( resId );
                    if( is != null )
                    {
                    }
                }

                aInternal.recycle();
            }
        }
    }
}

使用反射,我可以访问&#34; src&#34;变量正确,在我的测试中是&#34; res / drawable-hdpi / image.bmp&#34; (来自&#34; @ drawable / image&#34;在XML中)。从那里,我该如何实际打开它? AssetManager.open()抛出FileNotFoundException,Resources.getIdentifier()返回0,File.exists()返回false。

我是否正确地解决了这个问题?反思是否会危害我的代码的未来证据?

0 个答案:

没有答案