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

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

Добавлено: 15 мар 2013, 19:08
neoksi
При выполнении долгих операций, к примеру при прохождении авторизации пользователем, зачастую для отображения хода операции мы отображаем 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:

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

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

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

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

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

Добавлено: 15 мар 2013, 22:17
Foenix
ух ты, мне надо! Спасибо!

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

Добавлено: 16 мар 2013, 15:11
rezak90
а не проще запретить перерисовку при поворотах?

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

Добавлено: 16 мар 2013, 15:25
neoksi
rezak90 писал(а):а не проще запретить перерисовку при поворотах?
И перерисовывать вручную?

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

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

Добавлено: 16 мар 2013, 16:03
rezak90
я имел в виду запретить перерисовку активити в манифесте и в фрагменте

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

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

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

Добавлено: 28 апр 2013, 23:30
neoksi
Столкнулся с проблемой на планшетах, код пришлось менять, так как на них ориентация считается иначе.
[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]

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

Добавлено: 29 апр 2013, 02:27
rezak90
пересмотрел все сообщения в данной теме, сразу задался вопросом: в чём проблема? диалог показали и при повороте он никуда не денется он уже существует и сам перерисуется как ему нужно, или я что то упустил?

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

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

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

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

Добавлено: 24 май 2021, 08:15
shephord
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. :)

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

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