Ну вот и свершилось! Вчера, 23го сентября состоялась презентация первого в мире смартфона, работающего под управлением Linux-платформы Google Android, разрабатываемой альянсом Open Handset Alliance (OHA) во главе с Google, — T-Mobile G1. Ранее устройство было известно под кодовым названием HTC Dream. По этому поводу можно посмотреть небольшой видео-тизер здесь. На том же сайте устройство доступно для предзаказа.

И наряду с этим событием как-то тихо и незаметно бала выпущена версия 1.0 инструментария разработки для платформы Google Android. Изменений в новом релизе не много (c ними можно ознакомиться здесь) и хотя при ознакомлении со списком изменений в новой версии кажется что до момента четкого установления API должно пройти еще немало времени, все равно моральный барьер пройден – рабочая версия SDK равно как и работающее устройство выпущены.

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

Для всех, кто интересуется разработкой для Google Android еще раз напоминаю полезные ссылки:

Previous ArticleNext Article
Технический директор IT-Dimension, компании-разработчика кросс-платформенного программного обеспечения

Leave a Reply

Your email address will not be published. Required fields are marked *

П.

Пишем свои компоненты для Mono for Android (Xamarin.Android) – Multi-Select Spinner

Для одного из текущих проектов понадобилось сделать контрол для множественного выбора элементов из списка.
Делать это отдельной Activity как-то не хотелось, но в Android нет готового компонента для этого. Максимум, что можно сделать, это использовать AlertDialog с множественным выбором. Обычный же Spinner позволяет выбрать только один элемент.
И вот, после гугления было найдено неплохое решение на StackOverflow, которое позволяет совместить внешний вид Spinner’а и функционал AlertDialog’а. Решение для Java можно посмотреть здесь. Это решение мне не очень понравилось из-за того, что работает только со строками + необходимо использовать дополнительный метод для установки элементов списка для выбора, вместо того, чтобы нормально испольщовать Adapter для этого.

После небольших допиливаний получился контрол, который, все-таки, можно использовать с адаптером. Правда, при этом теряется возможность хранить ссылку на объект адаптера где-то снаружи контрола и делать ему NotifyDataSetChanged() и NotifyDataSetInvalidated(), но для спиннера это очень редко используемый функционал, так что можно назвать решение приемлемым.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Util;

namespace SampleWidgets.Android.Views
{
    public class MultiSpinner : Spinner, 
		IDialogInterfaceOnMultiChoiceClickListener, 
		IDialogInterfaceOnCancelListener
    {
        public class MultiSpinnerSelectionEventArgs : EventArgs
        {
            public MultiSpinnerSelectionEventArgs(bool[] selected)
            {
                Selected = selected;
            }

            public bool[] Selected { get; private set; }
        }



        public delegate void ItemsSelectedHandler(object sender, 
			MultiSpinnerSelectionEventArgs args);
        public event ItemsSelectedHandler ItemsSelected;
        private ISpinnerAdapter RealAdapter;
        private bool[] selected;

        public MultiSpinner(IntPtr a, JniHandleOwnership b) : base(a, b) { }

        public MultiSpinner(Context context) : base(context)
        {
        }

        public MultiSpinner(Context context, IAttributeSet attrs) 
			: base(context, attrs)
        {
        }

        public MultiSpinner(Context context, IAttributeSet attrs, int defStyle) 
			: base(context, attrs, defStyle)
        {
        }

        public void OnClick(IDialogInterface dialog, int which, bool isChecked)
        {
            selected[which] = isChecked;
        }

        private ISpinnerAdapter CreateLabelAdapter()
        {
            List<string> names = new List<string>();
            int count = RealAdapter != null ? RealAdapter.Count : 0; 
            for (int i = 0; i < count; i++)
            {
                if (selected[i]) names.Add(RealAdapter.GetItem(i).ToString());
            }
            string label = string.Join(", ", names);
            if (label.Length == 0) 
				label = Context.GetString(Resource.String.LabelNone);
            return new ArrayAdapter<string>(Context,
                Android.Resource.Layout.sherlock_spinner_item,
                new string[] { label });
        }

        public void OnCancel(IDialogInterface dialog)
        {
            base.Adapter = CreateLabelAdapter();
            if (ItemsSelected != null) 
				ItemsSelected(this, new MultiSpinnerSelectionEventArgs(selected));
        }

        public override bool PerformClick()
        {
            AlertDialog.Builder builder = new AlertDialog.Builder(Context);
            List<string> names = new List<string>();
            int count = RealAdapter != null ? RealAdapter.Count : 0;
            if (count > 0)
            {
                for (int i = 0; i < count; i++)
                {
                    names.Add(RealAdapter.GetItem(i).ToString());
                }
                builder.SetMultiChoiceItems(names.ToArray(), selected, this);
                builder.SetPositiveButton(global::Android.Resource.String.Ok,
                    delegate(object o, DialogClickEventArgs e) 
					{
						(o as AlertDialog).Cancel(); 
					});
                builder.SetOnCancelListener(this);
                builder.Show();
            }
            return true;
        }

        public override ISpinnerAdapter Adapter 
        { 
            get { return RealAdapter; } 
            set 
            {
                selected = new bool[value.Count]; 
                RealAdapter = value;  
                base.Adapter = CreateLabelAdapter(); 
            } 
        }
    }
}

В коде можно заметить странного вида конструктор public MultiSpinner(IntPtr a, JniHandleOwnership b). Без него Mono for Android не хочет компилировать этот компонент т.к. в нем переопределены виртуальные методы и свойства. Решение проблемы с компиляцией было найдено на том же StackOverflow в этом топике. Ответ, который помечен как решение проблемы, хоть и описывает суть проблемы, но не предлагает реального решения. Зато добавление конструктора реально помогает.

Выглядит все это как-то так:
multi-spinner-screenshot

С.

Свершилось! Android Native Development Kit Released!

Ну наконец-то разработчики платформы Android повернулись к нам лицом и выпустили Android Native Development Kit, который позволяет разрабатывать мобильные приложения для платформы Android на C++!

Что анонсировано в NDK:

  • Средства для сборки native-приложений для Android
  • Средства для встраивания native-библиотек в дистрибутивы приложений .apks
  • Набор заголовочных файлов и библиотек для создания native-приложений

NDK поддерживает набор инструкций ARMv5TE и содержит заголовки и статические библиотеки для:

  • libc
  • libm
  • JNI
  • libz
  • liblog

На самом деле NDK – это не полноценный инструментарий для разработки native-приложений и лучшим вариантом использования его все равно остается связка с Java-based GUI, но все равно, это уже значительный шаг вперед.