Всем привет! Вот случилось создать свой преференс для расширения настроек живых обоев поскольку поиски в интернете к такому не привели. Хочу поделиться с заинтересованными и повысить популярность форума Android)) Это мой первый опыт так что отрывайтесь по полной

Статья рассчитана на новичков, поскольку сам являюсь таковым.
Все, что я тут напишу базируется в первую очередь на "
вот этом примере", а так же на беседах с binarytoys, за что ему огромное спасибо (да да, именно Вы подтолкнули нас вытащить немного голову из игрушек и познакомиться поближе с осью).
Итак, разговор пойдет о создании собственного Preference.
Немного предыстории. В очередной попытке популяризации наших продуктов на play.google, мы решили сделать ход конем - бесплатные живые обои.
Целей преследуется несколько - проверить на сколько близка тема хорора андроид-пользователю, изучение расширения AndEngineLiveWallpaperExtension движка AndEngine, изучение "спроса" на живые обои и, наконец, популяризация остальных продуктов компании посредством установок ссылок из активити настроек живых обоев. Рекламу, было решено не впихивать, так как мониторинг показал, что присутствие рекламы в обоях очень раздражает пользователя и не столько из-за наличия таковой, сколько от массы различных permission.Кроме того, самые "продвинутые" путают мошенническую рекламу с вирусами и, конечно, обвиняют, в собственной
тупости глупости, авторов и приложение.
В общем задача создать свой преференс при клике на который пользователь переходил бы куда нам надо.
Выглядеть это должно примерно так:

Начинаем ваять.
1. Собственно скелет нашего преференса. Создаем свой xml-файл (например text_link_pref.xml) для лэйаута нашего преференса и помещаем его в папку res/layout:
| Код |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingBottom="0dp" android:paddingLeft="20dp" android:paddingRight="20dp" android:paddingTop="10dp" >
<TextView android:id="@+id/textMain" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_marginLeft="57dp" android:gravity="top" android:text="TextView" android:textColor="#ffff" android:textSize="25dip" />
<ImageView android:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:src="@drawable/ic_playlogo" />
<TextView android:id="@+id/textSummary" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/imageView1" android:layout_below="@+id/imageView1" android:text="TextView" android:textColor="#00C618" android:textStyle="normal" />
</RelativeLayout>
|
Скелет готов. Теперь, кроме того, что у нас есть спозиционированные относительно друг друга элементы интерфейса, у нас должна быть возможность задавать основной текст (title), картинку (Image) и короткое описание (Summary) внизу, ну и конечно самое главное - LINK(!) на наши веб-ресурсы. Создадим еще один xml-файл (attrs.xml) в котором будет описание собственных атрибутов для нашего преференса и поместим его в папку res/values:
| Код |
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="com.expedition107.wp.moon.nightmare.TextLinkPreference"> <attr name="link" format="string" /> <attr name="text" format="string" /> <attr name="summary" format="string" /> <attr name="picsrc" format="reference" /> </declare-styleable> </resources>
|
Атрибуты готовы вроде бы. Теперь, собственно, переходим к созданию собственного класса. Спросите - почему назвал TextLink... потому что думал обойтись текстом, но друг настоял на картинке. В общем есть картинка, а название так и прижилось.
Наследуемся от Preference:
| Код |
package com.expedition107.wp.moon.nightmare;
import com.expedition107.wp.moon.nightmare.R;
import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; import android.net.Uri; import android.preference.Preference; import android.util.AttributeSet; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView;
public class TextLinkPreference extends Preference implements OnClickListener { private static final String PREFERENCE_NS = "http://schemas.android.com/apk/res/com.expedition107.wp.moon.nightmare"; private final String mLink; private final String mText; private final String mSummary; private TextView mTextMain; private TextView mTextSummary; private ImageView mImageView; private Drawable mImageRes;
public TextLinkPreference(Context context, AttributeSet attrs) { super(context, attrs); mLink = attrs.getAttributeValue(PREFERENCE_NS, "link"); mText = attrs.getAttributeValue(PREFERENCE_NS, "text"); mSummary = attrs.getAttributeValue(PREFERENCE_NS, "summary"); mImageRes = context.getResources().getDrawable(attrs.getAttributeResourceValue(PREFERENCE_NS,
"picsrc",R.drawable.ic_launcher)); } @Override protected View onCreateView(ViewGroup parent){ RelativeLayout layout = null; try { LayoutInflater mInflater = (LayoutInflater)
getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
layout = (RelativeLayout)mInflater.inflate(R.layout.text_link_pref, parent, false); mTextMain = (TextView)layout.findViewById(R.id.textMain); mTextSummary = (TextView)layout.findViewById(R.id.textSummary); mImageView = (ImageView)layout.findViewById(R.id.imageView1); mTextMain.setText(mText); mTextSummary.setText(mSummary); mImageView.setImageDrawable(mImageRes); layout.setOnClickListener(this); } catch(Exception e) { //Log.e("wp_", "Error creating link preference", e); } return layout; } @Override public void onBindView(View view) { super.onBindView(view);
}
@Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri .parse(mLink)); v.getContext().startActivity(intent); } }
|
Еще одна мелочь: одноименные файлы-картинки используемые для наших линков будут лежать в папках res/drawable-hdpi (...ldpi,mdpi, xhdpi) в соответствии с resolution. У меня эти файлы называются (для facebook и play.google соответственно) ic_fblogo.png и ic_playlogo.png
Вот вроде и все.
Файл со структурой preferences может выглядеть так:
| Код |
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" xmlns:customattrs="http://schemas.android.com/apk/res/com.expedition107.wp.moon.nightmare" android:key="settings" android:title="Moon Settings" >
<PreferenceScreen android:enabled="true" android:key="supportscreen" android:orderingFromXml="true" android:summary="Your voice is very important!" android:title="Support Us" > <com.expedition107.wp.moon.nightmare.TextLinkPreference android:key="fblink" android:persistent="true" customattrs:link="http://тра-ля-ля" customattrs:summary="Like us on Facebook!" customattrs:text="Facebook!" customattrs:picsrc = "@drawable/ic_fblogo"/> <com.expedition107.wp.moon.nightmare.TextLinkPreference android:key="twitterlink" android:persistent="true" customattrs:link="http://twitter.com" customattrs:summary="Follow us on Twitter!" customattrs:text="Twitter!" customattrs:picsrc = "@drawable/ic_twitlogo"/> <com.expedition107.wp.moon.nightmare.TextLinkPreference android:key="market" android:persistent="true" customattrs:link="http://тру-лю-лю" customattrs:summary="Look more goodies on play.google!" customattrs:text="Expedition107" customattrs:picsrc = "@drawable/ic_playlogo"/> </PreferenceScreen> </PreferenceScreen>
|
Вроде ничего не забыл)) Если встретили ошибки, неточности - давайте исправим ;)
PS В процессе создания этого чуда природы у меня возник вопрос - есть ли возможность как-то вытащить значения атрибутов элементов по умолчанию? Например цвет summary всегда синий в стандартных преференсах, я тоже хочу синий но не хочу указывать его конкретное значение по понятным причинам, поэтому в примере сделал зеленым

, тоже касается и размеров текста и прочего. Кто знает - расскажите, плиз.
PPS Очень хочется дать прямую ссылку на нашу обоину, поэтому... я ее дам

, а если модератор ее уберет - возражать не буду. Чужие пространства мы уважаем.
ВОТ ОНА!!!