пятница, 6 июля 2012 г.

Создание собственного Preference для живых обоев

Всем привет! Вот случилось создать свой преференс для расширения настроек живых обоев поскольку поиски в интернете к подобному не привели (иногда так не хочется отвлекаться на всякую мелочь, а хочется копипаст). Хочу поделиться с заинтересованными, берите, пользуйтесь на здоровье:-)  Статья рассчитана на новичков, поскольку сам являюсь таковым.

Все, что я тут напишу базируется в первую очередь на вот этом примере.

Итак, разговор пойдет о создании собственного 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 static final String ANDROID_NS = "http://schemas.android.com/apk/res/android";
 
 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_steel", "Error creating seek bar 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://www.facebook.com/pages/Expedition107/199617420087112"
            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="https://play.google.com/store/apps/developer?id=Expedition107"
            customattrs:summary="Look more goodies on play.google!"
            customattrs:text="Expedition107" 
            customattrs:picsrc = "@drawable/ic_playlogo"/>
    
    </PreferenceScreen>

</PreferenceScreen>
Вроде ничего не забыл. Если встретили ошибки, неточности - давайте исправим ;) 

PS В процессе создания этого чуда природы у меня возник вопрос - есть ли возможность как-то вытащить значения атрибутов элементов по умолчанию? Например цвет summary всегда синий в стандартных преференсах, я тоже хочу синий но не хочу указывать его конкретное значение по понятным причинам, поэтому в примере сделал зеленым , тоже касается и размеров текста и прочего. Кто знает - расскажите, плиз.
Ну а вот, собственно, и наши обои на play.google

Комментариев нет:

Отправить комментарий