Как определить настраиваемые атрибуты и атрибуты по умолчанию, чтобы принимать как float, так и int (dp и wrap_content)

Я работаю над библиотекой OpenSource в качестве альтернативы для встроенного Android PopupMenu, в моей библиотеке я хотел бы сделать все настраиваемым так, чтобы, если вы хотите использовать его и изменять цвета / размеры всплывающих окон, это стало легко.

Полный исходный код находится здесь: https://github.com/shehabic/Droppy/tree/styleable_ui

У меня мало вопросов... вкратце я узнал, что для того, чтобы сделать ваш виджет / настраиваемый вид стилизованным, вы должны определить значения 1-Custom View, 2-Styleable атрибутов, 3-Default для таких настраиваемых атрибутов. поэтому у меня есть следующие XML-файлы:

Рез /droppy__attr.xml

<resources>
    <declare-styleable name="Droppy">
        <attr name="droppyMenuItemTitleStyle" format="reference"/>
    </declare-styleable>

    <declare-styleable name="DroppyMenuItemTitle">
        <attr name="android:textColor"/>
        <attr name="android:minWidth"/>
        <attr name="android:minHeight"/>
        <attr name="android:layout_height"/>
        <attr name="android:layout_width"/>
        <attr name="android:layout_gravity"/>
        <attr name="android:gravity"/>
        <attr name="android:layout_weight"/>
    </declare-styleable>
</resource>

Рез /droppy__styles.xml

<resources>
    <style name="Theme.DroppyDefaults" parent="android:Theme">
        <item name="droppyMenuItemTitleStyle">@style/Droppy.DroppyMenuItemTitle</item>
    </style>

    <style name="Droppy">
    </style>

    <style name="Droppy.DroppyMenuItemTitle">
        <item name="android:textColor">@color/darkgrey</item>
        <item name="android:minWidth">128dp</item>
        <item name="android:minHeight">30dp</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_gravity">end|center_vertical</item>
        <item name="android:gravity">center_vertical</item>
        <item name="android:layout_weight">1</item>
    </style>
</resource>

Рез /droppy__defaults.xml

<resources>       
    <!-- Menu Item Title -->
    <color name="default_menu_item_title_textColor">@color/darkgrey</color>
    <dimen name="default_menu_item_title_minWidth">128dp</dimen>
    <dimen name="default_menu_item_title_minHeight">30dp</dimen>
    <dimen name="default_menu_item_title_layout_width">0dp</dimen>


    <!-- There's no easy way to set default values for the following -->
    <!--<float name="default_menu_item_title_layout_weight">1</float>-->
    <!--<item name="default_menu_item_title_layout_gravity">end|center_vertical</item>-->
    <!--<item name="default_menu_item_title_gravity">center_vertical</item>-->
</resources>

В приведенном выше блоке есть первая проблема. Теперь вот код, который я использую в своем пользовательском представлении:

DroppyMenuItem.java

public class DroppyMenuItemTitle extends TextView {

    public DroppyMenuItemTitle(Context context) {
        this(context, null);
    }

    public DroppyMenuItemTitle(Context context, AttributeSet attrs) {
        this(context, attrs, R.attr.droppyMenuItemTitleStyle);
    }

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

        final int defaultWidth = ViewGroup.LayoutParams.MATCH_PARENT;
        final float defaultWeight = 1;

        final int defaultGravity = Gravity.CENTER_VERTICAL;
        final int defaultLayoutGravity = Gravity.END | Gravity.CENTER_VERTICAL;

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DroppyMenuItemTitle, defStyleAttr, 0);
        int width = (int) a.getDimension(R.styleable.DroppyMenuItemTitle_android_layout_width, defaultWidth);
        int height = a.getInt(R.styleable.DroppyMenuItemTitle_android_layout_height, ViewGroup.LayoutParams.WRAP_CONTENT); 
        setGravity(a.getInt(R.styleable.DroppyMenuItemTitle_android_gravity, defaultGravity));

        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(width, height);
        lp.width = width;
        lp.height = height;
        lp.weight = a.getFloat(R.styleable.DroppyMenuItemTitle_android_layout_weight, defaultWeight);
        lp.gravity = a.getInteger(R.styleable.DroppyMenuItemTitle_android_layout_gravity, defaultLayoutGravity);

        setLayoutParams(lp);
    }

Согласно следующей строке:

int width = (int) a.getDimension(R.styleable.DroppyMenuItemTitle_android_layout_width, defaultWidth);

если я использую этот customView и указываю ширину как wrap_content или match_parent, он работает нормально, так как они переводятся в -1 и -2. Но если указать его как XXdp (например, 20dp), он потерпит неудачу, так как число теперь на самом деле является числом с плавающей точкой, а не int

я получаю следующую ошибку:

E / AndroidRuntime (2940): java.lang.NumberFormatException: недопустимый int: "20.0dip"

0 ответов

Другие вопросы по тегам