Динамическое создание интерфейса.
-
mechanikos
- Сообщения: 33
- Зарегистрирован: 30 сен 2013, 12:14
Динамическое создание интерфейса.
Уважаемые форумчане, не подскажите как можно реализовать создание интерфейса в активити по переданному приложению xml-файлу, чтобы приложение могло создавать его на лету. если не сложно подскажите хотя бы откуда и куда копать.
Re: Динамическое создание интерфейса.
Смотрели уроки 16, 17 и обсуждения этих уроков на форуме?
Когда выкладываете код на форум - код оформляйте. Редактор - поищите слова Geshi Syntax -Java. (или xml)
Свои сообщения можно редактировать - кнопка edit.
Свои сообщения можно редактировать - кнопка edit.
-
mechanikos
- Сообщения: 33
- Зарегистрирован: 30 сен 2013, 12:14
Re: Динамическое создание интерфейса.
да, и я в принципе понимаю как сделать программно нужный мне интрефейс. проблема в том как реализовать когда приложение получает готовый хмl в котором уже сверстан интерфейс и как по нему этот интерфейс создать.( если я что то не заметил в уроках или обсуждениях к ним, будьте добры укажите на мою ошибку(trew писал(а):Смотрели уроки 16, 17 и обсуждения этих уроков на форуме?
Re: Динамическое создание интерфейса.
Вот пример того, что Вам нужноmechanikos писал(а):да, и я в принципе понимаю как сделать программно нужный мне интрефейс. проблема в том как реализовать когда приложение получает готовый хмl в котором уже сверстан интерфейс и как по нему этот интерфейс создать.( если я что то не заметил в уроках или обсуждениях к ним, будьте добры укажите на мою ошибку(trew писал(а):Смотрели уроки 16, 17 и обсуждения этих уроков на форуме?
Код: Выделить всё
public class MainActivity extends Activity {
LinearLayout mainLayer;
View layer1, layer2;
CheckBox enableLayer1, enableLayer2, enableLayer3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
enableLayer1 = (CheckBox) findViewById(R.id.enlayer1);
enableLayer2 = (CheckBox) findViewById(R.id.enlayer2);
mainLayer = (LinearLayout) findViewById(R.id.master);
LayoutInflater inflater = getLayoutInflater();
layer1 = inflater.inflate(R.layout.layer1, null);
layer2 = inflater.inflate(R.layout.layer2, null);
enableLayer1.setOnCheckedChangeListener(enableLayer1ChangeListener);
enableLayer2.setOnCheckedChangeListener(enableLayer2ChangeListener);
}
CheckBox.OnCheckedChangeListener enableLayer1ChangeListener = new CheckBox.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (isChecked) {
mainLayer.addView(layer1);
} else {
mainLayer.removeView(layer1);
}
}
};
CheckBox.OnCheckedChangeListener enableLayer2ChangeListener = new CheckBox.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (isChecked) {
mainLayer.addView(layer2);
} else {
mainLayer.removeView(layer2);
}
}
};
}
Когда выкладываете код на форум - код оформляйте. Редактор - поищите слова Geshi Syntax -Java. (или xml)
Свои сообщения можно редактировать - кнопка edit.
Свои сообщения можно редактировать - кнопка edit.
- KamiSempai
- Сообщения: 1339
- Зарегистрирован: 17 фев 2012, 21:23
- Откуда: Мордор
Re: Динамическое создание интерфейса.
LayoutInflater может принимать на вход XmlPullParser. Что будет парсить XmlPullParser зависит только от вас. Можно даже использовать скачанный с интернета файл. Останется только установить полученный View в качестве контента в Активности.mechanikos писал(а):Уважаемые форумчане, не подскажите как можно реализовать создание интерфейса в активити по переданному приложению xml-файлу, чтобы приложение могло создавать его на лету. если не сложно подскажите хотя бы откуда и куда копать.
PS: Если будете использовать XML разметки не из приложения, советую проверять на наличие всех необходимых View. Иначе при испорченном XML можно наткнуться на NullPointerExecption.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.
Хватит таскать макулатуру на тренировку! Используй T Note.
-
mechanikos
- Сообщения: 33
- Зарегистрирован: 30 сен 2013, 12:14
Re: Динамическое создание интерфейса.
я чего то не понимаю... а зачем в таком случае использовать XmlPullParser? разве layoutinflater не принимает сразу xml-файл? и вопрос не по теме но я сейчас всегда использовал хмl-файлы из проекта которые лежали в папке res/xml/ но как быть чтобы использовать файл из любой директории?KamiSempai писал(а):LayoutInflater может принимать на вход XmlPullParser. Что будет парсить XmlPullParser зависит только от вас. Можно даже использовать скачанный с интернета файл. Останется только установить полученный View в качестве контента в Активности.mechanikos писал(а):Уважаемые форумчане, не подскажите как можно реализовать создание интерфейса в активити по переданному приложению xml-файлу, чтобы приложение могло создавать его на лету. если не сложно подскажите хотя бы откуда и куда копать.
PS: Если будете использовать XML разметки не из приложения, советую проверять на наличие всех необходимых View. Иначе при испорченном XML можно наткнуться на NullPointerExecption.
- KamiSempai
- Сообщения: 1339
- Зарегистрирован: 17 фев 2012, 21:23
- Откуда: Мордор
Re: Динамическое создание интерфейса.
Вы не поверите, но данном случае layoutinflater самостаятельно создает XmlParser из файла, id на который вы передаете в параметрах.mechanikos писал(а):я чего то не понимаю... а зачем в таком случае использовать XmlPullParser? разве layoutinflater не принимает сразу xml-файл?
У XmlPullParser есть метод setInput (InputStream inputStream, String inputEncoding).mechanikos писал(а):... и вопрос не по теме но я сейчас всегда использовал хмl-файлы из проекта которые лежали в папке res/xml/ но как быть чтобы использовать файл из любой директории?
Открываете файл, получаете InputStream, передаете в качестве параметра. Второй параметр может быть null.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.
Хватит таскать макулатуру на тренировку! Используй T Note.
-
mechanikos
- Сообщения: 33
- Зарегистрирован: 30 сен 2013, 12:14
Re: Динамическое создание интерфейса.
KamiSempai писал(а):Вы не поверите, но данном случае layoutinflater самостаятельно создает XmlParser из файла, id на который вы передаете в параметрах.mechanikos писал(а):я чего то не понимаю... а зачем в таком случае использовать XmlPullParser? разве layoutinflater не принимает сразу xml-файл?У XmlPullParser есть метод setInput (InputStream inputStream, String inputEncoding).mechanikos писал(а):... и вопрос не по теме но я сейчас всегда использовал хмl-файлы из проекта которые лежали в папке res/xml/ но как быть чтобы использовать файл из любой директории?
Открываете файл, получаете InputStream, передаете в качестве параметра. Второй параметр может быть null.
вот большое спасибо) до вашей второй подсказки допер уже сам ночью но основная проблема вот в в чем: layoutinflater самостоятельно создает XmlParser из файла, id на который вы передаете в параметрах. Как мне получить id файла который у меня не зашит в ресурсы проекта а лежит допустим на флешке? разве все константы не генерятся сами в R.java на этапе компиляции? буду очень благодарен вам если вы покажете хоть какой нибудь пример( а то я пока без большого опыта часто бодаюсь с синтаксисом хотя в основном делаю правильно.
- KamiSempai
- Сообщения: 1339
- Зарегистрирован: 17 фев 2012, 21:23
- Откуда: Мордор
Re: Динамическое создание интерфейса.
Как-то так:Где path - это путь к XML файлу.
Код: Выделить всё
InputStream streem = new FileInputStream(path);
XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
parser.setInput(streem, null);
View view = getLayoutInflater().inflate(parser, null);R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.
Хватит таскать макулатуру на тренировку! Используй T Note.
-
mechanikos
- Сообщения: 33
- Зарегистрирован: 30 сен 2013, 12:14
Re: Динамическое создание интерфейса.
сделал как вы посоветовали но к сожалению приложение вылетает при запуске. не могу понять что я делаю не такKamiSempai писал(а):Как-то так:Где path - это путь к XML файлу.Код: Выделить всё
InputStream streem = new FileInputStream(path); XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser(); parser.setInput(streem, null); View view = getLayoutInflater().inflate(parser, null);
Код: Выделить всё
package com.example;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends Activity {
LinearLayout mainLayer;
View view, layer2;
CheckBox enableLayer1, enableLayer2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
enableLayer1 = (CheckBox) findViewById(R.id.enlayer1);
enableLayer2 = (CheckBox) findViewById(R.id.enlayer2);
mainLayer = (LinearLayout) findViewById(R.id.master);
InputStream streem = null;
try {
streem = new FileInputStream("/data/data/Test.xml");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
XmlPullParser parser = null;
try {
parser = XmlPullParserFactory.newInstance().newPullParser();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
parser.setInput(streem, null);
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
LayoutInflater inflater = getLayoutInflater();
view=inflater.inflate(parser, null);
layer2 = inflater.inflate(R.layout.layer2, null);
enableLayer1.setOnCheckedChangeListener(enableLayer1ChangeListener);
enableLayer2.setOnCheckedChangeListener(enableLayer2ChangeListener);
}
CheckBox.OnCheckedChangeListener enableLayer1ChangeListener = new CheckBox.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (isChecked) {
mainLayer.addView(view);
} else {
mainLayer.removeView(view);
}
}
};
CheckBox.OnCheckedChangeListener enableLayer2ChangeListener = new CheckBox.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (isChecked) {
mainLayer.addView(layer2);
} else {
mainLayer.removeView(layer2);
}
}
};
- KamiSempai
- Сообщения: 1339
- Зарегистрирован: 17 фев 2012, 21:23
- Откуда: Мордор
Re: Динамическое создание интерфейса.
Что в логах?
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.
Хватит таскать макулатуру на тренировку! Используй T Note.
-
mechanikos
- Сообщения: 33
- Зарегистрирован: 30 сен 2013, 12:14
Re: Динамическое создание интерфейса.
секунду сейчас добавлю вывод эксепшена в логKamiSempai писал(а):Что в логах?
-
mechanikos
- Сообщения: 33
- Зарегистрирован: 30 сен 2013, 12:14
Re: Динамическое создание интерфейса.
очень много всего пишет( но вижу что то про InputStreamReaderKamiSempai писал(а):Что в логах?
upd.
буду очень благодарен все кто сможет объяснить в чем проблема тут... у меня к сожалению уже пол пятого утра и поэтому посплю перед парами чуток
- KamiSempai
- Сообщения: 1339
- Зарегистрирован: 17 фев 2012, 21:23
- Откуда: Мордор
Re: Динамическое создание интерфейса.
Ни о чем не говорит. Может быть все что угодно. Наиболее вероятное - это отсутствие разрешения на работу с файлами и ли не правильно указанный путь.mechanikos писал(а):очень много всего пишет( но вижу что то про InputStreamReader
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.
Хватит таскать макулатуру на тренировку! Используй T Note.
-
mechanikos
- Сообщения: 33
- Зарегистрирован: 30 сен 2013, 12:14
Re: Динамическое создание интерфейса.
я в документации к инфлэйту вот что нарылKamiSempai писал(а):Ни о чем не говорит. Может быть все что угодно. Наиболее вероятное - это отсутствие разрешения на работу с файлами и ли не правильно указанный путь.mechanikos писал(а):очень много всего пишет( но вижу что то про InputStreamReader
"Important For performance reasons, view inflation relies heavily on pre-processing of XML files that is done at build time. Therefore, it is not currently possible to use LayoutInflater with an XmlPullParser over a plain XML file at runtime."
это случайно не означает что у меня нихрена не выйдет скармилвать инфлэйту через парсер внешний xml?
- KamiSempai
- Сообщения: 1339
- Зарегистрирован: 17 фев 2012, 21:23
- Откуда: Мордор
Re: Динамическое создание интерфейса.
Хм... А я это пропустил. Действительно, так не получится. Во всяком случае, до этого пока даже не дошло иначе была бы ошибка InflateException.mechanikos писал(а):Я в документации к инфлэйту вот что нарыл
"Important For performance reasons, view inflation relies heavily on pre-processing of XML files that is done at build time. Therefore, it is not currently possible to use LayoutInflater with an XmlPullParser over a plain XML file at runtime."
это случайно не означает что у меня нихрена не выйдет скармилвать инфлэйту через парсер внешний xml?
Там говорится, что при сборке приложения XML файлы проходят предварительную обработку. Следовательно, если передать обработанный файл, должно сработать.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.
Хватит таскать макулатуру на тренировку! Используй T Note.
-
mechanikos
- Сообщения: 33
- Зарегистрирован: 30 сен 2013, 12:14
Re: Динамическое создание интерфейса.
каким образом обработанный? и если все таки первоначальный план не работает то что делать теперь? в ручную парсить хмл и в соответсвии с тэгами пытаться создать гуй из кода?KamiSempai писал(а):Хм... А я это пропустил. Действительно, так не получится. Во всяком случае, до этого пока даже не дошло иначе была бы ошибка InflateException.mechanikos писал(а):Я в документации к инфлэйту вот что нарыл
"Important For performance reasons, view inflation relies heavily on pre-processing of XML files that is done at build time. Therefore, it is not currently possible to use LayoutInflater with an XmlPullParser over a plain XML file at runtime."
это случайно не означает что у меня нихрена не выйдет скармилвать инфлэйту через парсер внешний xml?
Там говорится, что при сборке приложения XML файлы проходят предварительную обработку. Следовательно, если передать обработанный файл, должно сработать.
- KamiSempai
- Сообщения: 1339
- Зарегистрирован: 17 фев 2012, 21:23
- Откуда: Мордор
Re: Динамическое создание интерфейса.
Вот этого точно делать не стоит.mechanikos писал(а):каким образом обработанный? и если все таки первоначальный план не работает то что делать теперь? в ручную парсить хмл и в соответсвии с тэгами пытаться создать гуй из кода?
Остается только одна надежда. Скомпилировать APK с нужным XML и вытащить его из него. Делается это легко, так как, фактически APK представляет из себя обычный архив и распаковывается любым архиватором.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.
Хватит таскать макулатуру на тренировку! Используй T Note.
-
mechanikos
- Сообщения: 33
- Зарегистрирован: 30 сен 2013, 12:14
Re: Динамическое создание интерфейса.
по подробнее. то есть отправлять не сам xml а допустим пустой проект с xml файлом? или как то програмно можно создать апк с хмл-ом? и как его оттуда потом доставать? устанавливать apk или опять же его как то разархивировать программно? если устанавливать то доставать xml через гетресурс или так же просто указать путь? в обещм если вам не трудно опишите здесь или в личке пожалуйста примерно или подробно как поступить лучше и какие телодвижения для этого нужно совершитьKamiSempai писал(а):Вот этого точно делать не стоит.mechanikos писал(а):каким образом обработанный? и если все таки первоначальный план не работает то что делать теперь? в ручную парсить хмл и в соответсвии с тэгами пытаться создать гуй из кода?
Остается только одна надежда. Скомпилировать APK с нужным XML и вытащить его из него. Делается это легко, так как, фактически APK представляет из себя обычный архив и распаковывается любым архиватором.