7

我的问题是加载在 XML 中定义的字符串数组在应用程序中工作,但会导致 ADT 图形布局预览中的错误。

由于这个错误,现在我在 Graphical Layout 中看不到任何图形,并且很难使用其他图形。但是如果我构建和运行我的应用程序,视图正在加载和显示字符串。

所以我想我的代码是正确的,但要么:

  • 我缺少图形布局预览的一些限制和一些解决方法
  • 或者也许我遗漏了一些明显的东西并且做错了即使它似乎在应用程序中工作

我有一个自定义视图,其中我在 array.xml 文件中获得了我定义的数组。

public class ScoreTable extends View {
  [...]
  @Override
  protected void onDraw(Canvas canvas) {
    [...]
    int score_vals[] = getResources().getIntArray(R.array.score_vals);
    [...]
  }
  [...]
}

我的数组在 res/values/array.xml 中定义:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <array name="score_vals">
        <item >10</item>
        <item >20</item>
        <item >50</item>
    </array>
</resources>

图形布局为空白并显示:

Int array resource ID #0x7f050000
Exception details are logged in Window > Show View > Error Log

但是我当然有“public static final int score_vals=0x7f050000;” 在 R.java 中!

此错误的详细信息位于 50 深的堆栈中,但继续如下:

android.content.res.Resources$NotFoundException: Int array resource ID #0x7f050000
    at android.content.res.Resources.getIntArray(Resources.java:405)
    at com.threecats.poker.ScoreTable.onDraw(ScoreTable.java:53)
    at android.view.View.draw(View.java:6740)
[...]

那么,getResources().getXXXArray() 是否应该在 ADT 图形布局预览的上下文中工作?

我想提一下,我尝试在 XML 中同时使用“array”和“array-integer”,它们都可以在应用程序中使用,但不能在预览中使用。我还尝试将 Context 从视图的构造函数中保存在私有 Context 成员中......也没有帮助。

4

2 回答 2

10

您的代码没问题,但不幸的是 ADT 插件中仍然存在一些错误,其中有一个。布局编辑器在渲染自定义视图时遇到问题。我有同样的问题,我发现的唯一锻炼是检查View.isInEditMode并以其他方式初始化 int 数组,但不是从资源中。因此,您的代码将如下所示:

int score_vals[];
if (isInEditMode()) {
    score_vals = { 10, 20, 50 };
} else {
    score_vals = getResources().getIntArray(R.array.score_vals);
}

顺便说一句,不要在您的onDraw方法中创建或加载任何资源。我想getResources().getIntArray使用某种缓存,但无论如何你的性能可能会受到影响。

于 2012-07-18T15:20:18.713 回答
0

我找到了一种解决方法,您必须劫持 android 自己的属性才能访问设计器中的资源。

下面应该提供这个想法,但你必须找到一个 int[] 类型的原生 android 属性

此自定义视图 XML 应在使用资源时呈现在图形布局预览中

<!-- Could override individual attributes here too rather than using a style -->
<com.github.espiandev.showcaseview.ShowcaseView
     style="@style/ShowcaseView"/>

styles.xml - 指定要使用的一些资源的样式

<style name="ShowcaseView" parent="match_fill">
    <!--# Cling drawable -->
    <item name="android:src">@drawable/cling</item>
    <!--# Title #-->
    <item name="android:contentDescription">@string/showcase_title</item>
    <!--# Description #-->
    <item name="android:description">@string/showcase_description</item>
    <!--# Button Text #-->
    <item name="android:text">@string/ok</item>
    <item name="sv_titleTextColor">#33B5E5</item>
    <item name="sv_detailTextColor">#FFFFFF</item>
    <item name="sv_backgroundColor">#3333B5E5</item>
    <item name="sv_buttonBackgroundColor">#3333B5E5</item>
    <item name="sv_buttonForegroundColor">#33B5E5</item>
</style>

attrs.xml - 与设计时预览兼容的自定义属性定义

<!-- The android attrs assume the corresponding android format / data type --> 
<declare-styleable name="ShowcaseView">
    <!--# Cling drawable -->
    <attr name="android:src"/>
    <!--# Title #-->
    <attr name="android:contentDescription"/>
    <!--# Description #-->
    <attr name="android:description"/>
    <!--# Button Text #-->
    <attr name="android:text"/>
    <attr name="sv_backgroundColor" format="color|reference" />
    <attr name="sv_detailTextColor" format="color|reference" />
    <attr name="sv_titleTextColor" format="color|reference" />
    <attr name="sv_buttonBackgroundColor" format="color|reference" />
    <attr name="sv_buttonForegroundColor" format="color|reference" />
</declare-styleable>

ShowcaseView.java - 在自定义视图中使用自定义属性

public ShowcaseView(Context context) {
    this(context, null, R.styleable.CustomTheme_showcaseViewStyle);
}

public ShowcaseView(Context context, AttributeSet attrs) {
    this(context, attrs, R.styleable.CustomTheme_showcaseViewStyle);
}

public ShowcaseView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    // Get the attributes for the ShowcaseView
    final TypedArray styled = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ShowcaseView, 0, 0);
    showcase = styled.getDrawable(R.styleable.ShowcaseView_android_src);
    titleText = styled.getString(R.styleable.ShowcaseView_android_contentDescription);
    subText = styled.getString(R.styleable.ShowcaseView_android_description);
    buttonText = styled.getString(R.styleable.ShowcaseView_android_text);
    backColor = styled.getInt(R.styleable.ShowcaseView_sv_backgroundColor, Color.argb(128, 80, 80, 80));
    detailTextColor = styled.getColor(R.styleable.ShowcaseView_sv_detailTextColor, Color.WHITE);
    titleTextColor = styled.getColor(R.styleable.ShowcaseView_sv_titleTextColor, Color.parseColor("#49C0EC"));
    styled.recycle();
    // Now make use of the fields / do further initialization ..
}
于 2013-07-19T09:15:56.967 回答