Как указать цвет фона в списке ресурсов Color State?
Чтобы дать пользователю моего приложения указание на то, какое поле в данный момент находится в фокусе, я пытаюсь изменить цвет фона некоторых из моих полей в зависимости от текущего состояния, однако у меня возникают проблемы с пониманием ресурсов списка состояний цветов Android:
Я нашел пример (извините, URL больше не работает), и если я пытаюсь точно так же, то есть, если я хочу адаптировать textColor, все работает. Однако, если я попробую только немного другую вещь, а именно адаптировать цвет фона, вещи не будут работать, и я не понимаю, почему? Почему это так противоречиво???
Чтобы было проще понять, что я пытаюсь сделать, я добавляю свою миску. XML-файлы:
AndroidManifest.xml
файл:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="mmo.android.test"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".Test"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Test-Activity
:
package mmo.android.test;
import android.app.Activity;
import android.os.Bundle;
public class Test extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
res/values/strings.xml
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, Test!</string>
<string name="app_name">Test</string>
</resources>
res/color/button_test_color.xml
:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="#f0f"/> <!-- pressed -->
<item android:state_focused="true" android:color="#ff0"/> <!-- focused -->
<item android:color="#000"/> <!-- default -->
</selector>
и наконец мой res/layout/main.xml
файл:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="foobar"
android:textColor="@color/button_test_color"
android:background="#f00"
/>
<!--
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="foobar"
android:textColor="#f00"
android:background="@color/button_test_color"
/>
-->
</LinearLayout>
If I run this as shown here, it works, ie I get a button whose text color changes depending on whether the button is focuses, pressed, etc.
If I uncomment the lower button, where I just flipped the attribute values for textColor and background I get an exception, stating
... <item> tag requires a 'drawable' attribute or child tag defining a drawable
What the heck am I missing here? Why is that color state list acceptable as a text color but not as a background color? How does one specify a view's background color depending on the view's state?
3 ответа
Попробуйте определить textColor как нарисованный, а не цвет:
android:textColor="@drawable/button_test_color"
Категории ресурсов основаны на типе ресурсов, а не на имени папки, в которой они находятся. XML-файлы в форме button_test_color.xml обычно называются "рисуемыми" - я на самом деле удивлен, что "цвет" работал вообще!
У меня была именно эта проблема. Это выглядит как android:background
не работает с цветными списками состояний. Я обошел это, создав вместо этого Drawable State State List (отдельные цвета можно использовать в качестве Drawables в State List).
Чтобы использовать ваш пример, создайте файл res/drawable/button_test_background.xml
:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@color/pressed_color"/>
<item android:state_focused="true" android:drawable="@color/focused_color"/>
<item android:drawable="@color/default_color"/>
</selector>
Обратите внимание на использование android:drawable
вместо android:color
, Android будет использовать цветной ресурс и делать из него рисование. Чтобы закончить это, вам нужно добавить цветовые ресурсы в ваш res/values/colors.xml
файл:
<?xml version="1.0" encoding="utf-8"?>
<resources>
...
<color name="pressed_color">#f0f</color>
<color name="focused_color">#ff0</color>
<color name="default_color">#000</color>
...
</resources>
Затем вы могли бы обратиться к этому рисованию, используя @drawable/button_test_background
вместо @color/button_test_color
,
Итак, в итоге, список состояний цвета отлично работает для android:textColor
, но для android:background
требуется описанный выше метод State List Drawable.
Если у вас уже есть список состояний цветов, который вы хотите использовать, вы можете создать простой рисунок, подобный этому, и использовать его.
res/drawable/button_test_background.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="@color/button_test_color" />
</shape>
<Button
...
android:background="@drawable/button_test_background.xml"
...
/>