J2J.RU - cовременная система продвижения сайтов
Меню сайта

Категории раздела

Наш опрос
Какой у Вас Андроид
Всего ответов: 192

Файлы
Новые Популярные Лучшие


Теги
Android (34)
uCoz (8)
mobile (3)
sistem (3)
xml (3)
google (2)
html (2)
Oboi (2)
opera (2)
Rest (2)
soap (2)
action (1)
ajax (1)
App2SD (1)
apps (1)
CSS (1)
Ddms (1)
editor (1)
gmail (1)
gobook (1)
java (1)
legend (1)
Lite (1)
live (1)
mp3 (1)
mrtm (1)
Muse (1)
ninja (1)
pdf (1)
php (1)
Root (1)
sensor (1)
shazam (1)
sql (1)
thread (1)
touch (1)
UI (1)
Widget (1)
Worms (1)
Xplore (1)
Zirco (1)

RSS
  
Новостная лента.

Форумная лента.

Файловая лента.  

Главная » Статьи » Программинг » Программирование [ Добавить статью ]

Знакомство с Android. Часть 4: Использование GridView

Итак, в нашем приложении осталось всего ничего: реализовать собственно алгоритм игры Life и отобразить его в GridView. Этим-то мы сейчас и займёмся.

Класс, реализующий логику Life


Добавим в проект новый класс, назовем его LifeModel. Тут у нас будет реализована вся логика Life

package demo.android.life;
 
import java.util.Random;
 
public class LifeModel
{
 // состояния клетки
 private static final Byte CELL_ALIVE = 1; // клетка жива
 private static final Byte CELL_DEAD = 0; // клетки нет
 
 // константы для количества соседей
 private static final Byte NEIGHBOURS_MIN = 2; // минимальное число соседей для живой клетки
 private static final Byte NEIGHBOURS_MAX = 3; // максимальное число соседей для живой клетки
 private static final Byte NEIGHBOURS_BORN = 3; // необходимое число соседей для рождения клетки
 
 private static int mCols; // количество столбцов на карте
 private static int mRows; // количество строк на карте
 private Byte[][] mCells; // расположение очередного поколения на карте. 
 //Каждая ячейка может содержать либо CELL_ACTIVE, либо CELL_DEAD
 
 /**
 * Конструктор
 */
 public LifeModel(int rows, int cols, int cellsNumber)
 {
 mCols = cols;
 mRows = rows;
 mCells = new Byte[mRows][mCols];
 
 initValues(cellsNumber);
 }
 
 /**
 * Инициализация первого поколения случайным образом
 * @param cellsNumber количество клеток в первом поколении
 */
 private void initValues(int cellsNumber)
 {
 for (int i = 0; i < mRows; ++i)
 for (int j = 0; j < mCols; ++j)
 mCells[i][j] = CELL_DEAD;
 
 Random rnd = new Random(System.currentTimeMillis());
 for (int i = 0; i < cellsNumber; ++i)
 {
 int cc;
 int cr;
 do
 {
 cc = rnd.nextInt(mCols);
 cr = rnd.nextInt(mRows);
 }
 while (isCellAlive(cr, cc));
 mCells[cr][cc] = CELL_ALIVE; 
 }
 }
 
 /**
 * Переход к следующему поколению
 */
 public void next()
 {
 Byte[][] tmp = new Byte[mRows][mCols];
 
 // цикл по всем клеткам
 for (int i = 0; i < mRows; ++i)
 for (int j = 0; j < mCols; ++j)
 {
 // вычисляем количество соседей для каждой клетки
 int n = 
 itemAt(i-1, j-1) + itemAt(i-1, j) + itemAt(i-1, j+1) +
 itemAt(i, j-1) + itemAt(i, j+1) +
 itemAt(i+1, j-1) + itemAt(i+1, j) + itemAt(i+1, j+1);
 
 tmp[i][j] = mCells[i][j];
 if (isCellAlive(i, j))
 {
 // если клетка жива, а соседей у нее недостаточно или слишком много, клетка умирает
 if (n < NEIGHBOURS_MIN || n > NEIGHBOURS_MAX)
 tmp[i][j] = CELL_DEAD;
 }
 else
 {
 // если у пустой клетки ровно столько соседей, сколько нужно, она оживает 
 if (n == NEIGHBOURS_BORN)
 tmp[i][j] = CELL_ALIVE; 
 }
 }
 mCells = tmp;
 }
 
 /**
 * @return Размер поля
 */
 public int getCount()
 {
 return mCols * mRows;
 }
 
 /**
 * @param row Номер строки
 * @param col Номер столбца
 * @return Значение ячейки, находящейся в указанной строке и указанном столбце
 */
 private Byte itemAt(int row, int col)
 {
 if (row < 0 || row >= mRows || col < 0 || col >= mCols)
 return 0;
 
 return mCells[row][col];
 }
 
 /**
 * @param row Номер строки
 * @param col Номер столбца
 * @return Жива ли клетка, находящаяся в указанной строке и указанном столбце
 */
 public Boolean isCellAlive(int row, int col)
 {
 return itemAt(row, col) == CELL_ALIVE;
 }
 
 /**
 * @param position Позиция (для клетки [row, col], вычисляется как row * mCols + col)
 * @return Жива ли клетка, находящаяся в указанной позиции
 */
 public Boolean isCellAlive(int position)
 {
 int r = position / mCols;
 int c = position % mCols;
 
 return isCellAlive(r,c);
 }
}

GridView. Отображение первого поколения клеток

Модифицируем разметку run.xml так, чтобы она выглядела следующим образом:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 <GridView
 android:id="@+id/life_grid" 
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 
 android:padding="1dp"
 android:verticalSpacing="1dp"
 android:horizontalSpacing="1dp"
 android:columnWidth="10dp"

 android:gravity="center"
 />
 <Button
 android:id="@+id/close"
 android:text="@string/close"
 android:textStyle="bold"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 />
</LinearLayout>

Теперь нам надо отобразить в этом GridView данные. Думаю, вполне логичным для данной задачи было бы отображение клеток в виде графических файлов. Создаем два графических файлика, на одном изображаем черный квадратик, на другом - зелёный. Первый назовём empty.png и он будет обозначать пустую клетку, второй - cell.png, и он будет изображать живую клетку. Оба файлика положим в папку /res/drawable

Нам нужно знать, что именно отображать в гриде. Для этого нужно создать для грида поставщик данных (Adapter). Есть стандартные классы для адаптеров (ArrayAdapter и др.), но нам будет удобнее написать свой, унаследованный от BaseAdapter. Дабы не плодить файлов (да и не нужен он больше никому), поместим его внутрь класса RunActivity. А напишем там следующее:

class LifeAdapter extends BaseAdapter
{
 private Context mContext;
 
 private LifeModel mLifeModel;
 
 public LifeAdapter(Context context, int cols, int rows, int cells)
 {
 mContext = context;
 mLifeModel = new LifeModel(rows, cols, cells);
 }
 
 public void next()
 {
 mLifeModel.next();
 }
 
 /**
 * Возвращает количество элементов в GridView 
 */
 public int getCount()
 {
 return mLifeModel.getCount();
 }
 
 /**
 * Возвращает объект, хранящийся под номером position
 */
 public Object getItem(int position)
 {
 return mLifeModel.isCellAlive(position);
 }
 
 /**
 * Возвращает идентификатор элемента, хранящегося в под номером position
 */
 public long getItemId(int position)
 {
 return position;
 }
 
 /**
 * Возвращает элемент управления, который будет выведен под номером position
 */
 public View getView(int position, View convertView, ViewGroup parent)
 {
 ImageView view; // выводиться у нас будет картинка
 
 if (convertView == null)
 {
 view = new ImageView(mContext);
 
 // задаем атрибуты
 view.setLayoutParams(new GridView.LayoutParams(10, 10));
 view.setAdjustViewBounds(false);
 view.setScaleType(ImageView.ScaleType.CENTER_CROP);
 view.setPadding(1, 1, 1, 1);
 }
 else
 {
 view = (ImageView)convertView;
 }
 
 // выводим черный квадратик, если клетка пустая, и зеленый, если она жива
 view.setImageResource(mLifeModel.isCellAlive(position) ? R.drawable.cell : R.drawable.empty);
 
 return view;
 }
}
 

Теперь добавим в RunActivity поля:

private GridView mLifeGrid;
private LifeAdapter mAdapter;

и модифицируем onCreate:

public void onCreate(Bundle savedInstanceState)
{
 super.onCreate(savedInstanceState);
 setContentView(R.layout.run);
 
 mCloseButton = (Button) findViewById(R.id.close);
 mCloseButton.setOnClickListener(this);
 
 Bundle extras = getIntent().getExtras();
 int cols = extras.getInt(EXT_COLS);
 int rows = extras.getInt(EXT_ROWS);
 int cells = extras.getInt(EXT_CELLS);
 mAdapter = new LifeAdapter(this, cols, rows, cells);
 
 mLifeGrid = (GridView)findViewById(R.id.life_grid);
 mLifeGrid.setAdapter(mAdapter);
 mLifeGrid.setNumColumns(cols);
 mLifeGrid.setEnabled(false);
 mLifeGrid.setStretchMode(0);
}
 

Запускаем и видим:



Отображение последующих поколений

Вот мы и добрались почти до самого конца. Осталось отобразить ход игры.

Каждую секунду нам нужно отправлять кому-то команду о том, что нужно обновить модель и UI. Для этого лучше всего подходит класс Handler. Назначение и поведение этого класса достойны отдельной статьи, но вкратце можно сказать, что он, ассоциировавшись с неким потоком и очередью сообщений, может отправлять туда на выполнение всякие Runnables и Messages. Одно из главных применений класса Handler — запуск Runnable по расписанию. Для этого в нем имеются методы вроде post, postDelayed и postAtTime

Итак, для отображения последующих поколений клеток модифицируем класс RunActivity следующим образом:

public class RunActivity extends Activity implements OnClickListener
{
 ...
 
 private Handler mHandler;
 
 @Override
 public void onCreate(Bundle savedInstanceState)
 {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.run);
 
 mCloseButton = (Button) findViewById(R.id.close);
 mCloseButton.setOnClickListener(this);
 
 Bundle extras = getIntent().getExtras();
 int cols = extras.getInt(EXT_COLS);
 int rows = extras.getInt(EXT_ROWS);
 int cells = extras.getInt(EXT_CELLS);
 mAdapter = new LifeAdapter(this, cols, rows, cells);
 
 mLifeGrid = (GridView)findViewById(R.id.life_grid);
 mLifeGrid.setAdapter(mAdapter);
 mLifeGrid.setNumColumns(cols);
 mLifeGrid.setEnabled(false);
 mLifeGrid.setStretchMode(0);
 
 mHandler = new Handler();
 mHandler.postDelayed(mUpdateGeneration, 1000);
 }
 
 private Runnable mUpdateGeneration = new Runnable()
 {
 public void run()
 {
 mAdapter.next();
 mLifeGrid.setAdapter(mAdapter);
 
 mHandler.postDelayed(mUpdateGeneration, 1000);
 }
 }; 
 ...

Теперь, запустив Life, можно увидеть, например, следующее


Заключение

Итак, мы написали первое приложение для Android, которое уже и не совсем "Hello, World". Лично мне писать для Android понравилось куда больше, чем классические мидлеты. Остался, правда, ряд претензий к Eclipse, но, возможно, это от недостатка опыта.

Спасибо, если кто осилил. Замечания приветствуются.

Взято с http://www.mobilab.ru

Категория: Программирование | Добавил: Virus (28.11.2012)

Похожие темы на пост "Знакомство с Android. Часть 4: Использование GridView"

Схожие темы выбранные по тегам : знакомство, использование, программирование, часть, Android., GridView
  
Просмотров: 1470 | Рейтинг: 0.0/0

Дорогие пользователи и гости сайта!!! Пожалуйста, если вам не сложно, оставте комментарий или ваше мнение о портале в Гостевой книге. Ваше мнение очень важно для нас и очень поможет в поиске дальнейшего пути развития сайта. С уважением, Администрация сайта AndroBum!



Так же рекомендуем:
Всего комментариев: 0
Информация:
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.

[ Регистрация | Вход ]
Поиск

Мини-чат

Block title
Virus
файлов: 69
Постов: 38
Комментов: 1005
Репутация: 0
Ранг:

droid
файлов: 3
Постов: 0
Комментов: 0
Репутация: 100
Ранг:

Serge
файлов: 1
Постов: 0
Комментов: 0
Репутация: 0
Ранг:

Sergey
файлов: 1
Постов: 0
Комментов: 0
Репутация: 0
Ранг:

Аватар не установлен! Blackfoxxx
файлов: 0
Постов: 0
Комментов: 0
Репутация: 0
Ранг:


Друзья сайта
  • Официальный блог
  • скрипты, шаблоны, html, css
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz

  • Статистика Сайта
    Статистика сайта как на сайте

    Пользователей всего: +0
    Материалов всего [?]: +
    Онлайн всего: 1
    Гостей: 1
    Пользователей: 0
    Гости сайта Пользователи

    Яндекс.Метрика




    Пользователи онлайн:


    Flag Counter



    Все материалы размещенные на сайте принадлежат их владельцам.
    Copyright dodomo.do.am © 2010-2012