我想布置一个如下所示的视图,但我不知道该怎么做:
这是我想象的一个小图片:
.----------------------.
| .--------------. |
| b | | b |
| g | | g |
| | | |
| i | MySurface | i |
| m | View | m |
| a | | a |
| g | (2:3 w:h) | g |
| e | | e |
| *--------------* |
|.--------------------.|
|| ||
|| SomeOtherView ||
|| ||
|*--------------------*|
*----------------------*
就设置MySurfaceView而言,我认为普通的layout_width和layout_height不会对我有所帮助,因为直到屏幕部分布局之后我才知道可用的屏幕尺寸,{{1}已被放置。
我想要覆盖SomeOtherView
中的某些功能,例如将作为参数传递可用的屏幕空间,让我决定如何设置视图的宽度和高度?
'通货膨胀'是我正在寻找的正确名词吗?我认为这与我正在寻找的东西有关,但我真的不知道术语。
Updated below我的研究结果,我认为可能是正确的解决方案。
答案 0 :(得分:13)
做了更多的研究,我想我想出了我需要做的事情:
我想要覆盖的函数是onMeasure(int widthSpec, int heightSpec)
,由父级调用,提供宽度和高度的建议(参见View.MeasureSpec)。我还将MySurfaceView
设置为在xml中具有wrap_content
的layout_width / height。然后,当调用onMeasure
时,我可以计算可用的宽高比,并根据需要设置视图的宽度和高度。
我做的第二件事是将我的MySurfaceView
放在FrameLayout中作为唯一的孩子。我最初在RelativeLayout中使用MySurfaceView
并使用我的图片中的SomeOtherView
。 RelativeLayout的问题在于它不会以允许我修复宽高比的方式协商宽度/高度。
onMeasure
在测量过程中被多次调用,而RelativeLayout的工作方式是它首先询问自定义视图的宽度而不告诉它可用的高度,然后再回来询问高度,同时宽度将锁定为您在第一次传递(MeasureSpec.EXACTLY
)中指定的宽度。这使得无法生成特定比率的视图,因为在知道可用高度之前必须确认宽度。
一旦进入FrameLayout,我就没有这个问题,因为传递给onMeasure
的MeasureSpecs只有限制AT_MOST
。这意味着我可以在onMeasure的每次传递过程中自由更改宽度和高度,因此我可以根据可用区域最终计算出我的宽高比。
尚未确认这适用于所有情况,但希望这会对某人有所帮助。
答案 1 :(得分:1)
要设置应使用的SurfaceView的大小:
// Set surfaceview size in px
private void setVideoSize(int width, int height) {
LayoutParams params = (LayoutParams) mYourSurfaceView.getLayoutParams();
params.height = height;
params.width = width;
mYourSurfaceView.setLayoutParams(params);
}
如果你想知道屏幕的大小:
Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int width = display.getWidth();
int heigth = display.getHeight();
希望这有帮助
答案 2 :(得分:0)
这将是我测试过的。
public class Test_stflowActivity extends Activity {
SurfaceView sv = null;
RelativeLayout rl = null;
int current_width = 0;
int current_height = 0;
boolean already_created = false;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
sv = (SurfaceView) findViewById(R.id.SurfaceView1);
rl = (RelativeLayout) findViewById(R.id.relativeLayout3);
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
current_height = rl.getHeight();
while (current_height == 0) {
current_height = rl.getHeight();
}
current_width = rl.getWidth();
runOnUiThread(new Runnable() {
@Override
public void run() {
update_surface(current_height, current_width);
}
});
}
});
thread.start();
already_created = false;
}
void update_surface(int current_height,int current_width) {
if (already_created == false){
// CALCULATE ASPECTED RATIO ACCORDING TO ABOVE HEIGHT AND WIDTH.
int calculated_height = current_height/2;
int calculated_width = current_width /2;
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(calculated_height,
calculated_width);
lp.addRule(RelativeLayout.CENTER_IN_PARENT);
sv.setLayoutParams(lp);
sv.setVisibility(View.VISIBLE);
already_created = true;
}
super.onResume();
}
}
这是我创建的布局。
<RelativeLayout
android:id="@+id/relativeLayout2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="87dp"
android:text="Button" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/relativeLayout3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/relativeLayout2"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" >
<android.view.SurfaceView
android:id="@+id/SurfaceView1"
android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_centerInParent="true" android:background="#ff0000" android:visibility="invisible"/>
</RelativeLayout>
希望帮助你解决。
答案 3 :(得分:0)
随着ConstraintLayout
和布局编辑器的引入,处理比率变得更加容易。
请查看下面的XML代码段:
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/bckg" />
<FrameLayout
android:id="@+id/mySurfaceView"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#99000000"
app:layout_constraintTop_toTopOf="@+id/imageView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@+id/someOtherView"
app:layout_constraintDimensionRatio="W,2:3" />
<FrameLayout
android:id="@+id/someOtherView"
android:layout_width="0dp"
android:layout_height="100dp"
android:background="#AAFFFFFF"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</android.support.constraint.ConstraintLayout>
这足以达到你要求的结果。请参见下面的屏幕截图: