tag:blogger.com,1999:blog-42136173206630228022024-03-13T13:31:48.366+02:00Developer's notesOleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comBlogger34125tag:blogger.com,1999:blog-4213617320663022802.post-89010213710872463142016-10-09T11:55:00.001+03:002016-10-09T11:55:59.759+03:00Pulsing sequence generator<div class="" data-block="true" data-editor="bm6i0" data-offset-key="u6dt-0-0" style="background-color: white; color: #1d2129; font-family: "San Francisco", -apple-system, BlinkMacSystemFont, ".SFNSText-Regular", sans-serif; font-size: 14px; letter-spacing: -0.24px; white-space: pre-wrap;">
<div class="_1mf _1mj" data-offset-key="u6dt-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="u6dt-0-0" style="font-family: inherit;">Imagine you need to generate "pulsing" sequence of numbers, which should continuously repeat while going up and down between needed values, like this: 5-6-7-8-9-10-9-8-7-6-5-6-7... </span>
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBbVlpUGo4eTkweDQ" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="199" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBbVlpUGo4eTkweDQ" width="320" /></a>
</div>
<div class="_1mf _1mj" data-offset-key="u6dt-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="u6dt-0-0" style="font-family: inherit;">Purposes of such sequence may be different, but anyway, we want to have universal solution even for this simple problem. Algorithm is simple too...</span>
</div>
</div>
<a name='more'></a><div class="" data-block="true" data-editor="bm6i0" data-offset-key="6dlms-0-0" style="background-color: white; color: #1d2129; font-family: "San Francisco", -apple-system, BlinkMacSystemFont, ".SFNSText-Regular", sans-serif; font-size: 14px; letter-spacing: -0.24px; white-space: pre-wrap;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBa0F3RW8xVmFiNWs" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="312" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBa0F3RW8xVmFiNWs" width="320" /></a>
</div>
<div class="_1mf _1mj" data-offset-key="6dlms-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span style="font-family: inherit; letter-spacing: -0.24px;">You can test this algorithm onlie on </span><a href="http://ideone.com/yS80zr" style="font-family: inherit; letter-spacing: -0.24px;" target="_blank">IDEone</a><span style="font-family: inherit; letter-spacing: -0.24px;">. Source code available on </span><a href="https://gist.github.com/shomeser/7f6b767d85ba6307124b85b7158db873" style="font-family: inherit; letter-spacing: -0.24px;" target="_blank">GitHub</a><span style="font-family: inherit; letter-spacing: -0.24px;">. Moreover, you can try to play with it using </span><a href="http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiJhYnMoKHgrNSklMTAtNSkrNSIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0zLjc2MDAwMDAwMDAwMDAwMTYiLCI0OC4yMzk5OTk5OTk5OTk5OTUiLCItMTEuNjYiLCIyMC4zNCJdfV0-" style="font-family: inherit; letter-spacing: -0.24px;" target="_blank">online plotter</a><span style="font-family: inherit; letter-spacing: -0.24px;">.</span>
</div>
</div>
Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-30765979516746993882016-10-09T11:36:00.002+03:002016-10-09T11:47:50.891+03:00Генерация пульсирующей последовательности<div class="" data-block="true" data-editor="bm6i0" data-offset-key="u6dt-0-0" style="background-color: white; color: #1d2129; font-family: "San Francisco", -apple-system, BlinkMacSystemFont, ".SFNSText-Regular", sans-serif; font-size: 14px; letter-spacing: -0.24px; white-space: pre-wrap;">
<div class="_1mf _1mj" data-offset-key="u6dt-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="u6dt-0-0" style="font-family: inherit;">Иногда нужно сгенерировать "пульсирующую" последовательность целых чисел, которая повторялась бы циклически, поднимаясь-спускаясь в рамках заданных значений, как бы ступеньки: 5-6-7-8-9-10-9-8-7-6-5-6-7... </span>
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBbVlpUGo4eTkweDQ" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="199" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBbVlpUGo4eTkweDQ" width="320" /></a>
</div>
<div class="_1mf _1mj" data-offset-key="u6dt-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span data-offset-key="u6dt-0-0" style="font-family: inherit;">Назначение такой последовательности может быть разным. Как всегда, нам хочется иметь универсальное решение даже для такой простой задачи. Алгоритм простой...</span>
</div>
</div>
<a name='more'></a>
<div class="" data-block="true" data-editor="bm6i0" data-offset-key="6dlms-0-0" style="background-color: white; color: #1d2129; font-family: "San Francisco", -apple-system, BlinkMacSystemFont, ".SFNSText-Regular", sans-serif; font-size: 14px; letter-spacing: -0.24px; white-space: pre-wrap;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBa0F3RW8xVmFiNWs" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="312" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBa0F3RW8xVmFiNWs" width="320" /></a>
</div>
<div class="_1mf _1mj" data-offset-key="6dlms-0-0" style="direction: ltr; font-family: inherit; position: relative;">
<span style="font-family: inherit; letter-spacing: -0.24px;">Протестировать этот алгоритм онлайн можно на </span><a href="http://ideone.com/yS80zr" style="font-family: inherit; letter-spacing: -0.24px;" target="_blank">IDEone</a><span style="font-family: inherit; letter-spacing: -0.24px;">. Исходный код также доступен на </span><a href="https://gist.github.com/shomeser/7f6b767d85ba6307124b85b7158db873" style="font-family: inherit; letter-spacing: -0.24px;" target="_blank">GitHub</a><span style="font-family: inherit; letter-spacing: -0.24px;">. Кроме того, можно испытать тот же подход </span><a href="http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiJhYnMoKHgrNSklMTAtNSkrNSIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0zLjc2MDAwMDAwMDAwMDAwMTYiLCI0OC4yMzk5OTk5OTk5OTk5OTUiLCItMTEuNjYiLCIyMC4zNCJdfV0-" style="font-family: inherit; letter-spacing: -0.24px;" target="_blank">на графиках</a><span style="font-family: inherit; letter-spacing: -0.24px;">.</span>
</div>
</div>Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-29441467241928057422016-03-21T12:04:00.000+02:002016-03-21T12:04:05.775+02:00Unity и разрешения в Android 6Я столкнулся с проблемой появления на старте игры диалогов, запрашивающих пользователя о получении разрешений.<br />
<br />
Должен сказать, что я выполняю экспорт проекта под Android и собираю его вручную. Я добавил несколько библиотек, которые используют кое-какие разрешения с уровнем безопасности "dangerous". Я также добавил их в AndroidManifest. Параметр targetSdk установлен в значение 23. Это значит, что мне нужно <a href="http://developer.android.com/intl/ru/training/permissions/requesting.html" target="_blank">запрашивать разрешения во время выполнения</a>.<br />
<br />
Я удивился, когда увидел эти диалоги на старте. Я потратил много времени, пытаясь понять что происходит и какая библиотека выполняет эти запросы. Как оказалось, Unity умеет самостоятельно запрашивать разрешения начиная с версии <a href="https://unity3d.com/unity/whats-new/unity-5.2.4" target="_blank">5.2.4</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBcWRObnFSVHI4Z28" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="276" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBcWRObnFSVHI4Z28" width="640" /></a></div>
<br />
Что ж, если вам нужно отключить этот функционал, то решение очень простое.<br />
<a name='more'></a>Нужно всего лишь добавить тег <span style="font-family: "courier new" , "courier" , monospace;">meta-data</span> в <span style="font-family: "courier new" , "courier" , monospace;">AndroidManifest.xml</span>.<br />
<br />
<div align="left" style="background: #FFF533;">
<pre><meta-data</pre>
<pre> android:name="unityplayer.SkipPermissionsDialog"</pre>
<pre> android:value="true"</pre>
<pre> /></pre>
</div>
<br />
<br />Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-43102169751500035262016-03-18T18:02:00.000+02:002016-03-18T18:05:11.315+02:00Unity and permissions in Android 6I faced with a problem of appearing "ask-permissions" dialog at the starting up of my app.<br />
<br />
At first I need to say that I've exported android project and built it manually. I've added few java-libs which use some permissions with protection level "dangerous". I've added them to AndroidManifest as well. My targetSdk parameter is 23. This means I have to <a href="http://developer.android.com/training/permissions/requesting.html" target="_blank">ask for permissions at run-time</a>.<br />
<br />
I was wondered that "ask-permissions" dialog appeared at the beginning. I spent lot of time trying to understand what happens. As it turned out, Unity brought this behavior as default starting from version <a href="https://unity3d.com/unity/whats-new/unity-5.2.4" target="_blank">5.2.4</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBcWRObnFSVHI4Z28" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="276" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBcWRObnFSVHI4Z28" width="640" /></a></div>
<br />
Well, if you want to disable this feature, solution is very simple.<br />
<a name='more'></a>You need to add this <span style="font-family: "courier new" , "courier" , monospace;">meta-data</span> tag into your <span style="font-family: "courier new" , "courier" , monospace;">AndroidManifest.xml</span>.<br />
<br />
<div align="left" style="background: #FFF533;">
<pre><meta-data</pre>
<pre> android:name="unityplayer.SkipPermissionsDialog"</pre>
<pre> android:value="true"</pre>
<pre> /></pre>
</div>
<br />
<br />Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-31740215680675733232016-03-09T01:53:00.000+02:002016-03-09T13:44:45.457+02:00Андроид статистика от 7 мартаПоследняя статистика о версиях Андроида доступна на сайте <a href="http://developer.android.com/about/dashboards/index.html" target="_blank">developer.android.com</a> как обычно. Мы можем видеть, как KitKat продолжает терять своих пользователей, и, с другой стороны, здесь уже заметен прогресс для Lollipop и Marshmallow. Это хорошая причина переключиться на minSdkVersion=19.<br />
<br />
Я понял, что страница "Android Dashboards" нуждается в других типах данных в секции "Screen Sizes and Densities".<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBZ1VjbE9EN3NwUkE" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="266" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBZ1VjbE9EN3NwUkE" width="400" /></a></div>
<br />
<a name='more'></a><br />
Сейчас там единственная таблица с квалификаторами "screen size" и "screen pixel density". Оба этих квалификатора уже устарели и редко используются.<br />
<br />
Современные приложения полагаются на квалификаторы "small width/height" и "available width/height" вместо предыдущих. Некоторые устройства используют свою особенную константу-множитель для плотности экрана, которая не попадает в стандартные группы типа mdpi, xhdpi, и т.д.. К примеру, Nexus 5X и Nexus 6P используют константы 2.6x и 3.5x в качестве мультипликатора.<br />
<br />
Так что, будет лучше, если предоставить таблицу распределения по размеру экрана в единицах dp и по значению мультипликатора плотности экрана, как это сделано здесь: <a href="https://design.google.com/devices/">https://design.google.com/devices/</a><br />
<div>
<br /></div>
<div>
Я создал задачу на баг-трекере андроида. Если вы согласны с изложенными тезисами, то можете проголосовать за эту задачу <a href="https://code.google.com/p/android/issues/detail?id=202848" target="_blank">по ссылке</a>.</div>
<div>
<br /></div>
<div>
Я также советую открыть <a href="https://docs.google.com/spreadsheets/d/1fcNxupYaOpNSpmEe02VAMWSV6ItnjeehUwlRhjMT2eA" target="_blank">этот документ</a> если вам нужна история версий Андроид и/или хочется поиграть с прогнозами.</div>
<div>
<br /></div>
Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-68152961144004750792016-03-09T01:36:00.000+02:002016-03-09T13:45:25.664+02:00Android Dashboards - March 7thLatest statistics about version of Android available on <a href="http://developer.android.com/about/dashboards/index.html" target="_blank">developer.android.com</a> as usual. We can see KitKat keeps losing its users and from other side here is stable progress for Lollipop and Marshmallow. It's a very good reason to switch for minSdkVersion=19.<br />
<br />
I've realized that page "Android Dashboards" needs another set of data in section "Screen Sizes and Densities".<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBZ1VjbE9EN3NwUkE" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="266" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBZ1VjbE9EN3NwUkE" width="400" /></a></div>
<br />
<a name='more'></a><br />
Currently there's single table with qualifiers "screen size" and "screen pixel density". Both of them are obsolete and rarely used.<br />
<br />
Modern apps rely on qualifiers "small width/height" and "available width/height" instead. Some of devices use custom density multiplier which is out of set of regular qualifiers like mdpi, xhdpi, etc. For instance Nexus 5X and Nexus 6P have 2.6x and 3.5x multipliers.<br />
<br />
So, it's better to provide distribution table grouped by screen sizes in dp units and real density multiplier, like this table has: <a href="https://design.google.com/devices/">https://design.google.com/devices/</a><br />
<div>
<br /></div>
<div>
I created an issue with the same description. If you agree with these terms, please, vote for <a href="https://code.google.com/p/android/issues/detail?id=202848" target="_blank">this issue</a>.</div>
<div>
<br /></div>
<div>
I also suggest you to visit <a href="https://docs.google.com/spreadsheets/d/1fcNxupYaOpNSpmEe02VAMWSV6ItnjeehUwlRhjMT2eA" target="_blank">this document</a> if you want to discover history of Android versions and play with forecast.</div>
<div>
<br /></div>
Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-79470676771476229482016-03-08T03:23:00.000+02:002016-03-08T03:26:57.067+02:00Составной итератор. Java<div style="text-align: left;">
Представьте, что у вас есть две коллекции объектов разного типа. Обе коллекции отсортированы по какому-то правилу. Вам нужно обойти обе коллекции, сохраняя порядок сортировки. Как, например, здесь:</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBS0ZIc0UyOWdONTg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBS0ZIc0UyOWdONTg" width="640" /></a></div>
Я хочу поделиться простой, но эффективной техникой использования интерфейсов <span style="font-family: "courier new" , "courier" , monospace;"><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html" target="_blank">Iterator</a></span> и <span style="font-family: "courier new" , "courier" , monospace;"><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html" target="_blank">Iterable</a></span>.<br />
<br />
<a name='more'></a><br />
Предположим, у нас есть такая структура классов:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBWFQ1Rmxubk5DNWM" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBWFQ1Rmxubk5DNWM" width="307" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Метод <span style="font-family: "courier new" , "courier" , monospace;">compareTo()</span> реализовывает сравнение по полю <span style="font-family: "courier new" , "courier" , monospace;">id</span> в естественном порядке. Метод <span style="font-family: "courier new" , "courier" , monospace;">toString()</span> возвращает конкретное имя класса наследника и его <span style="font-family: "courier new" , "courier" , monospace;">id</span>.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Оджнажды я встретил подобную иерархию в рабочем коде. Вдобавок объекты хранились в двух разных списках: <span style="font-family: "courier new" , "courier" , monospace;">List<Bar></span> и <span style="font-family: "courier new" , "courier" , monospace;">List<Qux></span>. Напомню, что оба списка отсортированы!</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBaEVjUHRhVUtXUFU" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="35" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBaEVjUHRhVUtXUFU" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
Итак, наша задача - обойти оба списка эффективно: линейная сложность по времени O(n), без копирования коллекций, без дополнительных сортировок, без лишних циклов.<br />
<br />
"Простейшее", на первый взгляд, решение - это написать два цикла, потом взять два элемента (по одному из каждого списка), сравнить их, решить какой из них использовать, перейти на первый шаг. Если один из списков закончится раньше другого, то там нужно будет проверить эту ситуацию дополнительным циклом. Этот код будет очень сложным и не используемым повторно. (Я не хочу приводить никаких примеров здесь, просто попробуйте написать это самостоятельно, в качестве тестовой задачи.)<br />
<br />
С другой стороны мы можем избежать многих усложнений, если мы будем использовать интерфейс <span style="font-family: "courier new" , "courier" , monospace;">Iterator</span>. Объявим класс <span style="font-family: "courier new" , "courier" , monospace;">CompositeIterator</span> таким образом:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBb0lzTVRuUVdvOWM" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="120" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBb0lzTVRuUVdvOWM" width="400" /></a></div>
<br />
Поля <span style="font-family: "courier new" , "courier" , monospace;">it1</span> и <span style="font-family: "courier new" , "courier" , monospace;">it2</span> будут ссылаться на итераторы, полученные из обоих коллекций. <span style="font-family: "courier new" , "courier" , monospace;">Comparator</span> используется для решения задачи сортировки. Поле <span style="font-family: "courier new" , "courier" , monospace;">lastUsed</span> будет хранить ссылку на итератор, из которого последним было возвращено значение. Поля <span style="font-family: "courier new" , "courier" , monospace;">obj1</span> и <span style="font-family: "courier new" , "courier" , monospace;">obj2</span> хранят объекты, полученные из итераторов <span style="font-family: "courier new" , "courier" , monospace;">it1</span> и <span style="font-family: "courier new" , "courier" , monospace;">it2</span> соответственно. Что ж, как это будет работать?<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBdVY0QlZOcTJzYTQ" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBdVY0QlZOcTJzYTQ" width="450" /></a></div>
<br />
Метод <span style="font-family: "courier new" , "courier" , monospace;">hasNext()</span> будет проверять по меньшей мере один объект <span style="font-family: "courier new" , "courier" , monospace;">obj1</span> или <span style="font-family: "courier new" , "courier" , monospace;">obj2</span>, полученный из итераторов. Если оба они равны <span style="font-family: "courier new" , "courier" , monospace;">null</span>, мы проверим как минимум один итератор, вызывая его метод <span style="font-family: "courier new" , "courier" , monospace;">hasNext()</span>.<br />
<br />
Если одно из этих четырёх условий равно <span style="font-family: "courier new" , "courier" , monospace;">true</span>, мы попадём в метод <span style="font-family: "courier new" , "courier" , monospace;">next()</span>. Теперь нам нужно убедиться, что мы используем объекты из обоих итераторов, если <span style="font-family: "courier new" , "courier" , monospace;">obj1</span> и/или <span style="font-family: "courier new" , "courier" , monospace;">obj2</span> равны <span style="font-family: "courier new" , "courier" , monospace;">null</span>, то мы "достанем" их из итераторов. Теперь если оба они не равны <span style="font-family: "courier new" , "courier" , monospace;">null</span>, то там нужно сравнить их и выбрать один, который необходимо вернуть. Иначе мы просто возвращаем тот, который не равен <span style="font-family: "courier new" , "courier" , monospace;">null</span>. В случае, если оба объекта равны <span style="font-family: "courier new" , "courier" , monospace;">null</span> в конце этого метода, то это значит, что метод <span style="font-family: "courier new" , "courier" , monospace;">next()</span> вызывается некорректно - нужно бросать исключение <span style="font-family: "courier new" , "courier" , monospace;">NoSuchElementException</span>.<br />
<br />
Обратите внимание на два метода <span style="font-family: "courier new" , "courier" , monospace;">obj1()</span> и <span style="font-family: "courier new" , "courier" , monospace;">obj2()</span>. Они сделаны для того, чтобы сохранить ссылку на последний используемый итератор, а также, чтобы очистить ссылку на объект, который будет возвращён.<br />
<br />
Метод <span style="font-family: "courier new" , "courier" , monospace;">remove()</span> будет использовать поле <span style="font-family: "courier new" , "courier" , monospace;">lastUsed</span> для того, чтобы удалить последний возвращённый элемент из правильного итератора.<br />
<br />
Для того, чтобы удобно использовать этот класс составного итератора, мы добавим простую реализацию интерфейса <span style="font-family: "courier new" , "courier" , monospace;">Iterable</span>, который будет создавать <span style="font-family: "courier new" , "courier" , monospace;">CompositeIterator</span> каждый раз, когда вызывается метод <span style="font-family: "courier new" , "courier" , monospace;">iterator()</span>:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBQ3dVTDhVa2JSb2s" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="204" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBQ3dVTDhVa2JSb2s" width="640" /></a></div>
<br />
И на этом всё! Не верите? Проверьте!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBd1E2VW5XS0F1VkE" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="138" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBd1E2VW5XS0F1VkE" width="640" /></a></div>
<br />
Ух ты! Я даже не думал, что получу такой красивый код. Вот вывод:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBUHd3YUpRMTBRS1U" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="248" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBUHd3YUpRMTBRS1U" width="640" /></a></div>
<br />
Хочу добавить, что вы можете использовать этот подход для любого числа оборачиваемых коллекций. Две, три, четыре - не имеет значения! Вы можете оборачивать эти коллекции попарно столько, сколько нужно.<br />
<br />
Я надеюсь, что это решение поможет вам работать с коллекциями более эффективно. Вы можете скачать все исходные файлы с <a href="https://gist.github.com/shomeser/1d6787f68c1c42f1ac9e" target="_blank">Github</a>. Спасибо за прочтение!<br />
<div style="text-align: center;">
<br /></div>
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/Pq7jjOnCRBE" width="420"></iframe>
</div>
Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-38196975122267574872016-03-08T03:03:00.003+02:002016-03-08T03:24:49.081+02:00Composite Iterator. Java<div style="text-align: left;">
Imagine you have two collections of different types of data. Both of them are sorted by any rule. You need to iterate over both of collections, saving the order they are sorted. Like this:</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBS0ZIc0UyOWdONTg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBS0ZIc0UyOWdONTg" width="640" /></a></div>
I want to share simple, but effective technique of using interfaces <span style="font-family: "courier new" , "courier" , monospace;"><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html" target="_blank">Iterator</a></span> and <span style="font-family: "courier new" , "courier" , monospace;"><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html" target="_blank">Iterable</a></span>.<br />
<br />
<a name='more'></a><br />
Let's suppose that we have such hierarchy of classes:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBWFQ1Rmxubk5DNWM" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBWFQ1Rmxubk5DNWM" width="307" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Method <span style="font-family: "courier new" , "courier" , monospace;">compareTo()</span> implements comparison by field <span style="font-family: "courier new" , "courier" , monospace;">id</span> in natural order. Method <span style="font-family: "courier new" , "courier" , monospace;">toString()</span> returns exact name of object's class and <span style="font-family: "courier new" , "courier" , monospace;">id</span>.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Once upon time I faced with similar hierarchy in production code. In addition there were two types of lists: <span style="font-family: "courier new" , "courier" , monospace;">List<Bar></span> and <span style="font-family: "courier new" , "courier" , monospace;">List<Qux></span>. I want to remind, that both lists are sorted!</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBaEVjUHRhVUtXUFU" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="35" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBaEVjUHRhVUtXUFU" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
So, the task is - iterate over these two lists effectively: linear time complexity O(n), no copies of collections, no additional sorting, no unnecessary loops.<br />
<br />
"The simplest" solution is to write two loops, then get two element (one from each list), compare them, decide which to use, iterate again. If one list become empty too fast we need to check this situation in separated loop. This code will be too complex and not reusable. (I don't want to provide any example here, you may do this by yourself like a training task.)<br />
<br />
From other side we can avoid lot of complications by using <span style="font-family: "courier new" , "courier" , monospace;">Iterator</span> interface. Let's declare class <span style="font-family: "courier new" , "courier" , monospace;">CompositeIterator</span> in such way:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBb0lzTVRuUVdvOWM" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="120" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBb0lzTVRuUVdvOWM" width="400" /></a></div>
<br />
Fields <span style="font-family: "courier new" , "courier" , monospace;">it1</span> and <span style="font-family: "courier new" , "courier" , monospace;">it2</span> will refer to iterators from both collections. <span style="font-family: "courier new" , "courier" , monospace;">Comparator</span> is used for solving a task of ordering. Field <span style="font-family: "courier new" , "courier" , monospace;">lastUsed</span> will save iterator which was used last time returning value. Fields <span style="font-family: "courier new" , "courier" , monospace;">obj1</span> and <span style="font-family: "courier new" , "courier" , monospace;">obj2</span> refer to objects retrieved from <span style="font-family: "courier new" , "courier" , monospace;">it1</span> and <span style="font-family: "courier new" , "courier" , monospace;">it2</span> correspondingly. Well, how will it works?<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBdVY0QlZOcTJzYTQ" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBdVY0QlZOcTJzYTQ" width="450" /></a></div>
<br />
Method <span style="font-family: "courier new" , "courier" , monospace;">hasNext()</span> will check at least one object (<span style="font-family: "courier new" , "courier" , monospace;">obj1</span> or <span style="font-family: "courier new" , "courier" , monospace;">obj2</span>) already retrieved. If both of them are <span style="font-family: "courier new" , "courier" , monospace;">null</span>, we will check at least one of iterators by calling <span style="font-family: "courier new" , "courier" , monospace;">hasNext()</span>.<br />
<br />
If one of these four conditions is <span style="font-family: "courier new" , "courier" , monospace;">true</span>, we will pass into the <span style="font-family: "courier new" , "courier" , monospace;">next()</span> method. Now we need to be sure that we use both iterators, so if <span style="font-family: "courier new" , "courier" , monospace;">obj1</span> and <span style="font-family: "courier new" , "courier" , monospace;">obj2</span> are <span style="font-family: "courier new" , "courier" , monospace;">null</span>, then we need to get them from iterators. Now if they're both not equals <span style="font-family: "courier new" , "courier" , monospace;">null</span>, we need to compare them and choose which to return. Otherwise we just return one of them which is not <span style="font-family: "courier new" , "courier" , monospace;">null</span>. In case if both of them are <span style="font-family: "courier new" , "courier" , monospace;">null</span> at the end of this method, this means method <span style="font-family: "courier new" , "courier" , monospace;">next()</span> was used wrong - need to throw <span style="font-family: "courier new" , "courier" , monospace;">NoSuchElementException</span>.<br />
<br />
Pay attention to two methods <span style="font-family: "courier new" , "courier" , monospace;">obj1()</span> and <span style="font-family: "courier new" , "courier" , monospace;">obj2()</span>. They are used in order to save reference to last used iterator and clear reference on object which was returned.<br />
<br />
Method <span style="font-family: "courier new" , "courier" , monospace;">remove()</span> will use field <span style="font-family: "courier new" , "courier" , monospace;">lastUsed</span> in order to remove last returned element from a proper iterator.<br />
<br />
In order to easy use this iterator, we will create simple implementation of <span style="font-family: "courier new" , "courier" , monospace;">Iterable</span> interface, which will create <span style="font-family: "courier new" , "courier" , monospace;">CompositeIterator</span> every time when method <span style="font-family: "courier new" , "courier" , monospace;">iterator()</span> is called:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBQ3dVTDhVa2JSb2s" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="204" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBQ3dVTDhVa2JSb2s" width="640" /></a></div>
<br />
That's all! Don't believe? Try it!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBd1E2VW5XS0F1VkE" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="138" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBd1E2VW5XS0F1VkE" width="640" /></a></div>
<br />
Wow! I even didn't expect so pretty code. Here is the output:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBUHd3YUpRMTBRS1U" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="248" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBUHd3YUpRMTBRS1U" width="640" /></a></div>
<br />
In addition I want to mention that you can use this approach for any number of collections wrapped. Two, three, four - it doesn't depend! You can wrap them in pairs many times.<br />
<br />
I hope this solution will help you to process collections better. You may download all files from this example on <a href="https://gist.github.com/shomeser/1d6787f68c1c42f1ac9e" target="_blank">Github</a>. Thanks for reading!<br />
<div style="text-align: center;">
<br /></div>
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/Pq7jjOnCRBE" width="420"></iframe>
</div>
Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-88915071364206735252016-03-01T14:51:00.000+02:002016-03-01T14:51:02.288+02:00Привет, мир!Нашёл <a href="http://www.cemspot.com/2013/01/how-do-you-set-blogger-to-work.html" target="_blank">неплохой трюк</a>, как сделать свой блог доступным на нескольких языках. Буду стараться публиковать статьи на нескольких языках одновременно.<br />
<br />
Если такого рода публикации будут популярны, то я добавлю переводы для своих старых записей.<br />
<br />
Посмотрим, что из этого получится. Следите за обновлениями, всем спасибо!Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-81341387688681026302016-03-01T13:02:00.001+02:002016-03-01T14:21:51.940+02:00How to move object following sine curve in Unity?<span style="font-family: inherit;">Today I solved little task of moving objects following given direction. In my case it was sine curve.</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<div style="text-align: center;">
<span style="font-family: inherit;"><iframe allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/Mq4ePbpmEno" width="560"></iframe><br /></span></div>
<a name='more'></a><b><span style="font-family: inherit;">Scene setup.</span></b><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">There are minimal set of objects on scene: camera, light, cube and sphere. Camera rotated by 90 degrees around X axis and lifted up by Y axis, so we're watching scene vertically. Cube has </span><span style="font-family: "courier new" , "courier" , monospace;">Rigidbody</span><span style="font-family: inherit;"> attached; property </span><span style="font-family: "courier new" , "courier" , monospace;">Use Gravity</span><span style="font-family: inherit;"> is disabled on it. Sphere has just a regular </span><span style="font-family: "courier new" , "courier" , monospace;">SphereCollider</span><span style="font-family: inherit;">.</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBOGFsNFNtamNzN1U" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: inherit;"><img border="0" height="414" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBOGFsNFNtamNzN1U" width="640" /></span></a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-family: inherit;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBazhDVnZkNTYtUmM" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: inherit;"><img border="0" height="358" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBazhDVnZkNTYtUmM" width="400" /></span></a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-family: inherit;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBZWVKVE94cDlLalU" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: inherit;"><img border="0" height="263" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBZWVKVE94cDlLalU" width="400" /></span></a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-family: inherit;"><br /></span></div>
<b><span style="font-family: inherit;">Mathematical background.</span></b><br />
<span style="font-family: inherit;"><b><br /></b>
We want to move </span><span style="font-family: "courier new" , "courier" , monospace;">Cube</span><span style="font-family: inherit;"> to </span><span style="font-family: "courier new" , "courier" , monospace;">Sphere</span><span style="font-family: inherit;"> adding sinusoidal vibration perpendicularly to the moving direction. At the beginning we need to calculate vector of moving direction and orthogonal vector for it. We will multiple orthogonal vector by result of sinus function (time is an argument).</span><br />
<span style="font-family: inherit;"><br /></span>
<b><span style="font-family: inherit;">Scripting.</span></b><br />
<b style="font-family: inherit;"><br /></b><span style="font-family: inherit;"><span style="font-family: inherit;">
Attach script </span><a href="https://github.com/shamanland/unity-sinusoidal-moving/blob/master/Assets/Mover.cs" target="_blank"><span style="font-family: "courier new" , "courier" , monospace;">Mover</span></a><span style="font-family: inherit;"> t</span></span><span style="font-family: inherit;">o Cube object. In the </span><span style="font-family: "courier new" , "courier" , monospace;">Start()</span><span style="font-family: inherit;"> m</span><span style="font-family: inherit;">ethod we will save both vectors and start time. Finally, the main magic is here in single line of code of </span><span style="font-family: "courier new" , "courier" , monospace;">FixedUpdate()</span><span style="font-family: inherit;"> m</span><span style="font-family: inherit;">ethod. We need calculate magnitude of orthogonal vector using classical formula of periodical vibration: </span><i style="font-family: inherit;">y = a * sin(w*x)</i><span style="font-family: inherit;">, where </span><i style="font-family: inherit;">a</i><span style="font-family: inherit;"> - is amplitude of vibration, </span><i style="font-family: inherit;">w</i><span style="font-family: inherit;"> - is frequency of vibration, </span><i style="font-family: inherit;">x</i><span style="font-family: inherit;"> - is time in our case. After that we will perform addition of two vectors and assign to Rigidbody.</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBb3lSOUd4TTM4S2s" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: inherit;"><img border="0" height="345" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBb3lSOUd4TTM4S2s" width="640" /></span></a></div>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">That's all! You can download all sources from <a href="https://github.com/shamanland/unity-sinusoidal-moving" target="_blank">Github</a>.</span><br />
<span style="font-family: inherit;"><br /></span>
Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-69763310800084025242016-02-25T01:05:00.000+02:002016-03-01T14:22:04.228+02:00Binary search tricksProbably array is the most popular collection of data. Everyone have used, is using and will use it. If array is sorted, this means you can simplify your life while processing array. I want to share some simple, but effective trick with binary search algorithm.<br />
<br />
Imagine you have sequence of <i>N</i> numbers which splits space for <i>N + 1</i> segments. Two of them on the edges are infinite. For instance, this is fuzzy thermometer.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBekxyODU0cEpNRWs" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="81" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBekxyODU0cEpNRWs" width="400" /></a></div>
<br />
<a name='more'></a>The idea is to display single word described weather. In other words, this is function which accepts temperature as an argument (Celsius in this example) and returns string as a single word.<br />
<br />
The simplest solution may looks like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBSGx5c09GLU56dE0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="377" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBSGx5c09GLU56dE0" width="640" /></a></div>
<br />
The algorithm is - iterate over an array and get label by index of first suitable element. It works because of our array is sorted, and we know about this. Complexity of this method is linear - O(n). It's not a problem for 4 values in array, but in general it's not a good solution, everyone should keep this in mind.<br />
<br />
Well, let's add another method which is much better that first one:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBcWFLWHRTQ3VSWkU" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="222" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBcWFLWHRTQ3VSWkU" width="640" /></a></div>
<br />
We're trying to find index of given value in array. What if this value is missed in array? The <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html#binarySearch-int:A-int-" target="_blank"><span style="font-family: "courier new" , "courier" , monospace;">binarySearch()</span> method</a> will return value of <i>-(insertion point) - 1</i>, where <i>insertion point </i><span style="background-color: #fff2cc;">is defined as the point at which the key would be inserted into the array: the index of the first element greater than the key, or a.length if all elements in the array are less than the specified key</span> - exactly what we need!<br />
<br />
Thus, we can check if the result is negative, and than invert it to positive value we needed. After that just return the label by index. The complexity of <a href="https://en.wikipedia.org/wiki/Binary_search_algorithm" target="_blank">binary search algorithm</a> is logarithmical - O(log<span style="font-size: xx-small;">2 </span>n). This means, even with 1 million of elements you find result by not more than 20 iterations.<br />
<br />
Let's test this new method:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBR0R3c0daRmEwUFU" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="298" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBR0R3c0daRmEwUFU" width="640" /></a></div>
<br />
<br />
Output is here:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBQjRuelNhTEtKUVk" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="250" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBQjRuelNhTEtKUVk" width="640" /></a></div>
<br />
We can see both methods works correctly. But second method looks much more elegant and works extremely faster on large arrays! Source code is available <a href="https://gist.github.com/shomeser/93ed5a4c40cf29142e70" target="_blank">here</a>. Thanks for reading!<br />
<br />
<b>NOTE</b>: In case of exact matching the value with one from array, we associate it with left category (e.g. -10 is treated like 'ice'). If you want to associate it with right category you need to replace operator <span style="background-color: #fff2cc;"><span style="font-family: "courier new" , "courier" , monospace;"> <= </span></span><span style="background-color: white;"> </span>by operator <span style="background-color: #fff2cc;"><span style="font-family: "courier new" , "courier" , monospace;"> < </span></span> inside <span style="font-family: "courier new" , "courier" , monospace;">getLabel1()</span>, and replace <span style="background-color: #fff2cc; font-family: "courier new" , "courier" , monospace;"> binarySearch(values, value) </span> by <span style="background-color: #fff2cc; font-family: "courier new" , "courier" , monospace;"> binarySearch(values, value <b>+ 1</b>) </span> inside <span style="font-family: "courier new" , "courier" , monospace;">getLabel2()</span>. In this case -10 will be treated like 'frosty'.<br />
<br />Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-30732266031713345962016-02-08T16:52:00.000+02:002016-03-07T16:14:01.058+02:00Rolling Ball. Join alpha-testing of my first game<div style="text-align: center;">
<div style="text-align: left;">
Move ball, avoid obstacles, collect bonuses! Be first on leaders board!<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://goo.gl/5IdKOQ" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://goo.gl/5IdKOQ" /></a></div>
<br />
<a name='more'></a><div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
</div>
<br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; margin: 0px; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
Hello everyone! This is my first game written on Unity! I'm still working on it, but I want to share it now for alpha-testing.<br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://play.google.com/apps/testing/com.shamanland.rollingball" style="margin-left: 1em; margin-right: 1em;" target="_blank"><img border="0" height="58" src="https://3.bp.blogspot.com/-UuCQq_lT2DA/VriscmV6QCI/AAAAAAAAlwk/Wh_zxNaAX04/s200/google-play-badge.png" width="200" /></a></div>
</div>
</div>
<div style="text-align: center;">
<div style="text-align: left;">
<div style="text-align: center;">
</div>
</div>
</div>
<div style="text-align: center;">
<div style="text-align: left;">
<div style="text-align: center;">
</div>
<div style="text-align: left;">
</div>
</div>
<div style="text-align: left;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBX2lMb2dURzZFSVU" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="371" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBX2lMb2dURzZFSVU" width="640" /></a></div>
I want to know your opinion about my game. I just want to deliver good game for the good people. If you have installed my game, please, fill <a href="http://goo.gl/forms/uniQ2paMrD" target="_blank">this form</a>.</div>
</div>
Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-87169564254528279642016-02-06T23:50:00.002+02:002016-03-01T14:23:59.014+02:00Android Dev Tips: How to replace Enum by int or String efficiently?<pre style="background-color: white; font-size: 10.5pt;"><span style="font-family: "arial" , "helvetica" , sans-serif;">There's a good topic on <a href="http://developer.android.com/training/articles/memory.html#Overhead" target="_blank">developer.android.com</a> about how to manage app's memory. I want to touch specific paragraph about enums:</span></pre>
<blockquote class="tr_bq" style="background-color: white;">
<span style="font-family: "arial" , "helvetica" , sans-serif; font-size: 14px;"><i>Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android.</i></span></blockquote>
<pre style="background-color: white;"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: 14px;">Lot of developers don't want to follow this rule, saying this is inconvenient, hard to navigate through code, hard to debug, blah-blah-blah... </span></pre>
<pre style="background-color: white;"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: 14px;">
</span></pre>
<pre style="background-color: white;"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: 14px;">Android guys want to help developers with this. They provided <a href="http://developer.android.com/reference/android/support/annotation/package-summary.html" target="_blank">android.support.annotation</a> package with lot of powerful annotations for Android Studio and Lint. I want to explain more about <a href="http://developer.android.com/reference/android/support/annotation/IntDef.html" target="_blank">IntDef</a> and <a href="http://developer.android.com/reference/android/support/annotation/StringDef.html" target="_blank">StringDef</a>. There two classes may help to replace enums efficiently for both: performance and convenience.</span></pre>
<pre style="background-color: white;"><a name='more'></a>
</pre>
<pre style="background-color: white;"><span style="font-family: "arial" , "helvetica" , sans-serif; font-size: 14px;">Let's look at two typical enum classes:</span></pre>
<pre style="background-color: white; font-size: 10.5pt;"><span style="font-family: "arial" , "helvetica" , sans-serif;">
</span></pre>
<pre style="background-color: white; font-size: 10.5pt;"><span style="font-family: "arial" , "helvetica" , sans-serif;">
</span></pre>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBcWxqLUlySHV5dFU" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="two enum declarations" border="0" height="320" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBcWxqLUlySHV5dFU" title="" width="228" /></a></div>
<pre style="background-color: white; font-size: 10.5pt;"></pre>
<pre style="background-color: white; font-size: 10.5pt;"><span style="font-family: "arial" , "helvetica" , sans-serif;">Nothing special, short set of logically named constants. If we replace them by static final variables, then we'll automatically loose completeness of these declarations. It will be set of unlinked constants. <a href="http://tools.android.com/tech-docs/support-annotations" target="_blank">Here is</a> good tutorial how to use android annotations. <a href="http://tools.android.com/tech-docs/support-annotations" target="_blank">It says</a>:</span></pre>
<pre style="background-color: white; font-size: 10.5pt;"><span style="font-family: "arial" , "helvetica" , sans-serif;">
</span></pre>
<blockquote class="tr_bq" style="background-color: white;">
<span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-size: 14px;"><i>The @IntDef annotation lets you basically create a "typedef", where you create another annotation which represents the valid integer constants that you expect, and then you decorate your API with this typedef annotation. </i></span></span></blockquote>
<div>
<span style="font-family: "arial" , "helvetica" , sans-serif;"><br /></span></div>
<div>
<span style="font-family: "arial" , "helvetica" , sans-serif;">It's okay, good idea. But what if we'll go even further? We will place our constants directly in the annotation class, like this:</span></div>
<pre style="background-color: white; font-size: 10.5pt;"><span style="font-family: "arial" , "helvetica" , sans-serif;">
</span></pre>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBVWhjaFVCa1RjZk0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="two annotations with constants inside" border="0" height="305" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBVWhjaFVCa1RjZk0" title="" width="640" /></a></div>
<pre style="background-color: white; font-size: 10.5pt;"></pre>
<pre style="background-color: white; font-size: 10.5pt;"><span style="font-family: "arial" , "helvetica" , sans-serif;">It looks a bit more complicated then enum declaration, but let's check how it works in code. Here is the simplest class declaration with two fields representing our enums. All we need to do is just mark both: fields and accessors with the annotations.</span></pre>
<pre style="background-color: white; font-size: 10.5pt;"><span style="font-family: "arial" , "helvetica" , sans-serif;">
</span></pre>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBT1pIbmF6U3U2YVU" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="simple class with two fields of types int and String marked with annotations declared above" border="0" height="618" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBT1pIbmF6U3U2YVU" title="" width="640" /></a></div>
<pre style="background-color: white; font-size: 10.5pt;"></pre>
<pre style="background-color: white; font-size: 10.5pt;"><span style="font-family: "arial" , "helvetica" , sans-serif;">And now let's try to assign some values out of declared constants set. You can see error messages directly in editor.</span></pre>
<pre style="background-color: white; font-size: 10.5pt;"><span style="font-family: "arial" , "helvetica" , sans-serif;">
</span></pre>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBT2hSMlJ6OXZrV3c" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="example of error messages" border="0" height="286" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBT2hSMlJ6OXZrV3c" title="" width="640" /></a></div>
<pre style="background-color: white; font-size: 10.5pt;"><span style="font-family: "arial" , "helvetica" , sans-serif;">
</span></pre>
<pre style="background-color: white; font-size: 10.5pt;"><span style="font-family: "arial" , "helvetica" , sans-serif;">It also works for switch-statement.</span></pre>
<pre style="background-color: white; font-size: 10.5pt;"><span style="font-family: "arial" , "helvetica" , sans-serif;">
</span></pre>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBWkl1azlHTlhxb2s" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="example of using switch-statement" border="0" height="314" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBWkl1azlHTlhxb2s" title="" width="640" /></a></div>
<pre style="background-color: white; font-size: 10.5pt;"><span style="font-family: "arial" , "helvetica" , sans-serif;">
</span></pre>
<pre style="background-color: white; font-size: 10.5pt;"><span style="font-family: "arial" , "helvetica" , sans-serif;">Thus we can replace enum classes by simple constants without losing comfort of using strictly declared types. Beside that we improve performance of our apps.</span></pre>
<pre style="background-color: white; font-size: 10.5pt;"><span style="font-family: "arial" , "helvetica" , sans-serif;">
</span></pre>
<pre style="background-color: white; font-size: 10.5pt;"><span style="font-family: "arial" , "helvetica" , sans-serif;">Source code of this example is <a href="https://gist.github.com/shomeser/2c9b0321b20b705ee8b5" target="_blank">here</a>.</span></pre>
<pre style="background-color: white; font-size: 10.5pt;"><span style="font-family: "arial" , "helvetica" , sans-serif;">
</span></pre>
Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-63068849022408300752016-02-05T11:54:00.001+02:002016-03-01T14:24:26.122+02:00Android Dev Tips - How to get static Application Context from anywhere?Everyone is facing with the problem of accessing <span style="font-family: "courier new" , "courier" , monospace;">Context </span>instance from methods, which aren't logically linked with <span style="font-family: "courier new" , "courier" , monospace;">Activity </span>or <span style="font-family: "courier new" , "courier" , monospace;">Service</span>.<br />
<br />
It may be needed for accessing independent resources, like strings or files from assets folder. Sometimes it may be inconvenient to initialize and keep additional variable with the static context.<br />
<br />
There're lot of questions on StackOverflow about this. Today I want to share my experience of handling such kind of problems.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBLXdJWEJYWjdLblU" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="193" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBLXdJWEJYWjdLblU" width="640" /></a></div>
<br />
<a name='more'></a>So, the first solution is just to place context variable in target class. Unfortunately it may affect lot of related code, we need to pass <span style="font-family: "courier new" , "courier" , monospace;">Context </span>reference across all of dependent classes.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBUURFb25WRjRGWGc" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="312" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBUURFb25WRjRGWGc" width="640" /></a></div>
<br />
Other guys try to add public static method to <span style="font-family: "courier new" , "courier" , monospace;">Application </span>class and access it from anywhere. I don't like this approach because of additional dependency to custom <span style="font-family: "courier new" , "courier" , monospace;">Application </span>class. In case when you're working on library, it's inappropriate at all.<br />
<br />
Well, my solution is to create standalone class <span style="font-family: "courier new" , "courier" , monospace;">AppHolder </span>which will be able to provide us Application Context without any additional steps.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBUkZDR1otakZ6c2c" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="238" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBUkZDR1otakZ6c2c" width="640" /></a></div>
<br />
This code access hidden field from OS class via Reflection API. Of course, it's not good and it may be risky in theory, but it works well on practice! This code is executed <b>only once</b> per lifetime of app. Static reference to <span style="font-family: "courier new" , "courier" , monospace;">Application </span>instance is cached in static final variable, nobody will re-write it.<br />
<br />
If you don't like to use Reflection API at all, you may adapt this solution on your own choice.<br />
<br />
And now we can access static application context from anywhere.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBM3k5dHlBSWtxQUk" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="196" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBM3k5dHlBSWtxQUk" width="640" /></a></div>
<br />
You may find <a href="https://gist.github.com/shomeser/38908c20c012a81db15b" target="_blank">source code here</a> or you can use method <a href="https://github.com/shamanland/xdroid/blob/master/lib-core/src/main/java/xdroid/core/Global.java#L28" target="_blank">Global.getContext()</a> from my <a href="https://github.com/shamanland/xdroid" target="_blank">Xdroid library</a>. This library is still "in progress", but it was tested already in real projects.<br />
<br />
<div style="background-color: #fff2cc;">
<pre style="font-family: 'Courier New'; font-size: 9pt;">dependencies {
compile <span style="color: green; font-weight: bold;">'com.shamanland:xdroid-core:0.3.0'</span>
}</pre>
<pre style="font-family: 'Courier New'; font-size: 9pt;"></pre>
<pre style="font-family: 'Courier New'; font-size: 9pt;"></pre>
</div>
<br />
Thanks for reading! Watch for updates.Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-42400681925410181262016-02-04T16:17:00.000+02:002016-03-01T14:24:51.066+02:00Android Dashboards - February 1stDo you still care how to choose min SDK version? Last two years Google guys spent lot of efforts in order to make Android more fluent for vendors. The most popular devices now regularly receive firmware updates automatically. From the developer's point of view it's a fantastic! We don't need to care about dino-phones anymore.<br />
<br />
You can see it by yourself from <a href="http://developer.android.com/about/dashboards/index.html" target="_blank">latest statistics from Google</a>. Devices with API 19 and higher now cover more than 70% of market! This means we can use lot of modern features of Android KitKat, Lollipop and Marshmallow without tons of libraries and crutches.<br />
<br />
You can find <a href="https://docs.google.com/spreadsheets/d/1fcNxupYaOpNSpmEe02VAMWSV6ItnjeehUwlRhjMT2eA/pubhtml" target="_blank">more details here</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBcmFjM3hiM1JZTjQ" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="250" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBcmFjM3hiM1JZTjQ" width="400" /></a></div>
<br />Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-85870654615110436832014-11-04T10:26:00.000+02:002016-03-01T14:24:57.331+02:00Android Dashboards - November 3rdThis post relates to statistics of Android versions presented on market. New statistics was published as usually 3rd November on <a href="http://developer.android.com/about/dashboards/index.html" target="_blank">developer.android.com</a>. Google should start shipping of new Nexus devices soon. So, we will wait for a Lollipop statistics after one month. And now you can discover the newest chart with the API levels of Android. Detailed history and forecast available <a href="https://docs.google.com/spreadsheet/pub?key=0Agh0SNLPmjQBdDFuYnFwWWFDMENaN1AtRFBCdTJNclE" target="_blank">here</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBZE1XajNJWTdyd28" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBZE1XajNJWTdyd28" /></a></div>
<br />Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-3337625205033930372014-09-11T14:16:00.000+03:002016-03-01T14:25:04.006+02:00Android Dashboards - September, 9thNew statistics about devices is available on <a href="https://developer.android.com/about/dashboards/index.html?utm_source=blog.shamanland.com" target="_blank">developer.android.com</a>. Gingerbread and Ice Cream Sandwich are disappearing from market continuously.<br />
<br />
Find history and forecast in <a href="https://docs.google.com/spreadsheet/pub?key=0Agh0SNLPmjQBdDFuYnFwWWFDMENaN1AtRFBCdTJNclE" target="_blank">this document</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://docs.google.com/uc?id=0Bwh0SNLPmjQBWnRWbGRsbUxQV0k" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://docs.google.com/uc?id=0Bwh0SNLPmjQBWnRWbGRsbUxQV0k" /></a></div>
Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-88988816097612889072014-06-12T15:36:00.001+03:002016-03-01T14:25:37.833+02:00How to add Facebook 'Like' button in Android app?Official <a href="https://developers.facebook.com/docs/android/" target="_blank">Facebook SDK</a> does not provide implementation of theirs plugin 'Like' for Android. There is just <a href="https://developers.facebook.com/docs/plugins/like-button" target="_blank">html-plugin</a> designed for web-sites and applications. Let's try to adapt this plugin for Android!<br />
<a name='more'></a><br />
In this post we will look at the two things:<br />
<ul>
<li><a href="http://blog.shamanland.com/2014/06/facebook-like-button-for-android.html#single">Using Facebook 'Like' button for single page</a></li>
<li><a href="http://blog.shamanland.com/2014/06/facebook-like-button-for-android.html#listview">Using Facebook 'Like' button in the ListView</a> </li>
</ul>
<br />
<h3>
<a href="http://blog.shamanland.com/2014/06/facebook-like-button-for-android.html#single" name="single"></a>
Using Facebook 'Like' button for single page </h3>
Just add single-line dependency in your gradle project:<br />
<br />
<div style="background: #ffe599; padding: 8px;">
<pre>dependencies {
compile 'com.shamanland:facebook-like-button:0.1.8'
}
</pre>
</div>
<br />
This library contains several widgets:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><a href="https://github.com/shamanland/facebook-like-button/blob/snapshot/lib/src/main/java/com/shamanland/facebook/likebutton/FacebookLikeButton.java" target="_blank">FacebookLikeButton</a></span> - button which opens <span style="font-family: "courier new" , "courier" , monospace;"><a href="https://github.com/shamanland/facebook-like-button/blob/snapshot/lib/src/main/java/com/shamanland/facebook/likebutton/FacebookLikeActivity.java" target="_blank">FacebookLikeActivity</a></span> by clicking on it.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBRGRSdDhFUXJReUU" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBRGRSdDhFUXJReUU" /></a></div>
<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><a href="https://github.com/shamanland/facebook-like-button/blob/snapshot/lib/src/main/java/com/shamanland/facebook/likebutton/FacebookLikeBox.java" target="_blank">FacebookLikeBox</a></span> - button with a specific background and with ability to check 'likes' count of your url.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBb2V6UmZkT0luVU0" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBb2V6UmZkT0luVU0" /></a></div>
<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><a href="https://github.com/shamanland/facebook-like-button/blob/snapshot/lib/src/main/java/com/shamanland/facebook/likebutton/FacebookLikePlugin.java" target="_blank">FacebookLikePlugin</a></span> - container which combines both <span style="font-family: "courier new" , "courier" , monospace;">FacebookLikeButton</span> and <span style="font-family: "courier new" , "courier" , monospace;">FacebookLikeBox</span> in different variations.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBa2lwanpVbm56T00" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBa2lwanpVbm56T00" /></a></div>
<br />
<br />
So, first you need is to include <span style="font-family: "courier new" , "courier" , monospace;">FacebookLikeButton</span> with specified style in your layout:<br />
<br />
<div style="background: #ffe599; padding: 8px;">
<pre><com.shamanland.facebook.likebutton.FacebookLikeButton
style="@style/Widget.FacebookLikeButton"
/></pre>
</div>
<br />
Before configuring your button you need to add <span style="font-family: "courier new" , "courier" , monospace;">app</span> xml namespace into the root node:<br />
<br />
<div style="background: #ffe599; padding: 8px;">
<pre>xmlns:app="http://schemas.android.com/apk/res-auto"</pre>
</div>
<br />
<br />
Add following attributes to your button: <span style="font-family: "courier new" , "courier" , monospace;">pageUrl</span> - original url of page which should to be liked, <span style="font-family: "courier new" , "courier" , monospace;">pageTitle</span> - title of this page, <span style="font-family: "courier new" , "courier" , monospace;">pageText</span> - short description of page, <span style="font-family: "courier new" , "courier" , monospace;">pagePictureUrl</span> - url of page picture.<br />
<br />
<div style="background: #ffe599; padding: 8px;">
<pre><com.shamanland.facebook.likebutton.FacebookLikeButton
style="@style/Widget.FacebookLikeButton"
app:pageUrl="http://your.site.com/page.html"
app:pageTitle="Title of your page"
app:pageText="Short description of your page"
app:pagePictureUrl="http://your.site.com/picture.png"
/></pre>
</div>
<br />
For example:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBcnM1OGpQTlpLNXc" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="423" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBcnM1OGpQTlpLNXc" width="640" /></a></div>
<br />
<br />
Do not forget to declare <span style="font-family: "courier new" , "courier" , monospace;">FacebookLikeActivity</span> in your <span style="font-family: "courier new" , "courier" , monospace;">AndroidManifest.xml</span>:<br />
<br />
<div style="background: #ffe599; padding: 8px;">
<pre><activity
android:name="com.shamanland.facebook.likebutton.FacebookLikeActivity"
android:label="@string/com_shamanland_facebook"
android:theme="@style/Theme.Facebook.Like"
/></pre>
</div>
<br />
Make sure that you have internet permission:<br />
<br />
<div style="background: #ffe599; padding: 8px;">
<pre><uses-permission android:name="android.permission.INTERNET"/></pre>
</div>
<br />
That's all! Now you can compile and launch your app. When user clicks 'Like' button, then he will see <span style="font-family: "courier new" , "courier" , monospace;">WebView</span> with official web-plugin 'Like' from Facebook:<br />
<br />
Now, if you want to include box with count of 'likes' - you should use <span style="font-family: "courier new" , "courier" , monospace;">FacebookLikePlugin</span>:<br />
<br />
<div style="background: #ffe599; padding: 8px;">
<pre><com.shamanland.facebook.likebutton.FacebookLikePlugin
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<com.shamanland.facebook.likebutton.FacebookLikeButton
style="@style/Widget.FacebookLikeButton"
app:pageUrl="http://your.site.com/page.html"
app:pageTitle="Title of your page"
app:pageText="Short description of your page"
app:pagePictureUrl="http://your.site.com/picture.png"
/>
<com.shamanland.facebook.likebutton.FacebookLikeBox
style="@style/Widget.FacebookLikeBox"
app:calloutMarker="left"
/>
</com.shamanland.facebook.likebutton.FacebookLikePlugin>
</pre>
</div>
<br />
Modified example:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBZ0hQNzhuVkRiOHc" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="464" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBZ0hQNzhuVkRiOHc" width="640" /></a></div>
<br />
Note about attribute <span style="font-family: "courier new" , "courier" , monospace;">calloutMarker</span>: if you re-arrange 'like' and 'box' buttons, then you need to select corresponding value for <span style="font-family: "courier new" , "courier" , monospace;">calloutMarker</span>: <span style="font-family: "courier new" , "courier" , monospace;">left</span>, <span style="font-family: "courier new" , "courier" , monospace;">top</span>, <span style="font-family: "courier new" , "courier" , monospace;">right</span>, <span style="font-family: "courier new" , "courier" , monospace;">bottom</span>.<br />
<br />
<h3>
<a href="http://blog.shamanland.com/2014/06/facebook-like-button-for-android.html#listview" name="listview"></a>
Using Facebook 'Like' button in the ListView </h3>
<br />
There is no fundamental difference between single button and buttons inside <span style="font-family: "courier new" , "courier" , monospace;">ListView</span>. You need just to set up button inside your <span style="font-family: "courier new" , "courier" , monospace;">Adapter.getView()</span> method.<br />
<br />
Use corresponding getters of class <span style="font-family: "courier new" , "courier" , monospace;">FacebookLikeButton</span>: <span style="font-family: "courier new" , "courier" , monospace;">setPageUrl()</span>, <span style="font-family: "courier new" , "courier" , monospace;">setPageTitle()</span>, <span style="font-family: "courier new" , "courier" , monospace;">setPageText()</span>, <span style="font-family: "courier new" , "courier" , monospace;">setPagePictureUrl()</span>.<br />
<br />
<b>NOTE</b>: <span style="font-family: "courier new" , "courier" , monospace;">@style/Widget.FacebookLikeButton</span> already has item <span style="font-family: "courier new" , "courier" , monospace;">android:id</span> with the value <span style="font-family: "courier new" , "courier" , monospace;">R.id.com_shamanland_facebook_like</span>. Use this value with method <span style="font-family: "courier new" , "courier" , monospace;">findViewById()</span>. You can also override <span style="font-family: "courier new" , "courier" , monospace;">android:id</span> in xml to use your own value.<br />
<br />
Check <a href="https://github.com/shamanland/facebook-like-button/blob/snapshot/app/src/main/java/com/shamanland/facebook/likebutton/example/LikeAdapter.java#L126" target="_blank">this code example</a> from library sources:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBU0JpdUI2YjBqLTg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBU0JpdUI2YjBqLTg" width="236" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
Well, I hope my library will help somebody to make awesome app with social features. Feel free to ask me anything, subscribe to repository and check for updates.<br />
<br />
Project page: <a href="http://blog.shamanland.com/p/facebook-like-button.html" target="_blank">http://blog.shamanland.com/p/facebook-like-button.html</a><br />
Sources: <a href="https://github.com/shamanland/facebook-like-button" target="_blank">https://github.com/shamanland/facebook-like-button</a> <br />
<br />Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-59772262832617393532014-06-07T14:49:00.001+03:002016-03-01T14:25:49.093+02:00Android FontIcon library available from Maven CentralThe latest version of <a href="http://blog.shamanland.com/p/android-fonticon-library.html" target="_blank">FontIcon library</a> for Android is available from Maven Central repository. It's easy to include it in project:<br />
<br />
<b>Gradle </b><br />
<br />
<div style="background: #ffe599; padding: 8px;">
<pre>repositories {
mavenCentral()
}
dependencies {
compile 'com.shamanland:fonticon:0.1.6'
}
</pre>
</div>
<br />
<b>Links </b><br />
<ul>
<li><a href="https://github.com/shamanland/fonticon" target="_blank">Sources</a></li>
<li><a href="http://blog.shamanland.com/p/android-fonticon-library.html" target="_blank">Project page</a></li>
</ul>
<br />Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-51454595381699515072014-06-07T00:17:00.000+03:002016-03-01T14:25:58.816+02:00Android Dashboards - June, 4thThis month Honeycomb devices are disappeared from <a href="https://developer.android.com/about/dashboards/index.html?utm_source=blog.shamanland.com" target="_blank">official statistics</a> about Android devices. There are three stable groups of API versions:<br />
<ul>
<li>Gingerbread (API 10) - 15%</li>
<li>Ice Cream Sandwich and Jelly Bean (API 15-18) - 70%</li>
<li>KitKat (API 19) - 14%</li>
</ul>
Check details in <a href="https://docs.google.com/spreadsheet/pub?key=0Agh0SNLPmjQBdDFuYnFwWWFDMENaN1AtRFBCdTJNclE" target="_blank">this public spreadsheet</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBS0UteVcwNU1VbjA" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="272" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBS0UteVcwNU1VbjA" width="640" /></a></div>
<br />Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-4621524363605605682014-05-19T23:12:00.001+03:002016-03-01T14:26:31.422+02:00Facebook SDK available from Maven repositoryI don't know why <a href="http://facebook.com/" target="_blank">Facebook</a> still not published theirs <a href="https://developers.facebook.com/docs/android/" target="_blank">SDK</a> to <a href="http://search.maven.org/" target="_blank">Maven Central</a>.<br />
Well, nobody forbids us to deploy it to Sonatype repository!<br />
<a name='more'></a><br />
<div style="background: #aaeeff; padding: 8px;">
<pre><span style="color: #f02020;"><b>UPDATE</b></span> (05-Nov-2014): Eventually, Facebook guys deployed theirs lib to <a href="http://search.maven.org/#artifactdetails%7Ccom.facebook.android%7Cfacebook-android-sdk%7C3.20.0%7Caar" target="_blank">Maven Central</a>! Congratulations!
</pre>
<pre></pre>
<pre></pre>
<pre>dependencies {</pre>
<pre> compile 'com.facebook.android:facebook-android-sdk:3.20.0'</pre>
<pre>}</pre>
</div>
<br />
If you want to include Facebook SDK for Android easily, just add few lines to your build.gradle file:<br />
<br />
<div style="background: #ffe599; padding: 8px;">
<pre>repositories {
maven {
url 'https://oss.sonatype.org/content/groups/public'
}
}
dependencies {
compile 'com.shamanland:facebook-android-sdk:3.15.0-SNAPSHOT'
}
</pre>
</div>
<br />
So, now you can add Facebook SDK to Android project as regular gradle-dependency.<br />
<br />
You can find sources of this assembly <a href="https://github.com/shamanland/facebook-android-sdk" target="_blank">here</a>. I hope some day Facebook guys will upload it to Maven Central.<br />
<br />
Check for updates and feel free to remind me if I miss new version of Facebook SDK for Android.<br />
<br />Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-87783962574862919112014-05-05T14:12:00.000+03:002016-03-01T14:26:36.844+02:00Android Dashboards - May, 1stLatest statistics about Android devices is available on <a href="http://developer.android.com/about/dashboards/index.html" target="_blank">developer.android.com</a>. As usual we publish additional statistics in public <a href="https://docs.google.com/spreadsheet/pub?key=0Agh0SNLPmjQBdDFuYnFwWWFDMENaN1AtRFBCdTJNclE" target="_blank">Google document</a>. You can check previous history and forecast for next month.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBR2VVVUphUXV0NEk" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://drive.google.com/uc?id=0Bwh0SNLPmjQBR2VVVUphUXV0NEk" height="272" width="640" /></a></div>
Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-69232675220549520812014-04-23T23:46:00.001+03:002016-03-01T14:26:48.499+02:00FontIcon Library now supports ColorStateListNew feature added to the <a href="http://blog.shamanland.com/p/android-fonticon-library.html" target="_blank">FontIcon Library</a> latest version 0.1.1.<br />
<br />
Now it's possible to set <a href="http://developer.android.com/guide/topics/resources/color-list-resource.html" target="_blank">color-selector</a> for icons. <a href="https://github.com/shamanland/fonticon/blob/dev/lib/src/main/java/com/shamanland/fonticon/FontIconDrawable.java" target="_blank">FontIconDrawable</a> will handle changing the state, propagated from parental Button, TextView, etc.<br />
<br />
<a name='more'></a><br />
You can see highlighted menu item here:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://drive.google.com/uc?id=0Bwh0SNLPmjQBcHcwcC1pTjBZOTQ" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://drive.google.com/uc?id=0Bwh0SNLPmjQBcHcwcC1pTjBZOTQ" width="225" /></a></div>
<br />
Check <a href="https://github.com/shamanland/fonticon" target="_blank">sources</a> of this library or just include it in your project via gradle dependency:<br />
<br />
<div style="background: #ffe599; padding: 8px;">
<pre>repositories {
mavenCentral()
}
dependencies {
compile 'com.shamanland:fonticon:0.1.6'
}
</pre>
</div>
<br />
Try this approach in your app!<br />
<br />
Direct <a href="https://docs.google.com/file/d/0Bwh0SNLPmjQBbXJVd3c3S2hfVTg/preview" target="_blank">link to this video</a> (there are some problem with mobile devices).<br />
<br />
<iframe height="385" src="https://docs.google.com/file/d/0Bwh0SNLPmjQBbXJVd3c3S2hfVTg/preview" width="640"></iframe>
Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-79878366053521565552014-03-05T08:38:00.001+02:002016-03-01T14:27:04.557+02:00Android Dashboards - March, 3Latest statistics about Android devices is available on <a href="http://developer.android.com/about/dashboards/index.html" target="_blank">developer.android.com</a>. As usual we publish additional statistics in public <a href="https://docs.google.com/spreadsheet/pub?key=0Agh0SNLPmjQBdDFuYnFwWWFDMENaN1AtRFBCdTJNclE" target="_blank">Google document</a>. You can check previous history and forecast for next month.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.comtag:blogger.com,1999:blog-4213617320663022802.post-48101421929613938762014-02-07T13:08:00.000+02:002016-03-01T14:27:29.762+02:00Android Dashboards. February 4th. Gingerbread still alive.Google published new statistics about active Android versions. The most important information is about Gingerbread. Many developers dream to stop support it. But it's still alive!<br />
<br />
<a href="http://shomeser.blogspot.com/2014/01/android-dashboards-january-2014.html" target="_blank">Last month</a> we made forecast and it was wrong. Check <a href="https://docs.google.com/spreadsheet/pub?key=0Agh0SNLPmjQBdDFuYnFwWWFDMENaN1AtRFBCdTJNclE" target="_blank">updated document</a> and make your own <span class="short_text" id="result_box" lang="en"><span class="hps">conclusion: support it or not.</span></span>Oleksii Kropachovhttp://www.blogger.com/profile/05905881948264541180noreply@blogger.com