Динамическое создание интерфейса.

Интерфейс, диалоги, темы, стили, меню
Ответить
mechanikos
Сообщения: 33
Зарегистрирован: 30 сен 2013, 12:14

Динамическое создание интерфейса.

Сообщение mechanikos » 30 сен 2013, 12:15

Уважаемые форумчане, не подскажите как можно реализовать создание интерфейса в активити по переданному приложению xml-файлу, чтобы приложение могло создавать его на лету. если не сложно подскажите хотя бы откуда и куда копать.

Аватара пользователя
trew
Сообщения: 450
Зарегистрирован: 28 сен 2013, 17:34

Re: Динамическое создание интерфейса.

Сообщение trew » 30 сен 2013, 12:25

Смотрели уроки 16, 17 и обсуждения этих уроков на форуме?
Когда выкладываете код на форум - код оформляйте. Редактор - поищите слова Geshi Syntax -Java. (или xml)
Свои сообщения можно редактировать - кнопка edit.

mechanikos
Сообщения: 33
Зарегистрирован: 30 сен 2013, 12:14

Re: Динамическое создание интерфейса.

Сообщение mechanikos » 30 сен 2013, 13:19

trew писал(а):Смотрели уроки 16, 17 и обсуждения этих уроков на форуме?
да, и я в принципе понимаю как сделать программно нужный мне интрефейс. проблема в том как реализовать когда приложение получает готовый хмl в котором уже сверстан интерфейс и как по нему этот интерфейс создать.( если я что то не заметил в уроках или обсуждениях к ним, будьте добры укажите на мою ошибку(

Аватара пользователя
trew
Сообщения: 450
Зарегистрирован: 28 сен 2013, 17:34

Re: Динамическое создание интерфейса.

Сообщение trew » 30 сен 2013, 16:44

mechanikos писал(а):
trew писал(а):Смотрели уроки 16, 17 и обсуждения этих уроков на форуме?
да, и я в принципе понимаю как сделать программно нужный мне интрефейс. проблема в том как реализовать когда приложение получает готовый хмl в котором уже сверстан интерфейс и как по нему этот интерфейс создать.( если я что то не заметил в уроках или обсуждениях к ним, будьте добры укажите на мою ошибку(
Вот пример того, что Вам нужно

Код: Выделить всё

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);
			}
		}
	};
}
Источник http://developer.alexanderklimov.ru/and ... ddview.php
Когда выкладываете код на форум - код оформляйте. Редактор - поищите слова Geshi Syntax -Java. (или xml)
Свои сообщения можно редактировать - кнопка edit.

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Динамическое создание интерфейса.

Сообщение KamiSempai » 30 сен 2013, 18:08

mechanikos писал(а):Уважаемые форумчане, не подскажите как можно реализовать создание интерфейса в активити по переданному приложению xml-файлу, чтобы приложение могло создавать его на лету. если не сложно подскажите хотя бы откуда и куда копать.
LayoutInflater может принимать на вход XmlPullParser. Что будет парсить XmlPullParser зависит только от вас. Можно даже использовать скачанный с интернета файл. Останется только установить полученный View в качестве контента в Активности.

PS: Если будете использовать XML разметки не из приложения, советую проверять на наличие всех необходимых View. Иначе при испорченном XML можно наткнуться на NullPointerExecption.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

mechanikos
Сообщения: 33
Зарегистрирован: 30 сен 2013, 12:14

Re: Динамическое создание интерфейса.

Сообщение mechanikos » 30 сен 2013, 21:36

KamiSempai писал(а):
mechanikos писал(а):Уважаемые форумчане, не подскажите как можно реализовать создание интерфейса в активити по переданному приложению xml-файлу, чтобы приложение могло создавать его на лету. если не сложно подскажите хотя бы откуда и куда копать.
LayoutInflater может принимать на вход XmlPullParser. Что будет парсить XmlPullParser зависит только от вас. Можно даже использовать скачанный с интернета файл. Останется только установить полученный View в качестве контента в Активности.

PS: Если будете использовать XML разметки не из приложения, советую проверять на наличие всех необходимых View. Иначе при испорченном XML можно наткнуться на NullPointerExecption.
я чего то не понимаю... а зачем в таком случае использовать XmlPullParser? разве layoutinflater не принимает сразу xml-файл? и вопрос не по теме но я сейчас всегда использовал хмl-файлы из проекта которые лежали в папке res/xml/ но как быть чтобы использовать файл из любой директории?

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Динамическое создание интерфейса.

Сообщение KamiSempai » 01 окт 2013, 14:29

mechanikos писал(а):я чего то не понимаю... а зачем в таком случае использовать XmlPullParser? разве layoutinflater не принимает сразу xml-файл?
Вы не поверите, но данном случае layoutinflater самостаятельно создает XmlParser из файла, id на который вы передаете в параметрах.
mechanikos писал(а):... и вопрос не по теме но я сейчас всегда использовал хмl-файлы из проекта которые лежали в папке res/xml/ но как быть чтобы использовать файл из любой директории?
У XmlPullParser есть метод setInput (InputStream inputStream, String inputEncoding).
Открываете файл, получаете InputStream, передаете в качестве параметра. Второй параметр может быть null.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

mechanikos
Сообщения: 33
Зарегистрирован: 30 сен 2013, 12:14

Re: Динамическое создание интерфейса.

Сообщение mechanikos » 01 окт 2013, 16:05

KamiSempai писал(а):
mechanikos писал(а):я чего то не понимаю... а зачем в таком случае использовать XmlPullParser? разве layoutinflater не принимает сразу xml-файл?
Вы не поверите, но данном случае layoutinflater самостаятельно создает XmlParser из файла, id на который вы передаете в параметрах.
mechanikos писал(а):... и вопрос не по теме но я сейчас всегда использовал хмl-файлы из проекта которые лежали в папке res/xml/ но как быть чтобы использовать файл из любой директории?
У XmlPullParser есть метод setInput (InputStream inputStream, String inputEncoding).
Открываете файл, получаете InputStream, передаете в качестве параметра. Второй параметр может быть null.


вот большое спасибо) до вашей второй подсказки допер уже сам ночью но основная проблема вот в в чем: layoutinflater самостоятельно создает XmlParser из файла, id на который вы передаете в параметрах. Как мне получить id файла который у меня не зашит в ресурсы проекта а лежит допустим на флешке? разве все константы не генерятся сами в R.java на этапе компиляции? буду очень благодарен вам если вы покажете хоть какой нибудь пример( а то я пока без большого опыта часто бодаюсь с синтаксисом хотя в основном делаю правильно.

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Динамическое создание интерфейса.

Сообщение KamiSempai » 01 окт 2013, 16:18

Как-то так:

Код: Выделить всё

InputStream streem = new FileInputStream(path);
XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
parser.setInput(streem, null);
View view = getLayoutInflater().inflate(parser, null);
Где path - это путь к XML файлу.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

mechanikos
Сообщения: 33
Зарегистрирован: 30 сен 2013, 12:14

Re: Динамическое создание интерфейса.

Сообщение mechanikos » 01 окт 2013, 20:30

KamiSempai писал(а):Как-то так:

Код: Выделить всё

InputStream streem = new FileInputStream(path);
XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
parser.setInput(streem, null);
View view = getLayoutInflater().inflate(parser, null);
Где path - это путь к XML файлу.
сделал как вы посоветовали но к сожалению приложение вылетает при запуске. не могу понять что я делаю не так

Код: Выделить всё

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: Динамическое создание интерфейса.

Сообщение KamiSempai » 02 окт 2013, 00:04

Что в логах?
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

mechanikos
Сообщения: 33
Зарегистрирован: 30 сен 2013, 12:14

Re: Динамическое создание интерфейса.

Сообщение mechanikos » 02 окт 2013, 00:16

KamiSempai писал(а):Что в логах?
секунду сейчас добавлю вывод эксепшена в лог

mechanikos
Сообщения: 33
Зарегистрирован: 30 сен 2013, 12:14

Re: Динамическое создание интерфейса.

Сообщение mechanikos » 02 окт 2013, 00:23

KamiSempai писал(а):Что в логах?
очень много всего пишет( но вижу что то про InputStreamReader

upd.

буду очень благодарен все кто сможет объяснить в чем проблема тут... у меня к сожалению уже пол пятого утра и поэтому посплю перед парами чуток

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Динамическое создание интерфейса.

Сообщение KamiSempai » 02 окт 2013, 09:42

mechanikos писал(а):очень много всего пишет( но вижу что то про InputStreamReader
Ни о чем не говорит. Может быть все что угодно. Наиболее вероятное - это отсутствие разрешения на работу с файлами и ли не правильно указанный путь.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

mechanikos
Сообщения: 33
Зарегистрирован: 30 сен 2013, 12:14

Re: Динамическое создание интерфейса.

Сообщение mechanikos » 02 окт 2013, 19:10

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: Динамическое создание интерфейса.

Сообщение KamiSempai » 03 окт 2013, 12:11

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?
Хм... А я это пропустил. Действительно, так не получится. Во всяком случае, до этого пока даже не дошло иначе была бы ошибка InflateException.

Там говорится, что при сборке приложения XML файлы проходят предварительную обработку. Следовательно, если передать обработанный файл, должно сработать.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

mechanikos
Сообщения: 33
Зарегистрирован: 30 сен 2013, 12:14

Re: Динамическое создание интерфейса.

Сообщение mechanikos » 04 окт 2013, 14:06

KamiSempai писал(а):
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?
Хм... А я это пропустил. Действительно, так не получится. Во всяком случае, до этого пока даже не дошло иначе была бы ошибка InflateException.

Там говорится, что при сборке приложения XML файлы проходят предварительную обработку. Следовательно, если передать обработанный файл, должно сработать.
каким образом обработанный? и если все таки первоначальный план не работает то что делать теперь? в ручную парсить хмл и в соответсвии с тэгами пытаться создать гуй из кода?

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Динамическое создание интерфейса.

Сообщение KamiSempai » 04 окт 2013, 14:27

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

Остается только одна надежда. Скомпилировать APK с нужным XML и вытащить его из него. Делается это легко, так как, фактически APK представляет из себя обычный архив и распаковывается любым архиватором.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

mechanikos
Сообщения: 33
Зарегистрирован: 30 сен 2013, 12:14

Re: Динамическое создание интерфейса.

Сообщение mechanikos » 04 окт 2013, 15:38

KamiSempai писал(а):
mechanikos писал(а):каким образом обработанный? и если все таки первоначальный план не работает то что делать теперь? в ручную парсить хмл и в соответсвии с тэгами пытаться создать гуй из кода?
Вот этого точно делать не стоит.

Остается только одна надежда. Скомпилировать APK с нужным XML и вытащить его из него. Делается это легко, так как, фактически APK представляет из себя обычный архив и распаковывается любым архиватором.
по подробнее. то есть отправлять не сам xml а допустим пустой проект с xml файлом? или как то програмно можно создать апк с хмл-ом? и как его оттуда потом доставать? устанавливать apk или опять же его как то разархивировать программно? если устанавливать то доставать xml через гетресурс или так же просто указать путь? в обещм если вам не трудно опишите здесь или в личке пожалуйста примерно или подробно как поступить лучше и какие телодвижения для этого нужно совершить

Ответить