2013-02-12 3 views
5

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

Вот мой attrs.xml, в котором я объявляю атрибут с именем "oddMonth", которая является булевой:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <declare-styleable name="DayView"> 
     <attr name="oddMonth" format="boolean"/> 
    </declare-styleable> 
</resources> 

Тогда у меня есть собственный вид:

<?xml version="1.0" encoding="utf-8"?> 
<com.example.calendar.DayView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="90dp" 
    android:background="@drawable/dayview_state" > 
    <TextView android:id="@+id/day_number" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentTop="true" 
     android:layout_alignParentRight="true" 
     android:paddingRight="3dp" /> 
</com.example.calendar.DayView> 

Я поместить строку "андроид: фон =" @ вытяжке/dayview_state "", который ссылается на файл dayview_state.xml:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:easycalendar="http://schemas.android.com/apk/res/com.example.calendar"> 

    <item easycalendar:oddMonth ="true" android:drawable="@drawable/customborder_odd" /> 
    <item easycalendar:oddMonth ="false" android:drawable="@drawable/customborder_even"/> 

</selector> 

Так е ar ... для чего я могу понять .... У меня есть атрибут, определенный в attrs.xml. Этот атрибут представляет состояние для моего пользовательского представления. Согласно логическому значению этого атрибута, мое приложение будет загружать один из двух разных xml (которые здесь не важны), каждый из которых определяет другой drawable. Итак, последний шаг - создать свой собственный класс! Следит экстракт из класса:

public class DayView extends RelativeLayout { 
    private static final int[] STATE_ODD_MONTH = { R.attr.oddMonth }; 
    private boolean mOddmonth = true; 

    public DayView(Context mContext, AttributeSet attrs) { 
     super(mContext, attrs); 
    } 

    @Override 
    protected int[] onCreateDrawableState(int extraSpace) { 
     if (mOddmonth) { 
      final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 
      mergeDrawableStates(drawableState, STATE_ODD_MONTH); 

      return drawableState; 
     } else { 
      return super.onCreateDrawableState(extraSpace); 
     } 
    } 

    public boolean isOddMonth() { 
     return mOddmonth; 
    } 

    public void setOddMonth(boolean oddMonth) { 
     if (mOddmonth != oddMonth) { 
      mOddmonth = oddMonth; 

      refreshDrawableState(); 
     } 
    } 
} 

Ok ... так что я должен здесь приватную переменную mOddMonth, Whith геттер и сеттер. Конструктор, который используется для раздувания этого представления в другом месте. Другой частные переменное:

private static final int[] STATE_ODD_MONTH = { R.attr.oddMonth }; 

который является массивом из только одного ИНТА значения, то есть ссылка на атрибут oddMonth, определенном в attrs.xml. И унаследованный метод:

@Override 
    protected int[] onCreateDrawableState(int extraSpace) { 
     if (mOddmonth) { 
      final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 
      mergeDrawableStates(drawableState, STATE_ODD_MONTH); 

      return drawableState; 
     } else { 
      return super.onCreateDrawableState(extraSpace); 
     } 
    } 

, который я не могу на самом деле «глубоко» понять ... ну, мне кажется, что я добавляю состояние, если локальная переменная mOddMonth верно, в противном случае нет. Так ... мой код работает только если я заменить мою dayview_state.xml следующим:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:easycalendar="http://schemas.android.com/apk/res/com.example.calendar"> 

    <item easycalendar:oddMonth ="true" android:drawable="@drawable/customborder_odd" /> 
    <item android:drawable="@drawable/customborder_even"/> 

</selector> 

Таким образом, первый макет загружается, если есть состояние, в противном случае будет загружен второй. Но ЧТО О ЗНАЧЕНИИ государства? Нигде в моем коде я не установил значение для этой переменной/атрибута .... где я ошибаюсь?

+0

Кажется, что работает с селектором по умолчанию и устанавливает только истинные значения:

+0

И так? как насчет моего пользовательского селектора? – Stefano

+0

Я не думаю, что я понимаю ваш вопрос сам по себе - переменная mOddmonth установлена ​​в true, поэтому поэтому вы входите в состояние STATE_ODD_MONTH в onCreateDrawableState. Итак, что именно вы подразумеваете под «ЧТО О ЗНАЧЕНИИ государства? Нигде в моем коде я не задал значение для этой переменной/атрибута» –

ответ

0

Я бы порекомендовал вам перефразировать ваш вопрос б/с не было ясно, что вы просили, пока я не прочитал ваш комментарий к @ kcoppock Ответим, который -

«, что я хочу сделать (или Я думаю, что мне следует сделать), чтобы установить это значение где-то в коде в соответствии с фактическим статусом моего пользовательского представления, , а затем заставлять его снова отображать .... Или я не должен? "

В любой момент вы можете запросить мнение, чтобы получить его вытяжку состояния с помощью View.getDrawableState.

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

Прежде всего, вы можете позвонить по телефону Drawable.invalidateSelf. Но вам редко приходится это делать, потому что обычно ваш drawable задается как фоновый рисунок, который автоматически нарисован для вас в методе draw (а не onDraw, который вы рисуете). Таким образом, все, что вам нужно сделать в этом случае, - это аннулировать представление (view.invalidate), оно автоматически перекроет ваш фоновый чертеж (следовательно, вы получите свое изменение с возможностью поворота).

Если вы используете ваш рисунок не как фон, но и для своего основного рисунка, вы рисуете свои чертежи в onDraw. Простой myDrawable.draw (холст) должен быть достаточно. Но помните, чтобы vall view.invalidate запускал метод onDraw.

0

Вы правы; вам необходимо присвоить это значение в конструкторе с переменной AttributeSet:

TypedArray values = context.obtainStyledAttributes(attrs, STATE_ODD_MONTH); 
boolean isOddMonth = values.getBoolean(R.attr.oddMonth, false); 
mOddmonth = isOddMonth; 
values.recycle(); 

Я считаю, что это следует сделать трюк. Обычно я использую тэг с объявлением в attrs.xml вместо hardcoding int [], но я считаю, что он должен работать одинаково.

+0

Спасибо за ответ! ну ... Но TypedArray не используется для извлечения значения атрибута oddMonth, определенного в attrs.xml? то, что я хочу сделать (или, я думаю, должен сделать), - установить это значение где-нибудь в коде в соответствии с фактическим статусом моего пользовательского представления, а затем заставить его снова отображать .... Или я не должен? – Stefano

+0

О, я вижу; Полагаю, я неправильно понял этот вопрос, извините. – kcoppock

+0

@Stefano см. Мой ответ ниже. –

Смежные вопросы