Android пользовательские атрибуты возвращают ноль - PullRequest
0 голосов
/ 03 мая 2020

Я пытаюсь научиться использовать пользовательские атрибуты в Android Studio. Я следую нескольким учебникам по этой теме, и, несмотря на все мои усилия, похоже, ничего не получается. Я создал код, который иллюстрирует проблему.

Я создал простой пользовательский вид, который ничего не представляет, а только получает стилизованные атрибуты. Это мой код customView:

package com.example.mytestattributes;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;

import androidx.annotation.Nullable;

public class customView extends View {
    public customView(Context context) {
        super(context);
        init(null);
    }

    public customView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }
    private void init(@Nullable AttributeSet attrs){
        if(attrs!=null){
            Log.d("INIT", "attribute set found");
            TypedArray ta = getContext().obtainStyledAttributes(R.styleable.customView);
            Log.d("LENGHT OF TA: ", ta.length()+"");
            Log.d("testString has value", ta.hasValue(R.styleable.customView_testString)+"");
            Log.d("testInteger has value", ta.hasValue(R.styleable.customView_testInteger)+"");
            Log.d("testBoolean has value", ta.hasValue(R.styleable.customView_testBoolean)+"");
            Log.d("testColor has value", ta.hasValue(R.styleable.customView_testColor)+"");
            Log.d("testDimension has value", ta.hasValue(R.styleable.customView_testDimension)+"");
            Log.d("testEnum has value", ta.hasValue(R.styleable.customView_testEnum)+"");

            Log.d("Return testDimension: ", ""+ta.getDimensionPixelSize(R.styleable.customView_testDimension,0));
            Log.d("Return testDimension: ", ""+ta.getDimension(R.styleable.customView_testDimension,0));

        }else{
            Log.d("INIT", "no attribute set found");
        }


    }
}

Код компилируется, и вывод:

D/INIT: attribute set found
D/LENGHT OF TA:: 6
D/testString has value: false
D/testInteger has value: false
D/testBoolean has value: false
D/testColor has value: false
D/testDimension has value: false
D/testEnum has value: false
D/Return testDimension:: 0
D/Return testDimension:: 0.0

Длина типизированного массива верна, это означает, что программа видит атрибуты, но когда я попросите, чтобы он проверил, имеют ли атрибуты значение, результат ложен. Как следствие, любая попытка прочитать эти атрибуты всегда возвращает значение по умолчанию. В коде примера я включил просто getDimension, но то же самое относится ко всем остальным методам get.

Это мои атрибуты. xml, где я определил атрибуты:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="customView">
        <attr name="testString" format="string|reference"/>
        <attr name="testInteger" format="integer"/>
        <attr name="testBoolean" format="boolean"/>
        <attr name="testColor" format="color|reference"/>
        <attr name="testDimension" format="dimension"/>
        <attr name="testEnum" format="enum">
            <enum name="var1" value="1"/>
            <enum name="var2" value="2"/>
        </attr>
    </declare-styleable>
</resources>

Я пытаюсь передать значения в Activity_Main. xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.example.mytestattributes.customView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:testBoolean="true"
        app:testDimension="200dp"
        app:testColor="@color/colorAccent"
        app:testEnum="var1"
        app:testInteger="15"
        app:testString="@string/app_name"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity. java - это неизмененный пустой класс активности. Я знаю, что у некоторых людей были подобные проблемы пару лет go, но никаких достоверных ответов не было. Кто-нибудь знает, что не так с этим кодом? Я использую API 17.

1 Ответ

0 голосов
/ 04 мая 2020

После некоторого возни я заменил строку:

TypedArray ta = getContext().obtainStyledAttributes(R.styleable.customView);

на

TypedArray ta = getContext().obtainStyledAttributes(attrs,R.styleable.customView);

и проблема была решена. В качестве альтернативы я также узнал, что если TypedArray когда-нибудь снова меня не подведет, то можно получить значения непосредственно из attrs с помощью:

attrs.getValue(int index) 

Следует отметить, что индекс атрибута в наборе атрибутов отличается чем индекс в типизированном массиве, поскольку он также включает в себя стандартные атрибуты android. Индекс можно проверить с помощью:

            for (int i = 0; i < attrs.getAttributeCount(); i++) {
                Log.d("ATTRS", i+ ": " + attrs.getAttributeName(i)+"");
            }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...