【问题标题】:Android: Rotate only overlay Buttons on camera previewAndroid:仅在相机预览上旋转叠加按钮
【发布时间】:2013-05-24 10:52:16
【问题描述】:

我有一个使用 LinearLayout 作为主布局的 Android 应用程序,其中 SurfaceView 由相机预览填充。 在此,我用三个按钮和一个自定义 TextView 为另一个 LinearLayout 充气。我希望相机预览始终保持横向,并且覆盖布局会根据设备方向而变化。

我尝试在活动清单中设置android:screenOrientation="landscape",但随后(当然)膨胀的布局也始终保持固定,而没有设置android:screenOrientation 属性,相机预览也旋转,减慢了应用程序并显示奇怪预览的形式因素。这里是布局的相关代码:

private void setupLayout()
{
    setContentView(R.layout.main);
    getWindow().setFormat(PixelFormat.UNKNOWN);

    // Release camera if owned by someone else
    if (camera != null)
        releaseCamera();

    surfaceView = (SurfaceView) findViewById(R.id.camerapreview);
    surfaceHolder = surfaceView.getHolder();
    surfaceHolder.addCallback(this);
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    controlInflater = LayoutInflater.from(getBaseContext());
    View viewControl = controlInflater.inflate(R.layout.control, null);
    LayoutParams layoutParamsControl = new LayoutParams(
            LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
    this.addContentView(viewControl, layoutParamsControl);


    buttonGetCollectingData = (Button) findViewById(R.id.getcolldata);
    buttonGetCollectingData.setOnClickListener(new Button.OnClickListener()
    {
        public void onClick(View arg0)
        {
            ...
        }
    });

    btnBackHome = (Button) findViewById(R.id.btnBackHome);
    btnBackHome.setOnClickListener(new Button.OnClickListener()
    {
        public void onClick(View arg0)
        {
            ...
        }
    });

    autoFitTextViewMainMsg = (AutoFitTextView) findViewById(R.id.autoFitTextViewMainMsg);

    buttonTakePicture.setOnClickListener(new Button.OnClickListener()
    {

        public void onClick(View arg0)
        {
            ...
        }
    });
}

任何关于如何实现这一点的想法将不胜感激!

【问题讨论】:

  • 我的应用程序中也有这样的问题。这个答案对我帮助很大:stackoverflow.com/a/5183690/1552622
  • @makovkastar 我试过你建议的代码,但似乎这不是我要找的......
  • 此代码不会在轮换期间重新创建活动,并且仅轮换叠加项目。在这种情况下,只有图标会旋转,但您可以旋转所有需要的东西。还是不是你要求的?
  • @makovkastar 我已经看到我可以获取方向,但是这个示例有助于更改单个组件的旋转(如您所写),例如基本的 android Camera 应用程序。实际上,我希望 main.xml 始终处于横向模式,而 control.xml 布局遵循设备方向,以便按钮始终放置在与设备方向无关的相同位置(例如 buttonTakePicture 始终在底部,btnBackHome 总是在右上角,...)

标签: android camera android-orientation


【解决方案1】:

您可以使用自定义方向事件侦听器来获取方向并根据需要设置您的 UI。

首先,创建一个类CustomOrientationEventListener

public abstract class CustomOrientationEventListener  extends OrientationEventListener {


private static final String TAG = "CustomOrientationEvent";
private int prevOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
private Context context;
private final int ROTATION_O    = 1;
private final int ROTATION_90   = 2;
private final int ROTATION_180  = 3;
private final int ROTATION_270  = 4;
private int rotation = 0;

public CustomOrientationEventListener(Context context) {
    super(context);
    this.context = context;
}

@Override
public void onOrientationChanged(int orientation) {

    if (android.provider.Settings.System.getInt(context.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 0) == 0) // 0 = Auto Rotate Disabled
        return;
    int currentOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
    if (orientation >= 340 || orientation < 20 && rotation != ROTATION_O) {
        currentOrientation = Surface.ROTATION_0;
        rotation = ROTATION_O;

    } else if (orientation >= 70 && orientation < 110 && rotation != ROTATION_90) {
        currentOrientation = Surface.ROTATION_90;
        rotation = ROTATION_90;

    } else if (orientation >= 160 && orientation < 200 && rotation != ROTATION_180) {
        currentOrientation = Surface.ROTATION_180;
        rotation = ROTATION_180;

    } else if (orientation >= 250 && orientation < 290 && rotation != ROTATION_270) {
        currentOrientation = Surface.ROTATION_270;
        rotation = ROTATION_270;
    }

    if (prevOrientation != currentOrientation && orientation != OrientationEventListener.ORIENTATION_UNKNOWN) {
            prevOrientation = currentOrientation;
            if (currentOrientation != OrientationEventListener.ORIENTATION_UNKNOWN) {
                onSimpleOrientationChanged(rotation);
        }
    }
}

public abstract void onSimpleOrientationChanged(int orientation);


}

然后将下面的行添加到您的活动标签下的 Android 清单中

  android:configChanges="orientation|keyboardHidden|screenSize"

确保您不要在该活动的清单中添加 android:screenOrientation 属性。

然后在您的相机活动的 onCreate 中使用 CustomOrientationEventListener

public class YourActivity extends AppCompatActivity {

  private CustomOrientationEventListener customOrientationEventListener;

  final int ROTATION_O    = 1;
  final int ROTATION_90   = 2;
  final int ROTATION_180  = 3;
  final int ROTATION_270  = 4;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

       .....

      customOrientationEventListener = new 
 CustomOrientationEventListener(getBaseContext()) {
          @Override
          public void onSimpleOrientationChanged(int orientation) {
              switch(orientation){
                  case ROTATION_O:
                      //rotate as on portrait
                 yourButton.animate().rotation(0).setDuration(500).start();
                      break;
                  case ROTATION_90:
                      //rotate as left on top
                 yourButton.animate().rotation(-90).setDuration(500).start();
                      break;
                  case ROTATION_270:
                      //rotate as right on top
                 yourButton.animate().rotation(90).setDuration(500).start();
                      break;
                  case ROTATION_180:
                      //rotate as upside down
                 yourButton.animate().rotation(180).setDuration(500).start();
                      break;

              }
          }
      };

  }

  @Override
  protected void onResume() {
      super.onResume();
      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
      customOrientationEventListener.enable();
  }

  @Override
  protected void onPause() {
      super.onPause();
      customOrientationEventListener.disable();
  }

  @Override
  protected void onDestroy() {
      super.onDestroy();
      customOrientationEventListener.disable();
  }
}

【讨论】:

  • 非常有用的帖子。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-06
  • 1970-01-01
  • 1970-01-01
  • 2013-01-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多