Урок 110. Android 3. Fragments. DialogFragment - диалог

Обсуждение уроков
Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

Re: Урок 110. Android 3. Fragments. DialogFragment - диалог

Сообщение rezak90 » 10 дек 2013, 11:50

Foenix писал(а):для этого когда-то было "контекстное меню", но теперь оно deprecated, используй
http://developer.android.com/design/pat ... contextual
вижу кто то вебинар смотрел ;)
R.id.team
Политика на форуме запрещена

Аватара пользователя
Foenix
Сообщения: 4200
Зарегистрирован: 20 окт 2012, 12:01

Re: Урок 110. Android 3. Fragments. DialogFragment - диалог

Сообщение Foenix » 10 дек 2013, 19:39

а кто-то пропустил!
Хотя толку? народ уже контекстное меню за свое личное изобретение считает. Это что значит? Что даже винда не установлена на компе?
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

парень
Сообщения: 223
Зарегистрирован: 30 мар 2013, 22:52

Re: Урок 110. Android 3. Fragments. DialogFragment - диалог

Сообщение парень » 12 дек 2013, 07:24

Foenix писал(а):для этого когда-то было "контекстное меню", но теперь оно deprecated, используй
http://developer.android.com/design/pat ... contextual
Спасибо. Разобрался с ActionBar, с ActionBarSherlock, с ActionMode,с ActionBarSherlock+ActionMode. все сделал. не понравилось :)

нужно контекстное меню прямо на нажатом эллементе со стрелочкой :) чтото вроде PopUpMenu

Решение такое:
Обработчик на списке:

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

 lvSimple.setOnItemLongClickListener(new OnItemLongClickListener() {
			public  boolean onItemLongClick(AdapterView<?> parent, final View view,
					int position, long id) {
				
			    int[] location = new int[2];
                view.getLocationOnScreen(location);

                // в backView сохраняем текущий фон итема (у меня он у многих итемов разный.
                backView = view.findViewById(R.id.list_item_lay).getBackground();
               // устанавливаем фон затемнения (нажатия)
                view.findViewById(R.id.list_item_lay).setBackgroundResource(R.drawable.item_selected_pressed_mystyle);
                 
                Point point = new Point();
                point.x = location[0];
                point.y = (int) (location[1]+view.getHeight()-40);
                //если не шерлок то здесь как то подругому надо прописать, например getActivity()
                showPopup(getSherlockActivity(), point);
     
				 return true;
			}
             });
сама процедура(метод) или как там оно называется

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

private void showPopup(Activity context, Point p) {

		LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// R.layout.popup_menu - это мой кастомный слой с тремя кнопочками графическими 
	   View layout = layoutInflater.inflate(R.layout.popup_menu, null);

	   PopupWindow PopUp = new PopupWindow(context);
	   PopUp.setContentView(layout);
	   PopUp.setWidth(LinearLayout.LayoutParams.WRAP_CONTENT);  
	   PopUp.setHeight(LinearLayout.LayoutParams.WRAP_CONTENT);
	   PopUp.setFocusable(true);    

	   PopUp.setBackgroundDrawable(new BitmapDrawable());
           PopUp.showAtLocation(layout, Gravity.NO_GRAVITY, p.x, p.y);
	   //Немножко анимации
           Animation anim = AnimationUtils.loadAnimation(getSherlockActivity(), R.anim.my_alpha); 
	   layout.startAnimation(anim);	  
	   // ловим уничтожение чтобы заменить слой на тот который был.
	   PopUp.setOnDismissListener(new OnDismissListener(){

			@Override
			public void onDismiss() {
				Log.d("asd","уничтожился СУКА !");
				viewItemList.findViewById(R.id.list_item_lay).setBackgroundDrawable(backView);
			}
	    	
	    	
	    });
	    
	}
велосипед? ;)
Мой первенец: MyMoney. Менеджер расходов

Бьем рекорды русских топов :)

Могу ответить на любые вопросы по маркетингу и развитию.

Razor
Сообщения: 10
Зарегистрирован: 13 окт 2014, 13:58

Re: Урок 110. Android 3. Fragments. DialogFragment - диалог

Сообщение Razor » 18 ноя 2014, 16:29

Есть еще один вариант вызова диалога. Это метод show, но на вход он уже принимает не FragmentManager, а FragmentTransaction. В этом случае система также сама вызовет commit внутри show, но мы можем предварительно поместить в созданную нами транзакцию какие-либо еще операции или отправить ее в BackStack.
Можно ли после закрытия диалога вернуть его кнопкой "Назад"?

Код из урока, вызов второго диалога методом show с FragmentTransaction, добавленной в BackStack:

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

import android.app.Activity;
import android.app.DialogFragment;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends Activity {

	DialogFragment dlg1;
	DialogFragment dlg2;
	FragmentTransaction ft;
	int bsID;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		dlg1 = new Dialog1();
		dlg2 = new Dialog2();
	}

	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btnDlg1:
			dlg1.setCancelable(false);
			dlg1.show(getFragmentManager(), "dlg1");
			break;
		case R.id.btnDlg2:
			ft = getFragmentManager().beginTransaction();
			ft.addToBackStack(null);
			dlg1.setCancelable(false);
			bsID = dlg2.show(ft, "dlg2");
			Toast.makeText(this, "bsID = " + bsID, Toast.LENGTH_SHORT).show();
			break;
		default:
			break;
		}

	}
}
Открываю приложение, вызываю диалог, закрываю, жму "Назад" - приложение закрывается.

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

Re: Урок 110. Android 3. Fragments. DialogFragment - диалог

Сообщение KamiSempai » 18 ноя 2014, 17:47

Все правильно работает. Закрытие диалога равносильно нажатию кнопки назад. Вот если вы сразу откроете 2 диалога первый поместится в стек и вернется после нажатия кнопки назад.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

igrok-vip
Сообщения: 56
Зарегистрирован: 29 апр 2013, 11:53

Re: Урок 110. Android 3. Fragments. DialogFragment - диалог

Сообщение igrok-vip » 24 фев 2015, 00:08

Я использую DialogFragment для подтверждения удаления записи из листвью. Т.е. в диалоге есть 2 кнопки "Да" и "Нет". И если была нажата "Да", то в основном активити с листвью нужно удалить запись. Подскажите как это можно реализовать?
Т.е. в основном активити я нажимаю "Удалить" - открывается диалог, где я нажимаю "Да", после чего диалог закрывается и основное активити должно как-то понять, что сейчас нужно удалить запись. Или не нужно, если была нажата "Нет".
Есть ли какой-то механизм ожидания сообщения от диалога или что-то типа того? Или в диалог нужно отправлять id записи и внутри диалога подключаться к базе по новой? Но тогда после закрытия диалога всё-равно в какой-то момент нужно обновить список, чтобы удалилась запись. В какой?

Аватара пользователя
Foenix
Сообщения: 4200
Зарегистрирован: 20 окт 2012, 12:01

Re: Урок 110. Android 3. Fragments. DialogFragment - диалог

Сообщение Foenix » 24 фев 2015, 00:35

можно из диалога запись удалить, разница небольшая. Нажата окей - удаляем. Можно организовать колбек - вызов метода при закрытии диалога в активити, которая реализует нужный интерфейс. Этот механизм тоже в уроках описан. Посмотри 106 после слов "Обработка в Activity события из фрагмента "
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

igrok-vip
Сообщения: 56
Зарегистрирован: 29 апр 2013, 11:53

Re: Урок 110. Android 3. Fragments. DialogFragment - диалог

Сообщение igrok-vip » 24 фев 2015, 12:15

Глянул 106й урок. Сложновато для простого подтверждения наверно.
Пока пытаюсь сделать первым способом, но есть тоже пара проблем:
Почему-то не передаётся параметр id в диалог
MainActivity.java

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

Bundle bnd = new Bundle();
bnd.putInt("id", (int) acmi.id);
dlg1.setArguments(bnd);
dlg1.show(getFragmentManager(), "dlg1");
Dialog1.java

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

int id = 999;
getArguments().getInt("id", -1);
Log.d("Dialog", "id = "+id);
Результат - 999.

И ещё сразу. Как после удаления записи в бд из диалога обновить listview в activity?
Там для этого используется SimpleCursorAdapter и getSupportLoaderManager().getLoader(0).forceLoad();

Аватара пользователя
Foenix
Сообщения: 4200
Зарегистрирован: 20 окт 2012, 12:01

Re: Урок 110. Android 3. Fragments. DialogFragment - диалог

Сообщение Foenix » 24 фев 2015, 12:21

Неправильно в диалоге ты делаешь.. Почитай уроки.. Там надо инстанс создавать..
Чтоб обновить данные в листвью вызвать notifydatasetchanged
Либо использовать лоадеры и контент провайдер
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

igrok-vip
Сообщения: 56
Зарегистрирован: 29 апр 2013, 11:53

Re: Урок 110. Android 3. Fragments. DialogFragment - диалог

Сообщение igrok-vip » 24 фев 2015, 13:11

Передать параметр в диалог получилось. Я же id то никуда не помещал)). Запись удаляется. Но всё-равно не пойму как обновить ListView.
Как вызвать этот notifydatasetchanged?
Как из диалога получить доступ к адаптеру и вызвать для него notifydatasetchanged?
Или изучать лоадеры и контент провайдеры?)

Аватара пользователя
Foenix
Сообщения: 4200
Зарегистрирован: 20 окт 2012, 12:01

Re: Урок 110. Android 3. Fragments. DialogFragment - диалог

Сообщение Foenix » 24 фев 2015, 13:20

Нет из диалога доступа к адаптеру.
Изучай если тебе всерьёз и надолго.
Если просто побыстрее то изучай что я описывала выше - колбеки, которые ты назвал сложным подходом. Однако эта штука используется тоже повсеместно и везде пригодится.
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

igrok-vip
Сообщения: 56
Зарегистрирован: 29 апр 2013, 11:53

Re: Урок 110. Android 3. Fragments. DialogFragment - диалог

Сообщение igrok-vip » 24 фев 2015, 13:24

Спасибо. Тогда буду изучать колбеки)

igrok-vip
Сообщения: 56
Зарегистрирован: 29 апр 2013, 11:53

Re: Урок 110. Android 3. Fragments. DialogFragment - диалог

Сообщение igrok-vip » 24 фев 2015, 14:37

Блин опять проблема. Я сейчас сделал листвью с использованием SimpleCursorAdapter. Для него нужно чтобы активити реализовывало интерфейс LoaderCallbacks<Cursor>. Для того, чтобы вызвать метод в активити нужно чтобы оно реализовывало интерфейс из диалога. Но когда я пытаюсь реализовать оба этих интерфейса

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

public class MainActivity extends FragmentActivity  implements LoaderCallbacks<Cursor> implements Dialog_del_pc.onSomeEventListener{
...}
AndroidStudio выделяет всё красным и выдаёт ошибку "'class' or 'interface' expected"
В андроид нельзя реализовывать несколько интерфейсов сразу или я опять что-то не так делаю?)

Аватара пользователя
Foenix
Сообщения: 4200
Зарегистрирован: 20 окт 2012, 12:01

Re: Урок 110. Android 3. Fragments. DialogFragment - диалог

Сообщение Foenix » 24 фев 2015, 15:10

два раза слово implements писать не надо, через запятую перечисляй
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

igrok-vip
Сообщения: 56
Зарегистрирован: 29 апр 2013, 11:53

Re: Урок 110. Android 3. Fragments. DialogFragment - диалог

Сообщение igrok-vip » 24 фев 2015, 15:15

Спасибо ещё раз. Не сталкивался пока с интерфейсами)

SkN[i]lPl[e][r]
Сообщения: 1
Зарегистрирован: 07 июн 2015, 12:08

Re: Урок 110. Android 3. Fragments. DialogFragment - диалог

Сообщение SkN[i]lPl[e][r] » 07 июн 2015, 12:17

Здравствуйте я использовал примеры из урока и у меня выдало ошибки:
dlg1 = new Dialog1(); - здесь говорит что Cannot resolve constructor "Dialog1()"
dlg1.show(getFragmentManager(), "dlg1"); - здесь говорит что Cannot resolve method "getFragmentManager()"
В проекте у меня minSdkVersion 11; targetSdkVersion 21.
Диалоги пытаюсь вызвать из класса конструктора.
Второй тип диалога dlg2 = new Dialog2(); - все нормально, здесь ничего не подчеркнул.
Но в dlg2.show(getFragmentManager(), "dlg2"); - та же ошибка что и в первом случае

Light310
Сообщения: 6
Зарегистрирован: 13 июн 2015, 00:59

Re: Урок 110. Android 3. Fragments. DialogFragment - диалог

Сообщение Light310 » 13 июн 2015, 01:16

Здравствуйте, товарищи.

Работая с DialogFragment столкнулся с ошибкой, которая заставила меня усомниться в понимании базовых механизмов работы с фрагментами, посему и хочу задать здесь свой вопрос.
Строю простенькое приложение, в его основе Activity, которая сама толком ничего не делает, а добавляет и заменяет на себе фрагменты. Итак, сразу после запуска приложения добавляется фрагмент, зовут его Initial. После нажатия на одну из кнопок, вызывается кастомный DialogFragment, цель которого - получить текст в EditText и обработать нажатие на кнопку.

У нужной мне кнопки стоит в XML'ке onClick:
android:id="@+id/btnDlgAdd"
...
android:onClick="dlgAddPlayer"

Далее, в java-классе для этого DialogFragment есть обработка этого метода:
public void dlgAddPlayer(View v) { ... }

Однако по её нажатию получаю ошибку:
java.lang.IllegalStateException: Could not find a method dlgAddPlayer(View) in the activity class android.view.ContextThemeWrapper for onClick handler on view class android.widget.Button with id 'btnDlgAdd'

Что лично меня напрягает, так это строка о том, что метод не найден "in the activity class". Быть может, я не туда ввожу обработчик нажатия? Куда передаётся этот запрос onClick? (для верности я добавил его и в родительский фрагмент и в саму activity, но не помогло).

P.S.: посмотрел пачку аналогичных проблем на stackoverflow, однако решения не нашёл. Буду благодарен за советы или наводки на что почитать.
P.P.S.: насколько оправдан подход избегания множества активностей? Лично мне показалось логичным работать не со множеством активностей, а с одной активностью и множеством фрагментов, особенно при условии будущей адаптации под планшеты. Но пока это лишь теория, хотелось бы услышать мнение практиков.

Аватара пользователя
doter.ua
Сообщения: 1106
Зарегистрирован: 23 ноя 2013, 16:08
Откуда: Ukraine

Re: Урок 110. Android 3. Fragments. DialogFragment - диалог

Сообщение doter.ua » 13 июн 2015, 02:05

Light310 писал(а):Здравствуйте, товарищи.

Работая с DialogFragment столкнулся с ошибкой, которая заставила меня усомниться в понимании базовых механизмов работы с фрагментами, посему и хочу задать здесь свой вопрос.
Строю простенькое приложение, в его основе Activity, которая сама толком ничего не делает, а добавляет и заменяет на себе фрагменты. Итак, сразу после запуска приложения добавляется фрагмент, зовут его Initial. После нажатия на одну из кнопок, вызывается кастомный DialogFragment, цель которого - получить текст в EditText и обработать нажатие на кнопку.

У нужной мне кнопки стоит в XML'ке onClick:
android:id="@+id/btnDlgAdd"
...
android:onClick="dlgAddPlayer"

Далее, в java-классе для этого DialogFragment есть обработка этого метода:
public void dlgAddPlayer(View v) { ... }

Однако по её нажатию получаю ошибку:
java.lang.IllegalStateException: Could not find a method dlgAddPlayer(View) in the activity class android.view.ContextThemeWrapper for onClick handler on view class android.widget.Button with id 'btnDlgAdd'

Что лично меня напрягает, так это строка о том, что метод не найден "in the activity class". Быть может, я не туда ввожу обработчик нажатия? Куда передаётся этот запрос onClick? (для верности я добавил его и в родительский фрагмент и в саму activity, но не помогло).

P.S.: посмотрел пачку аналогичных проблем на stackoverflow, однако решения не нашёл. Буду благодарен за советы или наводки на что почитать.
P.P.S.: насколько оправдан подход избегания множества активностей? Лично мне показалось логичным работать не со множеством активностей, а с одной активностью и множеством фрагментов, особенно при условии будущей адаптации под планшеты. Но пока это лишь теория, хотелось бы услышать мнение практиков.

Найди кнопку в фрагменте и вручную накинь обработчик
Button btn = (Button) mainContainer.findView...
btn .setOnClick...
Семь раз отмерь - поставь студию.
Эклипс не студия, ошибка вылетит - не исправишь.
Скажи мне кто твой друг, и оба поставили студию.
Студия - свет, а эклипс - тьма.

Light310
Сообщения: 6
Зарегистрирован: 13 июн 2015, 00:59

Re: Урок 110. Android 3. Fragments. DialogFragment - диалог

Сообщение Light310 » 13 июн 2015, 13:16

doter.ua писал(а): Найди кнопку в фрагменте и вручную накинь обработчик
Button btn = (Button) mainContainer.findView...
btn .setOnClick...
Помогло, большое спасибо!

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

kunstkamera
Сообщения: 5
Зарегистрирован: 17 июл 2015, 14:17

Re: Урок 110. Android 3. Fragments. DialogFragment - диалог

Сообщение kunstkamera » 02 авг 2015, 02:01

Здравствуйте. C помощью someEventListener я из фрагмента передаю строку в DialogFragment, который меняет содержимое EditText на мою строку.

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

Bundle bundle = getArguments();
String s = bundle.getString("key");
((EditText)v.findViewById(R.id.eDevice)).setText(s);
При следующей передаче строки диалог остается прежним, значение EditText не меняется, т.к. диалог не удаляется.
Как при каждом вызове диалога обновлять его \ создавать его заново?
--
PS.Желаемый мною эффект происходит при повороте экрана.

Ответить