Доступ к attrs в AttributeSet для пользовательских компонентов
у меня есть пользовательский компонент, содержащий два TextViews, которые имеют пользовательский метод установки размера (два текстовых представления пропорциональны примерно соотношению 1:2). Поскольку это подкласс RelativeLayout, у него нет атрибута textSize, но мне интересно, можно ли все еще установить android:textSize
атрибут в экземпляре XML для этого компонента, а затем захватить textSize
атрибут из AttributeSet для использования с моим пользовательским setSize()
метод в конструктор.
Я видел технику, чтобы сделать это с пользовательскими атрибутами, но что, если я хочу захватить атрибут, который уже находится в лексиконе android?
2 ответов
да, это возможно;
предположим, что ваше объявление RelativeLayout (в xml) имеет textSize, определенный с помощью 14sp:
android:textSize="14sp"
в конструкторе вашего пользовательского представления (тот, который принимает в AttributeSet), вы можете получить атрибуты из пространства имен Android как таковые:
String xmlProvidedSize = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "textSize");
значение xmlProvidedSize будет чем-то вроде этого "14.0 sp" и, возможно, с небольшим количеством редактирования строк вы можете просто извлечь числа.
другой вариант объявления собственного набора атрибутов будет немного длинным, но это также возможно.
Итак, у вас есть свой пользовательский вид, и ваши TextViews объявили что-то вроде этого права:
public class MyCustomView extends RelativeLayout{
private TextView myTextView1;
private TextView myTextView2;
// rest of your class here
большой...
теперь вам также нужно убедиться, что ваше пользовательское представление переопределяет конструктор, который принимает AttributeSet следующим образом:
public MyCustomView(Context context, AttributeSet attrs){
super(context, attrs);
init(attrs, context); //nice, clean method to instantiate your TextViews//
}
ok, давайте посмотрим, что метод init() теперь:
private void init(AttributeSet attrs, Context context){
// do your other View related stuff here //
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.MyCustomView);
int xmlProvidedText1Size = a.int(R.styleable.MyCustomView_text1Size);
int xmlProvidedText2Size = a.int(R.styleable.MyCustomView_text2Size);
myTextView1.setTextSize(xmlProvidedText1Size);
myTextView2.setTextSize(xmlProvidedText2Size);
// and other stuff here //
}
вам, вероятно, интересно, где R. styleable.MyCustomView, R. styleable.MyCustomView_text1Size и R. styleable.MyCustomView_text2Size исходят из; позвольте мне подробно остановиться на них.
вы должны объявить имя (имена) атрибута в своих attrs.xml-файл (в каталоге values), чтобы при использовании пользовательского представления значения, собранные из этих атрибутов, передавались в конструктор.
Итак, давайте посмотрим, как вы объявить эти пользовательские атрибуты, как вы просили: Вот весь мой attrs.в XML
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyCustomView">
<attr name="text1Size" format="integer"/>
<attr name="text2Size" format="integer"/>
</declare-styleable>
</resources>
теперь вы можете установить размер TextViews в XML, но не без объявления пространства имен в вашем макете, вот как:
<com.my.app.package.MyCustomView
xmlns:josh="http://schemas.android.com/apk/res-auto"
android:id="@+id/my_custom_view_id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
josh:text1Size="15"
josh:text2Size="30"
/>
обратите внимание, как я объявил пространство имен "Джош" в качестве первой строки в наборе атрибутов вашего CustomView.
надеюсь, это поможет Джошу,
принятый ответ немного длинный. Вот сокращенная версия, которой, я надеюсь, будет легко следовать. Для того, чтобы добавить (или все, что использует dp
/sp
) для пользовательского представления выполните следующие действия.
1. Создайте пользовательский атрибут
создать (или добавить следующий раздел) в attrs.в XML. Примечание dimension
.
<resources>
<declare-styleable name="CustomView">
<attr name="textSize" format="dimension" />
</declare-styleable>
</resources>
2. Задайте атрибут в xml макет.
обратите внимание на обычай app
пространство имен.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.myproject.CustomView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:textSize="20sp" />
</RelativeLayout>
3. Получите значение атрибута в пользовательском представлении
обратите внимание на использование getDimensionPixelSize
. В вашем пользовательском представлении просто работайте с пикселями. См.ответ если вам нужно преобразовать в другое измерение.
public class CustomView extends View {
private float mTextSize; // pixels
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs, R.styleable.CustomView, 0, 0);
try {
mTextSize = a.getDimensionPixelSize(R.styleable.CustomView_textSize, 0);
} finally {
a.recycle();
}
}
/**
* @param size in SP units
*/
public void setTextSize(int size) {
mTextSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
size, getResources().getDisplayMetrics());
mTextPaint.setTextSize(mTextSize);
invalidate();
requestLayout();
}
// ...
}