Статьи

Создание клиента Twitter для Android: создание интерфейса

В этой серии мы создаем клиент Twitter для платформы Android с использованием библиотеки Twitter4J. В этом руководстве мы подготовим элементы пользовательского интерфейса для приложения и обработаем вход пользователя в Twitter, чтобы разрешить доступ к его учетной записи.


  1. Создание клиента Twitter для Android: настройка и обзор
  2. Создание клиента Twitter для Android: создание интерфейса
  3. Создание клиента Twitter для Android: создание базы данных временной шкалы
  4. Создание клиента Twitter для Android: получение обновлений с помощью службы
  5. Создание клиента Twitter для Android: твиты, ретвиты и ответы

Прежде чем мы сможем получить доступ к учетной записи пользователя в Твиттере, нам нужно, чтобы они выполнили вход и предоставили разрешение приложению. Откройте основной класс Activity для вашего приложения, создав его сейчас, если Eclipse не сгенерировал его автоматически при запуске проекта. Измените начальную строку объявления класса следующим образом и при необходимости измените имя класса на свое:

1
public class TwitNiceActivity extends Activity implements OnClickListener

OnClickListener будет обнаруживать различные нажатия кнопок. Вам понадобятся следующие операторы импорта, добавленные над объявлением класса, хотя Eclipse, возможно, добавил их автоматически:

1
2
3
import android.app.Activity;
import android.os.Bundle;
import android.view.View.OnClickListener;

Внутри класса добавьте следующие переменные экземпляра:

1
2
3
4
5
6
/**developer account key for this app*/
public final static String TWIT_KEY = «your key»;
/**developer secret for the app*/
public final static String TWIT_SECRET = «your secret»;
/**app url*/
public final static String TWIT_URL = «tnice-android:///»;

Измените переменные Key и Secret, чтобы сохранить значения, которые вы скопировали из своей учетной записи Twitter Developer в прошлый раз. Обратите внимание, что URL является расширенной версией элемента данных, который мы добавили в манифест, поэтому обязательно измените его, если вы использовали другое значение там. Добавьте следующие дополнительные переменные экземпляра для подключения к Twitter:

1
2
3
4
5
6
7
8
9
/**Twitter instance*/
private Twitter niceTwitter;
/**request token for accessing user account*/
private RequestToken niceRequestToken;
/**shared preferences to store user details*/
private SharedPreferences nicePrefs;
  
//for error logging
private String LOG_TAG = «TwitNiceActivity»;//alter for your Activity name

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

1
2
3
import twitter4j.Twitter;
import twitter4j.auth.RequestToken;
import android.content.SharedPreferences;

В методе Activity onCreate после вызова метода суперкласса добавьте следующий код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
//get the preferences for the app
nicePrefs = getSharedPreferences(«TwitNicePrefs», 0);
  
//find out if the user preferences are set
if(nicePrefs.getString(«user_token», null)==null) {
      
    //no user preferences so prompt to sign in
    setContentView(R.layout.main);
  
}
else
{
    //user preferences are set — get timeline
    setupTimeline();
}

Здесь мы получаем ссылку на объект Shared Preferences приложения, чтобы установить, предоставил ли пользователь разрешение приложения или нет. В строке настроек «user_token» будет храниться токен доступа, который мы используем для доступа к Twitter, поэтому, если он уже был установлен, мы знаем, что пользователь ранее выполнил вход в приложение. Если настройки не были установлены, нам нужно предложить пользователю войти в Twitter, что мы будем делать в операторе «если» — на данный момент мы просто устанавливаем основной вид контента.

В блоке else мы позаботимся о пользователях, которые уже выполнили вход и авторизовали приложение. Здесь мы вызываем вспомогательный метод с именем «setupTimeline», который мы реализуем в следующем уроке.

Давайте создадим наш основной макет, который мы установили в операторе if. Обычно Eclipse создает файл в «res / layout / main.xml» автоматически, если вы не можете создать его самостоятельно, щелкнув правой кнопкой мыши папку макета в Package Explorer (или выбрав ее, а затем выбрав меню «Файл»), затем выбрав « Новый »и« Файл ». Откройте основной файл макета и введите следующий код XML:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<LinearLayout xmlns:android=»http://schemas.android.com/apk/res/android»
    android:layout_width=»fill_parent»
    android:layout_height=»fill_parent»
    android:padding=»5dp»
    android:orientation=»vertical» >
  
    <TextView
        android:layout_width=»fill_parent»
        android:layout_height=»wrap_content»
        android:text=»Welcome to TwitNice!»
        android:textStyle=»bold» />
  
    <TextView
        android:layout_width=»fill_parent»
        android:layout_height=»wrap_content»
        android:text=»You need to sign into Twitter to authorize the app» />
  
    <Button
        android:id=»@+id/signin»
        android:layout_width=»wrap_content»
        android:layout_height=»wrap_content»
        android:text=»Sign In» />
  
</LinearLayout>

Это LinearLayout с двумя текстовыми полями и кнопкой. Текстовые поля просто информативны, а кнопка приведет пользователя на веб-страницу входа в Twitter. Кнопка имеет атрибут ID, чтобы мы могли идентифицировать его в коде Java.


Теперь вернемся к нашему методу onCreate для основного приложения Activity, в котором реализована подпись для новых пользователей. Вам понадобится следующий импорт:

1
import android.util.Log;

Внутри блока if после строки, в которой мы устанавливаем главное представление содержимого, добавьте следующее:

1
2
3
4
5
//get a twitter instance for authentication
niceTwitter = new TwitterFactory().getInstance();
  
//pass developer key and secret
niceTwitter.setOAuthConsumer(TWIT_KEY, TWIT_SECRET);

Здесь мы создаем экземпляр класса Twitter из библиотеки Twitter4J, который мы уже объявили как переменную экземпляра. Этот класс необходим для почти всего, что мы делаем с Twitter. Чтобы проверить наши учетные данные, мы передаем ключ и секрет из интерфейса разработчика, в котором было зарегистрировано приложение, для которого мы создали константы класса. Далее нам нужно получить токен запроса от объекта Twitter, чтобы мы могли попытаться авторизовать приложение для учетной записи пользователя:

1
2
3
4
5
6
7
//try to get request token
try
{
    //get authentication request token
    niceRequestToken = niceTwitter.getOAuthRequestToken(TWIT_URL);
}
catch(TwitterException te) { Log.e(LOG_TAG, «TE » + te.getMessage());

Мы здесь пытаемся создать экземпляр токена запроса, для которого мы создали переменную экземпляра. Метод может вызвать исключение, поэтому мы помещаем его в блок try и выводим сообщение об ошибке в журнал Android, если выбрасывается исключение. Обратите внимание, что в коде используется созданная нами константа «LOG_TAG» — полученные сообщения вы можете увидеть на панели Eclipse LogCat.

Чтобы завершить блок if, настройте прослушиватель кликов для кнопки входа, которую мы включили в наш файл макета main.xml:

1
2
3
//setup button for click listener
Button signIn = (Button)findViewById(R.id.signin);
signIn.setOnClickListener(this);

Слушателем нажатия кнопки является сам класс Activity, поэтому теперь нам нужно реализовать метод onClick в любом месте файла класса:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
/**
 * Click listener handles sign in and tweet button presses
 */
public void onClick(View v) {
    //find view
    switch(v.getId()) {
        //sign in button pressed
        case R.id.signin:
            //take user to twitter authentication web page to allow app access to their twitter account
            String authURL = niceRequestToken.getAuthenticationURL();
            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(authURL)));
            break;
    //other listeners here
  
    default:
        break;
    }
}

Метод использует оператор switch для настройки того, что происходит с конкретными нажатиями кнопок. Мы добавим оператор case для другой кнопки позже, но на данный момент все, что нам нужно, это процесс входа в систему. Код извлекает URL-адрес аутентификации из объекта токена запроса Twitter, а затем открывает страницу в веб-браузере.

Не беспокойтесь о том, как реализованы эти методы Twitter4J. Это просто процесс, которому вы должны следовать, если используете API. Отсутствие необходимости заботиться о деталях реализации подключения к Twitter является одним из основных преимуществ использования внешней библиотеки.

Нам нужно разобраться, что произойдет, когда пользователь вернется в приложение после входа в Twitter, чтобы авторизовать его. Когда пользователь войдет в систему, Twitter вернет их вместе с некоторыми данными, чтобы проверить и облегчить доступ приложения к своей учетной записи. Метод onNewIntent сработает, поэтому давайте реализуем его сейчас:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
/*
 * onNewIntent fires when user returns from Twitter authentication Web page
 */
@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    //get the retrieved data
    Uri twitURI = intent.getData();
    //make sure the url is correct
    if(twitURI!=null && twitURI.toString().startsWith(TWIT_URL))
    {
        //is verifcation — get the returned data
        String oaVerifier = twitURI.getQueryParameter(«oauth_verifier»);
  
    }
}

Метод извлекает данные проверки из Twitter, которые мы позже будем использовать для доступа к твитам пользователя. Чтобы выполнить вход в систему только один раз, мы сохраняем необходимые данные в общих настройках приложения. По-прежнему внутри оператора «if» добавьте следующее:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
//attempt to retrieve access token
try
{
    //try to get an access token using the returned data from the verification page
    AccessToken accToken = niceTwitter.getOAuthAccessToken(niceRequestToken, oaVerifier);
      
    //add the token and secret to shared prefs for future reference
    nicePrefs.edit()
        .putString(«user_token», accToken.getToken())
        .putString(«user_secret», accToken.getTokenSecret())
        .commit();
          
    //display the timeline
    setupTimeline();
}
catch (TwitterException te)
{ Log.e(LOG_TAG, «Failed to get access token: » + te.getMessage());

Это еще один метод, который может вызвать исключение. Код внутри блока try сначала получает токен доступа из Twitter, используя данные, возвращаемые с веб-страницы. Затем он использует объект «Общие настройки» для хранения токена и секрета, необходимых для доступа к Twitter. Наконец, код вызывает метод для отображения временной шкалы, который мы еще не реализовали.

Если вы хотите проверить процесс входа в систему прямо сейчас, предоставьте метод «setupTimeline», просто включив вывод сообщений в журнал, например:

1
2
3
private void setupTimeline() {
Log.v(LOG_TAG, «setting up timeline»);
}

Мы полностью реализуем метод в следующих уроках.


Теперь, когда мы обработали подпись пользователей при первом запуске приложения, мы можем перейти к пользовательскому интерфейсу приложения, которое будет запущено впоследствии. Мы будем использовать различные ресурсы в дизайне пользовательского интерфейса для этого приложения, в том числе рисунки, цвета и макеты. XML-файлы макета будут ссылаться на ресурсы для рисования, которые мы создадим на следующем шаге. Не беспокойтесь, если Eclipse предупредит вас об ошибках, потому что ресурсы еще не представлены. Когда вы создаете файлы макетов, просто обратите внимание на ссылки на ресурсы, которые вам еще предстоит создать.

Приложение будет использовать четыре файла макета, один из которых («main.xml») мы уже создали для экрана входа в систему, который появляется только при первом запуске. Нам также нужны макеты, чтобы определить внешний вид основной временной шкалы, экран Tweet и каждое обновление в пределах временной шкалы. В каждом файле макета вы заметите, что многие элементы имеют атрибуты ID. Это сделано для того, чтобы мы могли ссылаться на эти элементы в коде приложения Java, особенно при обработке взаимодействия с пользователем.

Макет временной шкалы будет основным интерфейсом, который увидят пользователи при запуске приложения после его авторизации. Домашняя временная шкала показывает список последних твитов из тех учетных записей, за которыми следует пользователь. В верхней части экрана пользователь увидит заголовок и кнопку Tweet для переключения на экран Tweet для отправки твита. Содержание каждого обновления в домашней временной шкале будет определено в отдельном файле макета, но в макете временной шкалы мы позаботимся о контейнере для списка обновлений в целом.

Создайте новый файл в папке «res / layout» с именем «timeline.xml». Откройте новый файл и добавьте следующую схему, которую мы расширим:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
<LinearLayout xmlns:android=»http://schemas.android.com/apk/res/android»
    android:layout_width=»fill_parent»
    android:layout_height=»fill_parent»
    android:orientation=»vertical» >
  
    <TableLayout xmlns:android=»http://schemas.android.com/apk/res/android»
        android:layout_width=»fill_parent»
        android:layout_height=»wrap_content»
        android:stretchColumns=»0″ >
    <TableRow>
  
  
    </TableRow>
    </TableLayout>
  
    <ListView android:id=»@+id/homeList»
        android:layout_width=»fill_parent»
        android:layout_height=»fill_parent» />
  
</LinearLayout>

Представление определяется LinearLayout. Внутри этого у нас есть TableLayout и ListView. Мы будем добавлять элементы внутри TableRow дальше. ListView будет содержать список обновленных твитов, которые будут отображаться на домашней временной шкале пользователя. Список будет заполнен этими твитами при запуске приложения. На данный момент мы просто определяем вид, который будет их содержать.

Добавьте содержимое в элемент TableLayout TableRow:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
<LinearLayout android:layout_width=»wrap_content»
    android:layout_height=»wrap_content»
    android:layout_marginRight=»15dp»
    android:layout_marginTop=»4dp»
    android:background=»@drawable/homebg»
    android:orientation=»horizontal» >
  
    <TextView android:layout_width=»wrap_content»
        android:layout_height=»wrap_content»
        android:text=»Home»
        android:textColor=»#ffffff»
        android:textSize=»25sp»
        android:textStyle=»bold» />
  
    <ImageView android:layout_width=»wrap_content»
        android:layout_height=»wrap_content»
        android:layout_marginLeft=»5dp»
        android:background=»#ffffff»
        android:src=»@drawable/home» />
</LinearLayout>

Это создает заголовок для домашней временной шкалы. Текст «Дом» выложен рядом с доступным для рисования ресурсом «Дом». Обратите внимание, что у раздела также есть фон, который является другим ресурсом для рисования с именем «homebg».

Затем добавьте кнопку твита, все еще внутри TableRow, но после LinearLayout, который вы только что добавили:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
<LinearLayout android:id=»@+id/tweetbtn»
    android:layout_width=»wrap_content»
    android:layout_height=»wrap_content»
    android:layout_marginBottom=»2dp»
    android:layout_marginRight=»3dp»
    android:layout_marginTop=»2dp»
    android:background=»@drawable/tweetbtnbg»
    android:clickable=»true»
    android:orientation=»horizontal» >
  
    <TextView android:layout_width=»wrap_content»
        android:layout_height=»wrap_content»
        android:layout_marginRight=»5dp»
        android:text=»Tweet»
        android:textColor=»#000000″
        android:textSize=»25sp»
        android:textStyle=»bold» />
  
    <ImageView android:layout_width=»wrap_content»
        android:layout_height=»wrap_content»
        android:src=»@drawable/tweet» />
</LinearLayout>

Как вы можете видеть, это похоже на заголовок Home, но в этом случае View будет функционировать как кнопка — у LinearLayout атрибут «clickable» установлен в значение true. Кнопка будет содержать текст «Tweet», отображаемый рядом с изображением. Когда пользователи нажимают эту кнопку, они переходят на экран Tweet.

В тот момент, когда вы выберете вкладку Graphical Layout для своей временной шкалы XML в Eclipse, вы не увидите много. Как только мы создадим drawables и файл макета обновления, он будет выглядеть так:


Поскольку содержимое временной шкалы создается только во время выполнения, вы не сможете реально увидеть, как будет выглядеть интерфейс, пока не сможете запустить приложение.

Мы собираемся использовать файл макета, чтобы смоделировать одиночное обновление в пределах временной шкалы. Создайте новый файл в вашей директории макета, назвав его «update.xml». Введите следующую схему:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
<LinearLayout xmlns:android=»http://schemas.android.com/apk/res/android»
    android:layout_width=»fill_parent»
    android:layout_height=»wrap_content»
    android:paddingRight=»7dp»
    android:paddingBottom=»3dp»
    android:orientation=»horizontal» >
  
    <ImageView android:id=»@+id/userImg»
        android:layout_width=»wrap_content»
        android:layout_height=»wrap_content»
        android:layout_margin=»5dp»
        android:background=»@drawable/profilebg» />
  
    <LinearLayout android:layout_width=»wrap_content»
        android:layout_height=»wrap_content»
        android:orientation=»vertical» >
  
          
    </LinearLayout>
</LinearLayout>

Макет содержит раздел для изображения профиля учетной записи, чей твит отображается, затем раздел для содержимого твита. Во втором элементе LinearLayout мы добавим содержимое твита и кнопки для ретвитов / ответов. Начните с содержания твита:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<LinearLayout android:layout_width=»wrap_content»
    android:layout_height=»wrap_content»
    android:orientation=»horizontal» >
  
    <TextView android:id=»@+id/userScreen»
        android:layout_width=»wrap_content»
        android:layout_height=»wrap_content»
        android:clickable=»true»
        android:textColor=»@color/control_two»
        android:textStyle=»bold» />
  
    <TextView android:id=»@+id/updateTime»
        android:layout_width=»wrap_content»
        android:layout_height=»wrap_content»
        android:layout_marginLeft=»5dp»
        android:textColor=»#cccccc»
        android:textStyle=»italic» />
</LinearLayout>
<TextView android:id=»@+id/updateText»
    android:layout_width=»wrap_content»
    android:layout_height=»80dp»
    android:layout_marginBottom=»5dp»
    android:autoLink=»all»
    android:textColorLink=»@color/control_one»
    android:textColor=»#ffffff» />

Каждый твит включает в себя отображаемое имя учетной записи в твиттере, время отправки твита и сам твит. Каждый TextView имеет атрибут ID, поскольку код Java будет отображать входящие данные твита в эти представления при запуске приложения. В конечном TextView для самого текста твита установлен атрибут «autoLink», чтобы пользователи могли щелкать ссылки в твитах. Представление с отображаемым именем пользователя также можно нажимать, чтобы пользователи могли просматривать страницу профиля каждой учетной записи в своей временной шкале. Обратите внимание, что эти представления также содержат ссылки на ресурсы цвета, которые мы еще не создали.

Теперь давайте добавим кнопки ретвита и ответа, после TextView, который мы только что добавили:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
<LinearLayout android:layout_width=»wrap_content»
    android:layout_height=»wrap_content»
    android:layout_gravity=»right»
    android:orientation=»horizontal» >
  
    <Button android:id=»@+id/retweet»
        android:layout_width=»wrap_content»
        android:layout_height=»wrap_content»
        android:layout_marginRight=»5dp»
        android:background=»@drawable/updatebtnbg»
        android:textColor=»#ffffff»
        android:text=»retweet» />
  
    <Button android:id=»@+id/reply»
        android:layout_width=»wrap_content»
        android:layout_height=»wrap_content»
        android:background=»@drawable/updatebtnbg»
        android:textColor=»#ffffff»
        android:text=»reply» />
</LinearLayout>

Каждый твит на временной шкале будет сопровождаться этими кнопками, каждая с небольшим текстом и фоном. Вот снимок одного обновления в готовом приложении.


Теперь перейдем к другому главному экрану нашего приложения — экрану Tweet. Создайте еще один новый файл в папке Layout, назвав его «tweet.xml». Введите следующую схему:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<LinearLayout xmlns:android=»http://schemas.android.com/apk/res/android»
    android:layout_width=»fill_parent»
    android:layout_height=»wrap_content»
    android:background=»#333333″
    android:paddingLeft=»3dp»
    android:paddingRight=»3dp»
    android:paddingBottom=»5dp»
    android:orientation=»vertical» >
  
    <TableLayout xmlns:android=»http://schemas.android.com/apk/res/android»
        android:layout_width=»fill_parent»
        android:layout_height=»wrap_content»
        android:stretchColumns=»0″ >
    <TableRow >
    <LinearLayout android:id=»@+id/homebtn»
        android:layout_width=»wrap_content»
        android:layout_height=»wrap_content»
        android:layout_marginRight=»15dp»
        android:layout_marginTop=»4dp»
        android:background=»@drawable/homebtnbg»
        android:clickable=»true»
        android:orientation=»horizontal» >
  
        <TextView android:layout_width=»wrap_content»
            android:layout_height=»wrap_content»
            android:text=»Home»
            android:textColor=»#ffffff»
            android:textSize=»25sp»
            android:textStyle=»bold» />
  
        <ImageView android:layout_width=»wrap_content»
            android:layout_height=»wrap_content»
            android:layout_marginLeft=»5dp»
            android:background=»#ffffff»
            android:src=»@drawable/home» />
    </LinearLayout>
  
    <LinearLayout android:layout_width=»wrap_content»
        android:layout_height=»wrap_content»
        android:layout_marginBottom=»2dp»
        android:layout_marginRight=»3dp»
        android:layout_marginTop=»2dp»
        android:background=»@drawable/tweetbtnbg»
        android:orientation=»horizontal» >
  
        <TextView android:layout_width=»wrap_content»
            android:layout_height=»wrap_content»
            android:layout_marginRight=»5dp»
            android:text=»Tweet»
            android:textColor=»#000000″
            android:textSize=»25sp»
            android:textStyle=»bold» />
  
        <ImageView android:layout_width=»wrap_content»
            android:layout_height=»wrap_content»
            android:background=»@drawable/tweet» />
    </LinearLayout>
    </TableRow>
    </TableLayout>
  
  
</LinearLayout>

Мы добавим больше элементов после TableLayout дальше. Не беспокойтесь о добавлении всего этого кода сразу — если вы сравните его с макетом временной шкалы выше, вы увидите, что он почти идентичен. Верхний раздел с заголовком «Домой» и кнопкой «Твит» будет отображаться одинаково как на домашней шкале времени, так и на экранах твитов. Помимо небольших косметических различий, позволяющих различать их, основное отличие состоит в том, что на экране Tweet заголовок Home функционирует как кнопка для возврата пользователя к его домашней временной шкале, тогда как на макете временной шкалы Tweet View функционирует как кнопка.

После TableLayout добавьте следующее:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
<TextView android:layout_width=»wrap_content»
    android:layout_height=»wrap_content»
    android:textColor=»#ffffff»
    android:text=»What do you want to say?»
  
<EditText android:id=»@+id/tweettext»
    android:layout_width=»fill_parent»
    android:layout_height=»wrap_content»
    android:lines=»5″
    android:singleLine=»false» />
  
<Button android:id=»@+id/dotweet»
    android:layout_width=»wrap_content»
    android:layout_height=»wrap_content»
    android:background=»@drawable/tweetbtnbg»
    android:text=»send» />

Это основной контент для экрана Tweet. Небольшое количество информативного текста предшествует редактируемому текстовому полю, в котором пользователь может ввести свой текст твита, а затем у нас есть кнопка, позволяющая ему продолжить и отправить твит. После того как мы создадим наши ресурсы для рисования, на вкладке «Графический макет» для макета твита вы увидите что-то вроде этого:



Теперь давайте создадим визуальные элементы в нашем интерфейсе, большинство из которых мы уже упоминали в наших ресурсах макета. Некоторые из наших объектов рисования будут определены в файлах XML, а некоторые будут созданы вне приложения с использованием графического дизайна или программы редактирования изображений. Конечно, вы можете изменять любые визуальные элементы, которые вам нравятся, но я бы рекомендовал начать с шагов, описанных в этом руководстве, а затем вносить изменения, как только вы поймете, как различные ингредиенты связаны друг с другом.

Для этого приложения мы используем три изображения, созданные вне Eclipse: значок приложения, домашняя временная шкала и кнопка твита. Вы можете создавать свои собственные версии, если хотите, или вообще не использовать изображения, если хотите. Домашняя временная шкала представляет собой простой рисунок, в то время как кнопка твита и значок приложения используют официальные ресурсы Twitter , которые также включают ретвиты, ответы и избранные значки.

Когда у вас есть готовые чертежи, скопируйте их в папку рабочей области приложения в «res / drawables- *». Eclipse должен был создать три папки для рисования в рабочей области проекта для устройств с низким, средним и высоким разрешением. Изображения должны быть сохранены как «ic_launcher» для значка, «дом» и «твит» для кнопок. Убедитесь, что каждое изображение сохранено с тем же именем в каждой папке, например, изображение твита может называться «tweet.png» во всех трех папках, хотя изображения в каждой папке на самом деле имеют разные размеры, чтобы соответствовать разным разрешениям.

Возможно, вам придется поручить Eclipse обновить рабочее пространство, прежде чем код сможет успешно ссылаться на новые изображения. Для этого выберите проект в Package Explorer, щелкните правой кнопкой мыши или выберите File, затем Refresh.

Помимо черного, белого и серого, интерфейс приложения в основном использует два цвета, оттенки зеленого и синего. Давайте определим их как цветовые ресурсы. В Eclipse создайте новый файл в каталоге «res / values» с именем «colors.xml»:


В XML-файле цветов введите следующий код, чтобы определить два основных цвета в приложении:

1
2
3
4
5
6
<resources>
<color name=»control_one»>#FF006699</color>
<color name=»control_two»>#FF009933</color>
<color name=»control_one_opaque»>#66006699</color>
<color name=»control_two_opaque»>#66009933</color>
</resources>

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

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

Создайте новый файл в папке (-ях) для рисования с именем «homebg.xml» со ​​следующим содержимым:

01
02
03
04
05
06
07
08
09
10
11
<shape xmlns:android=»http://schemas.android.com/apk/res/android»
    android:dither=»true»>
        <gradient
            android:startColor=»#ff000000″
            android:endColor=»#ff333333″
            android:angle=»90″ />
    <padding android:left=»5dp»
        android:top=»5dp»
        android:right=»5dp»
        android:bottom=»5dp» />
</shape>

Это определяет простую рисованную форму с отступом и градиентной заливкой. Если вы оглянетесь назад на код макета вашей временной шкалы, вы увидите этот чертеж, называемый фоном для LinearLayout.

Создайте еще один новый файл с именем «homebtnbg.xml» в ваших чертежах со следующим содержимым:

01
02
03
04
05
06
07
08
09
10
11
<shape xmlns:android=»http://schemas.android.com/apk/res/android»
    android:dither=»true»>
        <gradient
            android:startColor=»#ff000000″
            android:endColor=»#ff121212″
            android:angle=»90″ />
        <padding android:left=»5dp»
            android:top=»5dp»
            android:right=»5dp»
            android:bottom=»5dp» />
</shape>

Этот фон используется для кнопки «Домой» на экране Tweet. Затем создайте файл с именем «profilebg.xml» со следующим содержанием:

01
02
03
04
05
06
07
08
09
10
11
12
<shape xmlns:android=»http://schemas.android.com/apk/res/android»
    android:dither=»true»>
        <gradient
            android:startColor=»#cc666666″
            android:endColor=»#33666666″
            android:angle=»90″ />
        <padding android:left=»5dp»
            android:top=»5dp»
            android:right=»5dp»
            android:bottom=»5dp» />
        <corners android:radius=»2dp» />
</shape>

На этот раз мы определяем закругленные углы, а также отступы и градиентную заливку. Этот фон предназначен для отображения за изображениями профиля на временной шкале.

Последние два рисунка немного сложнее. Для кнопки Tweet и кнопок в каждом обновлении (для ответа или ретвита) мы собираемся определить различные виды состояний выбора, так что кнопки меняются по внешнему виду, когда пользователь нажимает их. Создайте файл с именем «tweetbtnbg.xml» со ​​следующим содержимым:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<selector xmlns:android=»http://schemas.android.com/apk/res/android»>
  
    <item android:state_pressed=»true»>
    <shape xmlns:android=»http://schemas.android.com/apk/res/android»
        android:dither=»true»>
        <gradient
            android:startColor=»@color/control_two_opaque»
            android:endColor=»@color/control_one_opaque»
            android:angle=»90″ />
        <stroke
            android:width=»2dp»
            android:color=»#66ffffff» />
        <padding android:left=»5dp»
            android:top=»5dp»
            android:right=»5dp»
            android:bottom=»5dp» />
        <corners android:radius=»2dp» />
    </shape>
    </item>
    <item>
    <shape xmlns:android=»http://schemas.android.com/apk/res/android»
        android:dither=»true»>
        <gradient
            android:startColor=»@color/control_two»
            android:endColor=»@color/control_one»
            android:angle=»90″ />
        <stroke
            android:width=»2dp»
            android:color=»#ffffffff» />
        <padding android:left=»5dp»
            android:top=»5dp»
            android:right=»5dp»
            android:bottom=»5dp» />
        <corners android:radius=»2dp» />
    </shape>
    </item>
</selector>

Этот код определяет две слегка отличающиеся формы, одну для нажатия кнопки. Единственная разница между ними заключается в цветах, которые определяются как цветовые ресурсы, которые мы создали. Наконец, создайте аналогичный файл с именем «updatebtnbg.xml» со ​​следующим содержимым:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<selector xmlns:android=»http://schemas.android.com/apk/res/android»>
  
    <item android:state_pressed=»true»>
    <shape xmlns:android=»http://schemas.android.com/apk/res/android»
        android:dither=»true»>
        <gradient
            android:angle=»90″
            android:endColor=»@color/control_two_opaque»
            android:startColor=»@color/control_one_opaque» />
  
        <padding android:bottom=»5dp»
            android:left=»5dp»
            android:right=»5dp»
            android:top=»5dp» />
  
        <corners android:radius=»2dp» />
    </shape>
    </item>
    <item>
    <shape xmlns:android=»http://schemas.android.com/apk/res/android»
        android:dither=»true»>
        <gradient android:angle=»90″
            android:endColor=»@color/control_two»
            android:startColor=»@color/control_one» />
  
        <padding android:bottom=»5dp»
            android:left=»5dp»
            android:right=»5dp»
            android:top=»5dp» />
  
        <corners android:radius=»2dp» />
    </shape>
    </item>
</selector>

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


Eclipse должен перестать отображать сообщения об ошибках для ваших файлов макета, так как присутствуют все ссылочные ресурсы


Теперь наш дизайн пользовательского интерфейса завершен! В следующем уроке мы создадим базу данных для хранения твитов обновлений, а затем используем адаптер для сопоставления этих обновлений с элементами просмотра, чтобы пользователь мог их видеть.