【问题标题】:obtainStyledAttributes works wronggainStyledAttributes 工作错误
【发布时间】:2019-01-03 17:58:43
【问题描述】:

我正在尝试创建自己的键盘。使用 Android 键盘不足以完成我的任务,因此我决定直接从 View.class 创建继承类。作为基础,我决定使用 Keyboard.class 的代码,然后开始一一改变。

我在尝试编译该类时遇到了很多问题,使用了一些反射和技巧来获取私有字段。我创建了文件 attrs 以便能够使用键盘的属性和标签。最后类编译并知道它崩溃了,因为应该从膨胀开始的参数是空的。

我发现方法 context.obtainStyledAttributes(attrs, R.styleable.MyKeyboardView);返回错误的结果和 a.getIndexCount();之后返回 0。

这是我的 attr.xml 文件:

<resources>
<declare-styleable name="MyKeyboardView">
    <attr name="keyBackground" format="reference" />
    <attr name="keyTextSize" format="dimension" />
    <attr name="labelTextSize" format="dimension" />
    <attr name="state_long_pressable" format="boolean" />
    <attr name="keyTextColor" format="color" />
    <attr name="keyPreviewLayout" format="reference" />
    <attr name="keyPreviewOffset" format="dimension" />
    <attr name="keyPreviewHeight" format="dimension" />
    <attr name="verticalCorrection" format="dimension" />
    <attr name="shadowColor" format="color" />
    <attr name="shadowRadius" format="float" />
    <attr name="backgroundDimAmount" format="float" />
    <attr name="popupLayout" format="reference" />
</declare-styleable>

这是我的键盘类的一部分:

public MyKeyboardView(Context context, AttributeSet attrs) {
    this(context, attrs, Resources.getSystem().getIdentifier("keyboardViewStyle", "attr", "android"));
}

public MyKeyboardView(Context context, AttributeSet attrs, int defStyleAttr) {
    this(context, attrs, defStyleAttr, 0);
}

public MyKeyboardView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);

    TypedArray a = context.obtainStyledAttributes(
            attrs, R.styleable.MyKeyboardView);

    LayoutInflater inflate =
            (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    int previewLayout = 0;
    int keyTextSize = 0;

    int n = a.getIndexCount();

这是我在布局中使用键盘的方式:

<FrameLayout
    android:layout_width="wrap_content"
    android:layout_height="240dp"
    android:layout_gravity="bottom">
    <com.test.features.keyboard.MyKeyboardView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/keyboard_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingTop="2.5dip"
        android:keyPreviewHeight="@dimen/key_height"
        android:shadowRadius="0"
        android:keyPreviewLayout="@layout/keyboard_key_preview"
        android:keyPreviewOffset="0dp"
        android:keyBackground="@drawable/keyboard_key_background"
        android:keyTextColor="@color/keyboard_key_color"
        android:background="@color/primary"
        android:popupLayout="@layout/keyboard_popup_layout"/>

尝试像这样使用它,length() 返回 11,但 switch case 几乎找不到匹配项。如果找到,则使用默认值:

int n = a.length();

    for (int i = 0; i < n; i++) {
        int attr = a.getIndex(i);

        switch (attr) {
            case R.styleable.MyKeyboardView_keyBackground:
                mKeyBackground = a.getDrawable(attr);
                break;
            case R.styleable.MyKeyboardView_verticalCorrection:
                mVerticalCorrection = a.getDimensionPixelOffset(attr, 0);
                break;
            case R.styleable.MyKeyboardView_keyPreviewLayout:
                previewLayout = a.getResourceId(attr, 0);
                break;
            case R.styleable.MyKeyboardView_keyPreviewOffset:
                mPreviewOffset = a.getDimensionPixelOffset(attr, 0);
                break;
            case R.styleable.MyKeyboardView_keyPreviewHeight:
                mPreviewHeight = a.getDimensionPixelSize(attr, 80);
                break;
            case R.styleable.MyKeyboardView_keyTextSize:
                mKeyTextSize = a.getDimensionPixelSize(attr, 18);
                break;
            case R.styleable.MyKeyboardView_keyTextColor:
                mKeyTextColor = a.getColor(attr, 0xFF000000);
                break;
            case R.styleable.MyKeyboardView_labelTextSize:
                mLabelTextSize = a.getDimensionPixelSize(attr, 14);
                break;
            case R.styleable.MyKeyboardView_popupLayout:
                mPopupLayout = a.getResourceId(attr, 0);
                break;
            case R.styleable.MyKeyboardView_shadowColor:
                mShadowColor = a.getColor(attr, 0);
                break;
            case R.styleable.MyKeyboardView_shadowRadius:
                mShadowRadius = a.getFloat(attr, 0f);
                break;
        }
    }

【问题讨论】:

  • 你是如何实例化MyKeyboardView的?你在夸大布局吗?如果是这样,您是否真的在要膨胀的布局中的 &lt;MyKeyboardView&gt; 上设置了任何这些自定义属性?
  • @MikeM。向问题添加代码
  • 这些属性将位于您应用的命名空间中,而不是系统命名空间中。添加xmlns:app="http://schemas.android.com/apk/res-auto",并将所有属性的android 前缀更改为app。 (让我知道 Android Studio 是否抱怨什么。)
  • @MikeM。太感谢了!现在我还有很多其他问题,但至少我的键盘已经膨胀并且不再崩溃了。创建一个答案,所以我会检查它是否正确)

标签: java android typedarray


【解决方案1】:

您的自定义 View 属性将位于您应用的命名空间中,而不是系统命名空间中,因此当它们具有系统命名空间前缀时,它们不会在给定的 AttributeSet 中找到。

直接在&lt;MyKeyboardView&gt; 标记或祖先标记中添加xmlns:app="http://schemas.android.com/apk/res-auto" 命名空间声明,并将所有属性的前缀更改为app

请注意,前缀可以是您喜欢的任何有效名称,但 app 可能是最常见的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-13
    • 2014-05-20
    • 1970-01-01
    • 1970-01-01
    • 2011-08-31
    • 2017-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多