Страница 1 из 1

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

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

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

Добавлено: 30 сен 2013, 12:25
trew
Смотрели уроки 16, 17 и обсуждения этих уроков на форуме?

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

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

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

Добавлено: 30 сен 2013, 16:44
trew
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

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

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

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

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

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

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

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

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

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

Добавлено: 01 окт 2013, 16:05
mechanikos
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 на этапе компиляции? буду очень благодарен вам если вы покажете хоть какой нибудь пример( а то я пока без большого опыта часто бодаюсь с синтаксисом хотя в основном делаю правильно.

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

Добавлено: 01 окт 2013, 16:18
KamiSempai
Как-то так:

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

InputStream streem = new FileInputStream(path);
XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
parser.setInput(streem, null);
View view = getLayoutInflater().inflate(parser, null);
Где path - это путь к XML файлу.

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

Добавлено: 01 окт 2013, 20:30
mechanikos
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);
			}
		}
	};

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

Добавлено: 02 окт 2013, 00:04
KamiSempai
Что в логах?

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

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

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

Добавлено: 02 окт 2013, 00:23
mechanikos
KamiSempai писал(а):Что в логах?
очень много всего пишет( но вижу что то про InputStreamReader

upd.

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

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

Добавлено: 02 окт 2013, 09:42
KamiSempai
mechanikos писал(а):очень много всего пишет( но вижу что то про InputStreamReader
Ни о чем не говорит. Может быть все что угодно. Наиболее вероятное - это отсутствие разрешения на работу с файлами и ли не правильно указанный путь.

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

Добавлено: 02 окт 2013, 19:10
mechanikos
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?

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

Добавлено: 03 окт 2013, 12:11
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 файлы проходят предварительную обработку. Следовательно, если передать обработанный файл, должно сработать.

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

Добавлено: 04 окт 2013, 14:06
mechanikos
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 файлы проходят предварительную обработку. Следовательно, если передать обработанный файл, должно сработать.
каким образом обработанный? и если все таки первоначальный план не работает то что делать теперь? в ручную парсить хмл и в соответсвии с тэгами пытаться создать гуй из кода?

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

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

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

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

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

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