Intereting Posts
Как включить переднюю камеру в webview для Android Модуль Arduino + Bluetooth + Android Как реализовать Beluga или WhatsApp как систему обмена сообщениями в Android 2.1 Android: Выполнение кода только при первом запуске и каждом последующем обновлении Элементы действия из исходного фрагмента Viewpager не отображаются Деформирование изображения в android Ароматизаторы продуктов для Android Gradle Наложения фрагментов Android перекрываются Как установить фиксированное количество строк в android gridView? Android 4.4 дает ошибку ERR_CACHE_MISS в onReceivedError для WebView назад Формат файла Android NinePatch .png? Android – Чтение PNG-изображения без альфа-декодирования и декодирования ARGB_8888 Различия между Android, убивающей приложение, и пользователя, отскакивающего его от недавнего списка приложений Как получить доступ к внешнему хранилищу с кордовыми файлами / файловыми системными плагинами? Какова цель FrameLayout и в каком сценарии мы должны ее использовать?

Повернуть просмотр иерархии на 90 градусов

Я работаю над подклассом FrameLayout, который должен вращать всех своих детей на 90 градусов. Я делаю это, чтобы преодолеть ограниченное по ландшафту ограничение камеры, присутствующее в Android 2.1 и ниже, благодаря тому, что активность была в ландшафте, но поместив наложение этой камеры на эту овальную рамку, чтобы она выглядела так, как будто это был портрет ( это как Layar делает это ). Для этого я приспосабливаю код Джеффа Шарки, чтобы повернуть виды. Моя проблема в том, что я могу повернуть Framelayout, но я не могу изменить его размер в соответствии с новыми измерениями. Так что на моем g1, вместо просмотра 320×480 портрет над разрешением 480×320 в пейзаже, я получаю окно размером 320×320 посередине, показывающее мой портретный вид с отбитыми сторонами.

Вот мой код:

public class RotateLayout extends FrameLayout { private Matrix mForward = new Matrix(); private Matrix mReverse = new Matrix(); private float[] mTemp = new float[2]; public RotateLayout(Context context) { super(context); } public RotateLayout(Context context, AttributeSet attrs) { super(context, attrs); } /* (non-Javadoc) * @see android.widget.FrameLayout#onMeasure(int, int) */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //This didn't work: //super.onMeasure(heightMeasureSpec, widthMeasureSpec); } /* (non-Javadoc) * @see android.widget.FrameLayout#onSizeChanged(int, int, int, int) */ @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); } @Override protected void dispatchDraw(Canvas canvas) { canvas.rotate(270, getWidth()/2, getHeight()/2); //This code will stretch the canvas to accommodate the new screen size. This is not what I want. //float scaleX=(float)getHeight()/getWidth(); //float scaleY=(float)getWidth()/getHeight(); //canvas.scale(scaleX, scaleY, getWidth()/2, getHeight()/2); mForward = canvas.getMatrix(); mForward.invert(mReverse); canvas.save(); canvas.setMatrix(mForward); //This is the matrix we need to use for proper positioning of touch events super.dispatchDraw(canvas); canvas.restore(); } @Override public boolean dispatchTouchEvent(MotionEvent event) { final float[] temp = mTemp; temp[0] = event.getX(); temp[1] = event.getY(); mReverse.mapPoints(temp); event.setLocation(temp[0], temp[1]); return super.dispatchTouchEvent(event); } } 

Я попытался переопределить OnMeasure чтобы переключить размеры X и Y в представлении, но не смог заставить это работать. Любая помощь, которую вы можете предоставить, очень ценится.

Solutions Collecting From Web of "Повернуть просмотр иерархии на 90 градусов"

У меня была такая же проблема, и мне удалось ее решить. Вместо поворота каждого вида или макета вручную я использовал LayoutAnimationController.

Сначала поместите файл в / res / anim / called rotation.xml

 <?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:fromDegrees="0" android:toDegrees="-90" android:pivotX="50%" android:pivotY="50%" android:duration="0" android:fillAfter="true"> </rotate> 

Затем, в своей операции onCreate, сделайте

  @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.myscreen); Animation rotateAnim = AnimationUtils.loadAnimation(this, R.anim.rotation); LayoutAnimationController animController = new LayoutAnimationController(rotateAnim, 0); FrameLayout layout = (FrameLayout)findViewById(R.id.MyScreen_ContentLayout); layout.setLayoutAnimation(animController); } 

Если вы хотите повернуть элементы, расположенные над просмотром предварительного просмотра камеры (SurfaceHolder), просто поместите FrameLayout над SurfaceHolder, поместите все свои элементы в этот FrameLayout и вызовите макет «MyScreen_ContentLayout». Готово.

Надежда, которая помогла кому-то, заставила меня долгое время собраться вместе.

Используя API уровня 11 и более поздние версии, вы можете использовать метод setRotation(degreesFloat); Для изменения поворота представления программно, или вы можете использовать атрибут XML android:rotation="" чтобы изменить его в своем XML. Существуют также методы / атрибуты для изменения только значений X или Y вращения представления: Android Docs – View (setRotation) .

Итак, пока вы используете API уровня 11 или выше, вы должны иметь возможность применить поворот к узлу макета оболочки. Тем не менее, вам, вероятно, также придется изменить размеры макета верхнего уровня в соответствии с размерами, которые вы хотите после поворота. Т.е. если у вас есть портретный вид с размерами 800×1280, вам придется изменить их на 1280×800, чтобы он выстраивался в линию после поворота на пейзаж.

Используя эту библиотеку, вы можете повернуть всю иерархию представлений https://github.com/rongi/rotate-layout

Как это

Введите описание изображения здесь

Это то, что сработало для меня в целом.

 private void init() { setRotation(90f); } public YourViewOrViewGroup(final Context context) { super(context); init(); } ... (all the View/ViewGroup constructors) ... @Override protected void onLayout(final boolean changed, final int l, final int t, final int r, final int b) { super.onLayout(changed, l, t, r, b); final int width = getWidth(); final int height = getHeight(); final int offset = Math.abs(width - height) / 2; setTranslationX(-offset); setTranslationY(offset); } @Override protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { super.onMeasure(heightMeasureSpec, widthMeasureSpec); } 

То, что вы хотите сделать, это поменять ширину с высотой, а затем поместить смещения X & Y так, чтобы представление становилось полноэкранным после поворота.

Вышеупомянутая версия является «пейзажной». Для достижения инвертированного ландшафта применяйте только поворот на 270 градусов. Вы можете либо изменить код внутри фрагмента, либо применить поворот снаружи более общим способом, т. Е.

 final YourViewOrViewGroup layout = inflater.inflate(...); if (currentOrientation.isInverted()) { layout.setRotation(layout.getRotation + 180f); } 

Таким образом, вы можете встроить повернутую View / ViewGroup в определение xml и раздуть версии «порт» и «земля», в то время как ориентация экрана меняется, но это кажется из этой темы.

Изменить: на самом деле гораздо лучше отложить настройку смещения до тех пор, пока не будет завершен хотя бы один макет. Это связано с тем, что в моем случае после первого onMeasure () будет отображаться представление (до того, как были установлены смещения). В конце концов, это может быть воспринято как сбой, потому что представление / макет вначале не будут нарисованы в финальных границах. (Обновленный фрагмент)

Я думаю, вы забыли одну строку в своем onMeasure.

 @Override protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(heightMeasureSpec, widthMeasureSpec); setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth()); } 

Взято из кода для вертикальной кнопки поиска здесь: Как я могу получить рабочий вертикальный SeekBar в Android?

Вам может понадобиться играть с getMeasuredHeight (), чтобы сделать правильный размер вашего экрана.

Попробуйте отключить отсечение детей в корне вашего вида: вызовите setClipChildren(false) на родителя вашего RotateLayout и в методе onMeasure вашего RotateLayout поместите эти строки:

 super.onMeasure(heightMeasureSpec, widthMeasureSpec); setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth()); 

У меня в основном такая же проблема, как и вы, и я до сих пор не тестировал свое решение – я сделаю это завтра и скажу, правильно ли он работает.