我有两个实现相同功能的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。
我是否正确地解决了这个问题?反思是否会危害我的代码的未来证据?