Вверх ↑
Этот топик читают: Гость
Ответов: 95
Рейтинг: 2
#1156: 2015-02-10 23:23:14 ЛС | профиль | цитата
Netspirit, скорее всего, так и происходит. Вот только скролл в первую очередь отрисовывается на весь экран и уже потом линейный контейнер помещается под него, т.е. за пределами экрана.
карма: 0

0
Ответов: 4628
Рейтинг: 749
#1157: 2015-02-11 11:20:31 ЛС | профиль | цитата
Попробуй в LayoutScroll поставь HeightMode=WrapContent.
карма: 26

0
Ответов: 95
Рейтинг: 2
#1158: 2015-02-13 22:31:29 ЛС | профиль | цитата
Netspirit, так в том то и смысл: сделать внизу кнопку, а всё остальное пространство занять скроллом
карма: 0

0
Ответов: 578
Рейтинг: 14
#1159: 2015-02-14 16:49:59 ЛС | профиль | цитата
это можно (в прищепке), а вот как разместить 3 слоя вопрос
code_35114.txt
карма: 0

0
файлы: 1code_35114.txt [578B] [488]
Ответов: 4628
Рейтинг: 749
#1160: 2015-02-14 17:36:09 ЛС | профиль | цитата
Вот так должно получиться?
В Layout-компоненты сейчас добавлю свойство Weight
------------ Дoбавленo в 17.36:
На SVN обновлены LayoutLinear, LayoutScroll. Вот пример применения:

Add(MainActivity,1151572,266,84)
{
}
Add(LayoutLinear,15522506,399,238)
{
Name="down"
Order=1
Weight=1
WidthMode=1
gVertical=3
}
Add(LayoutScroll,6553478,399,175)
{
Name="up"
Weight=5
}
Add(Button,849396,448,238)
{
Left=200
Top=265
LayoutManager="down"
Point(onClick)
}
Add(TextView,8458221,448,175)
{
Left=280
Top=40
LayoutManager="up"
TextSize="30dp"
Caption="TextView
TextView
TextView
TextView
TextView
TextView
TextView
TextView
TextView
TextView
TextView
TextView
TextView
TextView
TextView
"
}

карма: 26

0
Ответов: 163
Рейтинг: 33
#1161: 2015-02-14 22:08:10 ЛС | профиль | цитата
Netspirit, sаmakacd, может возьмете на заметку. Я тут подумал, чтобы при использовании нескольких одинаковых (или разных) элементов, использующих какие-то однотипные переменные в коде, которые не меняются в процессе работы, бестолку плодятся копии этих переменных, содержащие одинаковые значения. Ну например, каким-нибудь элементам нужен ContentResolver. Ну и допустим мы будем получать его в onCreate при запуске программы. Если договориться о каком-то стандарте в названиях полей, то можно в функции Init всех элементов, которым нужен ContentResolver, разместить примерно такой код:
#hws
old = block.select(BLK_METHODS)
if(not block.intext('public ContentResolver common_content_resolver;'))
addToImport('android.content.Context')
addToImport('android.content.ContentResolver')
println('public ContentResolver common_content_resolver;')
block.select(BLK_ON_CREATE)
println('common_content_resolver = getApplicationContext().getContentResolver();')
end
block.select(old)
И поле common_content_resolver появится в коде на выходе лишь один раз (как и код по его инициализации).

И еще одно предложение. В сервисе неплохо бы в event onStart вывести Action переданного при запуске Intent`a (а в идеале еще и сам Intent снизу. Просто общаться с сервисом безопаснее всего именно через startService. При других способах надо быть уверенным что сервис запущен, иначе - exception. Прикладываю модификацию hiChildService, в которой Action выведен:
#hws
include("general")

func SaveEnvironment()
// --- Сохраняем окружение родительского контейнера
old_local_vars = BLK_LOC_VAR
old_local_methods = BLK_METHODS
old_oncreate = BLK_ON_CREATE
old_onstart = BLK_ON_START
old_ondestroy = BLK_ON_DESTROY
old_class_name = CURRENT_CLASS
old_import = BLK_IMPORT
old_classes = BLK_CLASSES

old_parent_id = PARENT_ID
old_finalize = ARR_FINALIZE
// ---
end

func RestoreEnvironment()
// --- Восстанавливаем окружение родительского контейнера
BLK_LOC_VAR = old_local_vars
BLK_METHODS = old_local_methods
BLK_ON_CREATE = old_oncreate
BLK_ON_START = old_onstart
BLK_ON_DESTROY = old_ondestroy
CURRENT_CLASS = old_class_name
BLK_IMPORT = old_import
BLK_CLASSES = old_classes

PARENT_ID = old_parent_id

cur_finalize = ARR_FINALIZE
ARR_FINALIZE = old_finalize
// ---
end

func SetEnvironment()
// --- Создаем окружение текущего контейнера
BLK_LOC_VAR = local_vars
BLK_METHODS = local_methods
BLK_ON_CREATE = cur_oncreate
BLK_ON_START = cur_onstart
BLK_ON_DESTROY = cur_ondestroy
CURRENT_CLASS = cur_class_name
BLK_IMPORT = cur_import
BLK_CLASSES = cur_classes

PARENT_ID = sys.curelement()
ARR_FINALIZE = cur_finalize
// ---
end

// ============================================ INIT ============================================== //

func Init()
fvar(old, tmp, tmp2, this)
var(local_vars, local_methods, cur_oncreate,
cur_onstart, cur_ondata, cur_ondestroy, cur_manifest,
cur_import, cur_classes, cur_finalize)

var(old_local_vars, old_local_methods, old_oncreate,
old_onstart, old_ondestroy, old_class_name, old_import,
old_classes, old_parent_id, old_finalize)
var(cur_class_name, cur_parent_class_name)


this = sys.curelement()
sys.selectelement(cgt.el_get_parent_id())
tmp = cur_class_name
tmp2 = cur_parent_class_name
sys.selectelement (this)
cur_class_name = tmp
cur_parent_class_name = tmp2


// --- Подготавливаем окружение текущего контейнера
local_vars = block.reggen()
local_methods = block.reggen()
cur_oncreate = block.reggen()
cur_onstart = block.reggen()
cur_ondata = block.reggen()
cur_ondestroy = block.reggen()
cur_import = block.reggen()
cur_classes = block.reggen()

cur_finalize &= ''

old = block.cur()

// --- Сохраняем окружение родительского контейнера
SaveEnvironment()

// --- Создаем окружение текущего контейнера
SetEnvironment()


block.select(BLK_IMPORT)
println('package ', PACKAGE_NAME, ';')
println('import android.app.Service;')
println('import android.app.Service;')
println('import android.content.Intent;')
println('import android.os.IBinder;')
block.select(old)


sys.initall()

// ======== Обработка событий ======== //

if(linked(onCreate))
tmp = block.reggen()
block.select(tmp)
event(onCreate)
block.select(BLK_ON_CREATE)
block.copyhere(tmp)
block.delete(tmp)
end


if(linked(onStart))
fvar(res)
AddVar(serv_start_action, 'String')
tmp = block.reggen()
block.select(tmp)
println ('if (',intent,' == null) ',serv_start_action,' = "";')
println ('else {')
block.inclvl()
println (serv_start_action,' = ',intent,'.getAction();')
println ('if (',serv_start_action,' == null) ',serv_start_action,' = "";')
block.declvl()
println ('}')

res = ToType(serv_start_action, 2)
event(onStart, res)
block.select(BLK_ON_START)
block.copyhere(tmp)
block.delete(tmp)
end

if(linked(onData))
tmp = block.reggen()
block.select(tmp)
event(onData, toType(idata, 100))
block.select(cur_ondata)
block.copyhere(tmp)
block.delete(tmp)
end

if(linked(onDestroy))
tmp = block.reggen()
block.select(tmp)
event(onDestroy)
block.select(BLK_ON_DESTROY)
block.copyhere(tmp)
block.delete(tmp)
end

// ======== ================= ======== //

block.select(old)

// --- Восстанавливаем окружение родительского контейнера
RestoreEnvironment()

end

// ========================================================================================== //


func doStop(_data)
println('stopSelf();')
end

func getData(d)
if(array_count(d) == 2)
return(d[1])
elseif(d != '')
return(d)
else
return('""')
end
end

func doSendData(_data)
println(mem,' = new Memory();')
println(mem,'.setValue(',getData(_data),');')
println(cur_parent_class_name,'.activity.on',cur_class_name,'Data(',mem,');')
println('DataNotifier.notify("',cur_class_name,'", ',mem,');')
end

func doStartForeground(_data)
fvar(n, i)

if(ForegroundNotification != 0)
n = sys.event(ForegroundNotification, 'get_notification')
i = sys.event(ForegroundNotification, 'get_id')

println('startForeground(',i,', ',n,');')
end
end

func doStopForeground(_data)
if(ForegroundNotification != 0)
println('stopForeground(true);')
end
end

// ============================================ FINISH ============================================== //
func Finish()
fvar(old, tmp, i, this, class_body, cls_index)

old = block.cur()

// --- Сохраняем окружение родительского контейнера
SaveEnvironment()

// --- Создаем окружение текущего контейнера
SetEnvironment()


// ********** Вызов метода finish() зарегистрированных компонентов *********** //

for (i = 1; i<_arr.count(ARR_FINALIZE); i++)
sys.event(ARR_FINALIZE[i], 'finish')
end

// *************************************************************************** //


// ******** Тело класса ******** //

class_body = block.reggen()
ARR_CLASSES &= "x"
cls_index = _arr.count(ARR_CLASSES)-1
ARR_CLASSES[cls_index] = cur_class_name & class_body

block.select(class_body)

block.copyhere(cur_import)
block.delete(cur_import)

println('public class ', cur_class_name, ' extends Service {')
block.inclvl()

println('public static ',cur_class_name,' service;') // Статическое поле для передачи данных
println('public Memory ',mem,';')
block.copyhere(local_vars)
block.delete(local_vars)
block.copyhere(local_methods)
block.delete(local_methods)

println('')
println('@Override')
println('public IBinder onBind(Intent ',arg,') {')
block.inclvl()
println('return null;')
block.declvl()
println('}')

//== onCreate
println('')
println('@Override')
println('public void onCreate() {')
block.inclvl()
println('super.onCreate();')
block.copyhere(cur_oncreate)
block.delete(cur_oncreate)
block.declvl()
println('}')
// ==

//== onStart
println('@Override')
println('public int onStartCommand(Intent ',intent,', int ',flags,', int ',startId,') {')
block.inclvl()
println('service = this;')
block.copyhere(cur_onstart)
block.delete(cur_onstart)
println('return START_STICKY;')
block.declvl()
println('}')
// ==

//== onData
println('public void onData(Memory ',idata,') {')
block.inclvl()
block.copyhere(cur_ondata)
block.delete(cur_ondata)
block.declvl()
println('}')
// ==

//== onDestroy
if (not block.isempty(cur_ondestroy))
println('@Override')
println('public void onDestroy() {')
block.inclvl()
block.copyhere(cur_ondestroy)
block.delete(cur_ondestroy)
println('super.onDestroy();')
block.declvl()
println('}')
end
// ==

block.declvl()
println('}') // Закрывающая скобка текущего класса

// Дополнительные классы
block.copyhere(cur_classes)
block.delete(cur_classes)

// ******************************** //

// ******** MANIFEST ******** //

block.select('BLK_MANIFEST')
tmp = block.reggen()
block.select(tmp)
println('<service android:name=".',cur_class_name,'"></service>')
block.select('BLK_MAINBODY')
MFAddComponent(tmp)
block.delete(tmp)

// ************************ //

block.select(old)

// --- Восстанавливаем окружение родительского контейнера
RestoreEnvironment()

end

// ========================================================================================== //

Ну и на последок, я в своих элементах заметил несколько ошибок из-за невнимательности, так что скоро обновлю.
карма: 3

0
Ответов: 4628
Рейтинг: 749
#1162: 2015-02-15 12:06:50 ЛС | профиль | цитата
GreM, глянь на сервис, так ли всё, как нужно: andr childservice upd 2015-02-15.7z
На будущее: если данные выдаются в поток и нету соответствующей нижней точки и они нигде по коду больше не используются - нет необходимости создавать глобальную переменную с помощью AddVar(). Потому что выдаваемые в поток данные могут быть использованы только в текущем методе, который вызвал событие. Чтобы использовать их позже, пользователю нужно будет сохранить данные из потока в Memory, а это уже и будет глобальная переменная. Вот для точки Intent нужно добавлять переменную.
Кроме того для данных типа int, String, double можно просто проставлять код точки в ini (1,2,7), тогда не будет необходимости использовать ToType при выдачи данных на точку.

По поводу ContentResolver. Что-то у тебя слишком много телодвижений. А что, нельзя в том месте, где он нужен, сделать
AddToImport('android.content.ContentResolver')
println('ContentResolver ', cr, ' = getApplicationContext().getContentResolver();')
...

карма: 26

0
Ответов: 163
Рейтинг: 33
#1163: 2015-02-15 17:22:23 ЛС | профиль | цитата
Netspirit, я там не зря вставил 2 проверки на null. Согласно документации,
public int onStartCommand (Intent intent, int flags, int startId)
...
intent The Intent supplied to startService(Intent), as given. This may be null if the service is being restarted after its process has gone away, and it had previously returned anything except START_STICKY_COMPATIBILITY.
Ну и сам Action часто может быть null, это необходимо учесть.

Netspirit писал(а):
нет необходимости создавать глобальную переменную с помощью AddVar()
Тут согласен, в данном случае можно было локальную переменную в функции объявить. Или завернуть что-то вроде
#hws
event(onStart, (ToType(',intent,' == null?"":(',intent,'.getAction() == null?"":',intent,'.getAction())), 2))
, но у меня от такого мозги плавятся :D
Netspirit писал(а):
Кроме того для данных типа int, String, double можно просто проставлять код точки в ini (1,2,7), тогда не будет необходимости использовать ToType при выдачи данных на точку.
Надо записать куда-нибудь, спасибо.

Netspirit писал(а):
По поводу ContentResolver. Что-то у тебя слишком много телодвижений. А что, нельзя в том месте, где он нужен, сделать
AddToImport('android.content.ContentResolver')
println('ContentResolver ', cr, ' = getApplicationContext().getContentResolver();')...
Оно то можно... Видно я после ассемблера больно придирчив к оптимизации стал Чего процессор по нескольку раз гонять прыжками по подпрограммам, если результат всегда одинаков будет? Для оптимизации под скорость лучше один раз прогнать, а потом только из переменной результат считывать. [flood]Вообще меня после асма джава до сих пор коробит Как-то не по себе мне от ее философии.[/flood]И кстати, в приведенном тобой виде можно делать только если это все в джава-коде будет обернуто в отдельный метод. Иначе поставим хаб на входе (разветвляющий) и подключим два его выхода к одному и тому же методу нашего элемента, и компилятор скажет о попытке дважды объявить одну и ту же переменную в одном методе. Тут либо делать cr глобальной переменной, либо везде по месту тыкать getApplicationContext().getContentResolver(). Вот, кстати, наглядный пример и повод задуматься:
#hws
Add(MainActivity,2953706,21,105)
{
Point(onResume)
link(onResume,16007637:doData,[])
}
Add(Display,5512927,245,126)
{
}
Add(Hub,15501647,182,133)
{
link(onEvent1,4767377:doWork2,[])
link(onEvent2,4767377:doWork3,[(214,146)])
}
Add(DoData,16007637,133,133)
{
Data=Integer(100)
link(onEventData,15501647:doEvent1,[])
}
Add(HubEx,4767377,210,133)
{
link(onEvent,5512927:doSetBrightness,[])
}
------------ Дoбавленo в 17.22:
В общем я это все к чему? Вот столкнулся я при написании элементов с проблемой как в последней приведенной схеме. И задумался, какие варианты?

  • Использовать в джава-коде только глобальные переменные.
  • Оборачивать код с локальными переменными в отдельный метод.
Сейчас я пользуюсь и тем и этим, но мне не нравились дубликаты одинаковых переменных и методов. Вот тогда я решил, пользуясь возможностями block.intext, создавать в коде на выходе эти переменные и методы-обертки лишь в одном экземпляре. И тут открывается еще более интересная возможность: эти вещи можно использовать в совершенно разных элементах (тот же ContentResolver может понадобиться разным по назначению элементам). Да, при написании элементов телодвижений больше, но в коде на выходе - наоборот меньше). И чем больше схема, тем это оправданней. Как-то так мне кажется
карма: 3

0
Ответов: 4628
Рейтинг: 749
#1164: 2015-02-15 18:58:37 ЛС | профиль | цитата
GreM писал(а):
сам Action часто может быть null
Не проверял, но вроде String с null в строковых операциях ведет себя как пустая строка ""?
А вот то, что Intent может быть null, так а что делать в таком случае? Вручную создавать пустой?
В схеме можно поставить ErrorHandler...

GreM писал(а):
Чего процессор по нескольку раз гонять
Не зацикливайся на скорости. Когда единственной проблемой пакета будет скорость, тогда и можно заморачиваться.

GreM писал(а):
какие варианты?

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

Вообще, если будут созданы некоторое количество компонентов, требующих ContentResolver - сделаем.
------------ Дoбавленo в 18.58:
Так пойдёт?
карма: 26

0
Ответов: 163
Рейтинг: 33
#1165: 2015-02-16 13:05:49 ЛС | профиль | цитата
Netspirit писал(а):
Так пойдёт?
Пойдет, пойдет . Так-то там кроме ContentResolver`а и SensorManager и PowerManager и WindowManager и еще много указателей можно найти, которые в процессе работы не меняются, но это я просто идейку подкинул, может когда пригодится, а может нет.

Netspirit писал(а):
вроде String с null в строковых операциях ведет себя как пустая строка
Завтра попробую. Заодно и сервис погоняю. И что делать с интентом подумаю.
------------ Дoбавленo в 13.05:
Netspirit, попробовал сервис последней правки (вчера не заметил как ты обновил). Запускается нормально, но при автоматическим перезапуске после остановки системой по нехватке памяти, крешется при попытке сравнить Action с какой-нибудь строкой. А вот если после println('st_intent = (', intnt,' != null)?', intnt,': new Intent();') добавить println('if (st_intent.getAction() == null) st_intent.setAction("");'), то работает нормально. Ну и тогда в описание точки onStart можно добавить: "При отсутствии Action выдает пустую строку".
карма: 3

0
Ответов: 4628
Рейтинг: 749
#1166: 2015-02-16 14:00:15 ЛС | профиль | цитата
Обновил.
карма: 26

0
Ответов: 163
Рейтинг: 33
#1167: 2015-02-16 14:21:06 ЛС | профиль | цитата
Что-то ты опять вчерашнее упаковал.
карма: 3

0
Ответов: 4628
Рейтинг: 749
#1168: 2015-02-16 14:23:33 ЛС | профиль | цитата
На SVN обновил.
карма: 26

1
Голосовали:GreM
Ответов: 163
Рейтинг: 33
#1169: 2015-02-26 08:40:27 ЛС | профиль | цитата
Привет. Предлагаю несколько правок.
Vibrator_.zip

  • Сверху точка Pattern, к которой можно подключить массив.
  • Добавлена точка doPatternFromString, которая принимает строку вида "пауза,вибрация,пауза,и т.д." и преобразует ее в массив. Просто шаблон вибрации удобно хранить в SharedPreferences в виде строки. Можно конечно и элементами пакета строку в массив преобразовывать, но громоздко получается.
  • Ну и уж коли преобразование строки в массив внутрь элемента спрятано, добавлена точка PatternFromStringDuration, возвращающая сумму длительностей пауз и вибраций, подсчитываемую при преобразовании строки в массив.

Intent.zip
Добавлено св-во Flags.

Spinner.zip
Раньше при вызове doItems шрифт списка становился черным. В результате при темной теме ничего не было видно. Еще после вызова doItems происходило увеличение высоты спинера. Долго мучался (не люблю я визуальными элементами заниматься), в результате переделал создание спинера "по букварю". Layout шрифта спинера из кода удалил. В onCreate создается ArrayAdapter, использующий layout "android.R.layout.simple_spinner_item". Одно не удалось - очищать ArrayAdapter методом clear при вызове doItems. Так что каждый раз при изменении списка создается новый ArrayAdapter.

Method.zip
sаmakacd, зря ты его забросил, интересный элемент. Идеальная замена ic, когда надо вставить в схему буквально пару строчек своего кода. А еще можно стандартные методы Activity переопределять (мне вот понадобилось onUserLeaveHint переопределить, ну не править же ради этого элемент Activity). Вот только точка Result некорректно работала (уже забыл подробности). Ну я немного подправил.
карма: 3

0
Ответов: 4628
Рейтинг: 749
#1170: 2015-02-26 11:16:58 ЛС | профиль | цитата
С флагами в Intent: а почему их не сделать в виде группы с включением по True/False?
карма: 26

0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)