ProgressDialog блокирующий поворот экрана

Ответить
Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

ProgressDialog блокирующий поворот экрана

Сообщение neoksi » 15 мар 2013, 19:08

При выполнении долгих операций, к примеру при прохождении авторизации пользователем, зачастую для отображения хода операции мы отображаем ProgressDialog. Но в это время пользователь может вертеть устройство в разных направлениях, что вызовет смену ориентации экрана и вызовет процедуру пересоздания Активити, чтоб от этого застраховаться, я создал следующий вспомогательный класс:

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

public class elProgressDialogOrientationBlock extends ProgressDialog {
	
	/*
	 * Прогресс диалог запрещающий поворот экрана при его работе
	 */
	
	private Context mContext;
	private int mOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR;

	public elProgressDialogOrientationBlock(Context context) {
	    super(context);
	    mContext = context;
	}

	public elProgressDialogOrientationBlock(Context context, int theme) {
	    super(context, theme);
	    mContext = context;
	}

	@Override
	public void show() {
		// Запоминаем ориентацию экрана
		mOrientation = ((Activity) mContext).getRequestedOrientation();
	    // Блокируем ориентацию экрана на время работы диалога.
	    switch (((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation()) {
	        case Surface.ROTATION_90: 
	        	((Activity) mContext).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 
	            break;
	        case Surface.ROTATION_180: 
	        	((Activity) mContext).setRequestedOrientation(9/* reversePortait */); 
	            break;          
	        case Surface.ROTATION_270: 
	        	((Activity) mContext).setRequestedOrientation(8/* reverseLandscape */); 
	            break;
	        default : 
	        	((Activity) mContext).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
	    }
	    	
	    super.show();
	}
	

	@Override
	public void dismiss() {
	    super.dismiss();
	    // Восстанавливаем ориентацию экрана
	    ((Activity) mContext).setRequestedOrientation(mOrientation);
	    //((Activity) mContext).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
	}
	

}

Выкладываю тут, возможно кому ещё пригодится. :roll:
Последний раз редактировалось neoksi 15 мар 2013, 21:37, всего редактировалось 1 раз.

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

Re: ProgressDialog блокирующий поворот экрана

Сообщение KamiSempai » 15 мар 2013, 21:23

Меня одна вещь беспокоит. Что если до показа диалога ориентация была не SCREEN_ORIENTATION_SENSOR?
Может стоит запоминать текущую ориентацию перед блокировкой, а потом восстанавливать ее?
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: ProgressDialog блокирующий поворот экрана

Сообщение neoksi » 15 мар 2013, 21:38

KamiSempai писал(а):Меня одна вещь беспокоит. Что если до показа диалога ориентация была не SCREEN_ORIENTATION_SENSOR?
Может стоит запоминать текущую ориентацию перед блокировкой, а потом восстанавливать ее?
Хорошее замечание :) , я даже как-то не подумал об этом, дополнил код выше.

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

Re: ProgressDialog блокирующий поворот экрана

Сообщение Foenix » 15 мар 2013, 22:17

ух ты, мне надо! Спасибо!
R.id.team

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

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

Re: ProgressDialog блокирующий поворот экрана

Сообщение rezak90 » 16 мар 2013, 15:11

а не проще запретить перерисовку при поворотах?
R.id.team
Политика на форуме запрещена

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: ProgressDialog блокирующий поворот экрана

Сообщение neoksi » 16 мар 2013, 15:25

rezak90 писал(а):а не проще запретить перерисовку при поворотах?
И перерисовывать вручную?

Вообще смысл этого класса запретить перерисовку только на момент работы ProgressDialog, чтоб избежать возможных ошибок при перерисовке. А после выполнения долгой операции, приложение работает как и работало.

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

Re: ProgressDialog блокирующий поворот экрана

Сообщение rezak90 » 16 мар 2013, 16:03

я имел в виду запретить перерисовку активити в манифесте и в фрагменте
R.id.team
Политика на форуме запрещена

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: ProgressDialog блокирующий поворот экрана

Сообщение neoksi » 16 мар 2013, 16:50

rezak90 писал(а):я имел в виду запретить перерисовку активити в манифесте и в фрагменте
Это тоже вариант, но он ущемляет юзабильность приложения. К примеру я обычно использую приложения на смартфонах в портретном режиме, но когда мне необходимо ввести текст, то я переворачиваю телефон в альбомный режим, так как там у клавиатуры большие кнопки. Если запретить в переворот приложения, то мне станет неудобно им пользоваться, в результате я просто найду другое приложение с аналогичным функционалом. :)

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: ProgressDialog блокирующий поворот экрана

Сообщение neoksi » 28 апр 2013, 23:30

Столкнулся с проблемой на планшетах, код пришлось менять, так как на них ориентация считается иначе.
[syntax=java]public class elProgressDialogOrientationBlock extends ProgressDialog {


private Context mContext;
private int mOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR;

public elProgressDialogOrientationBlock(Context context) {
super(context);
mContext = context;
}

public elProgressDialogOrientationBlock(Context context, int theme) {
super(context, theme);
mContext = context;
}

@Override
public void show() {
// Запоминаем ориентацию экрана
mOrientation = ((Activity) mContext).getRequestedOrientation();
// Блокируем ориентацию экрана на время работы диалога.
/*
switch (((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation()) {
case Surface.ROTATION_0:
((Activity) mContext).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
break;
case Surface.ROTATION_90:
((Activity) mContext).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
break;
case Surface.ROTATION_180:
((Activity) mContext).setRequestedOrientation(9);// reversePortait
break;
case Surface.ROTATION_270:
((Activity) mContext).setRequestedOrientation(8);// reverseLandscape
break;
default :
((Activity) mContext).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
*/

((Activity) mContext).setRequestedOrientation(getCurentOrientation());

super.show();
}

@SuppressWarnings("deprecation")
private int getCurentOrientation() {
Display d = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

final Point point = new Point();
try {
d.getSize(point);
} catch (java.lang.NoSuchMethodError ignore) { // Older device
point.x = d.getWidth();
point.y = d.getHeight();
}

boolean isWide = point.x >= point.y;

switch (d.getRotation()) {
case Surface.ROTATION_0:
return isWide ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
: ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
case Surface.ROTATION_90:
return isWide ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
: 9;
case Surface.ROTATION_180:
return isWide ? 8
: 9;
case Surface.ROTATION_270:
return isWide ? 8
: ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
}
return -1;
}


@Override
public void dismiss() {
super.dismiss();
// Восстанавливаем ориентацию экрана
try{
((Activity) mContext).setRequestedOrientation(mOrientation);
}catch (Exception e) {
// Ничего не делаем.
}
}


}[/syntax]

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

Re: ProgressDialog блокирующий поворот экрана

Сообщение rezak90 » 29 апр 2013, 02:27

пересмотрел все сообщения в данной теме, сразу задался вопросом: в чём проблема? диалог показали и при повороте он никуда не денется он уже существует и сам перерисуется как ему нужно, или я что то упустил?
R.id.team
Политика на форуме запрещена

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: ProgressDialog блокирующий поворот экрана

Сообщение neoksi » 29 апр 2013, 11:08

rezak90 писал(а):пересмотрел все сообщения в данной теме, сразу задался вопросом: в чём проблема? диалог показали и при повороте он никуда не денется он уже существует и сам перерисуется как ему нужно, или я что то упустил?
Это сам диалог, а AsyncTask который к нему привязан и который запускает пользователь, а не программа? =)

Я этот диалог использую в одном случае, при логине пользователя в программу.

shephord
Сообщения: 4
Зарегистрирован: 24 май 2021, 08:10

Re: ProgressDialog блокирующий поворот экрана

Сообщение shephord » 24 май 2021, 08:15

neoksi писал(а):
28 апр 2013, 23:30
Столкнулся с проблемой на планшетах, код пришлось менять, так как на них ориентация считается иначе.
[syntax=java]public class elProgressDialogOrientationBlock extends ProgressDialog {


private Context mContext;
private int mOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR;

public elProgressDialogOrientationBlock(Context context) {
super(context);
mContext = context;
}

public elProgressDialogOrientationBlock(Context context, int theme) {
super(context, theme);
mContext = context;
}

@Override
public void show() {
// Запоминаем ориентацию экрана
mOrientation = ((Activity) mContext).getRequestedOrientation();
// Блокируем ориентацию экрана на время работы диалога.
/*
switch (((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation()) {
case Surface.ROTATION_0:
((Activity) mContext).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
break;
case Surface.ROTATION_90:
((Activity) mContext).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
break;
case Surface.ROTATION_180:
((Activity) mContext).setRequestedOrientation(9);// reversePortait
break;
case Surface.ROTATION_270:
((Activity) mContext).setRequestedOrientation(8);// reverseLandscape cps
break;
default :
((Activity) mContext).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
*/

((Activity) mContext).setRequestedOrientation(getCurentOrientation());

super.show();
}

@SuppressWarnings("deprecation")
private int getCurentOrientation() {
Display d = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

final Point point = new Point();
try {
d.getSize(point);
} catch (java.lang.NoSuchMethodError ignore) { // Older device
point.x = d.getWidth();
point.y = d.getHeight();
}

boolean isWide = point.x >= point.y;

switch (d.getRotation()) {
case Surface.ROTATION_0:
return isWide ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
: ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
case Surface.ROTATION_90:
return isWide ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
: 9;
case Surface.ROTATION_180:
return isWide ? 8
: 9;
case Surface.ROTATION_270:
return isWide ? 8
: ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
}
return -1;
}


@Override
public void dismiss() {
super.dismiss();
// Восстанавливаем ориентацию экрана
try{
((Activity) mContext).setRequestedOrientation(mOrientation);
}catch (Exception e) {
// Ничего не делаем.
}
}


}[/syntax]
Hey, I checked personaly
It's working for me. :)

rakeshpatel
Сообщения: 4
Зарегистрирован: 24 май 2021, 08:25
Контактная информация:

Re: ProgressDialog блокирующий поворот экрана

Сообщение rakeshpatel » 19 окт 2021, 13:26

KamiSempai писал(а):
15 мар 2013, 21:23
Меня одна вещь беспокоит. Что если до показа ometv cps test диалога ориентация была не SCREEN_ORIENTATION_SENSOR?
Может стоит запоминать текущую ориентацию перед блокировкой, а потом восстанавливать ее?
thank you!

Ответить