RelativeLayout align parent bottom 在底部不对齐
RelativeLayout align parent bottom does not align at bottom
我有一个使用相对布局的自定义圆形布局:
public class CircularLayout extends RelativeLayout implements OnDragListener {
private DropCallback onDrop = null;
private ImageButton imageButton = null;
private ImageView imageViewBackgroundWave = null;
private int radius = -1;
private double step = -1;
private double angle = -1;
private static final int CENTER_ID = 111;
public CircularLayout(Context context, DropCallback onDrop, int radius, List<View> views) {
super(context);
this.onDrop = onDrop;
this.radius = radius;
this.step = (2 * Math.PI) / views.size();
this.initView(context, views);
}
private void initView(Context context, List<View> views) {
RelativeLayout.LayoutParams layoutParamsView = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
this.setLayoutParams(layoutParamsView);
RelativeLayout.LayoutParams layoutParamsImageview = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParamsImageview.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
layoutParamsImageview.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
this.imageViewBackgroundWave = new ImageView(this.getContext());
this.imageViewBackgroundWave.setLayoutParams(layoutParamsImageview);
this.imageViewBackgroundWave.setImageDrawable(this.getResources().getDrawable(R.drawable.background_wave));
this.addView(this.imageViewBackgroundWave);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
layoutParams.addRule(RelativeLayout.CENTER_VERTICAL);
this.imageButton = new ImageButton(context);
this.imageButton.setId(CENTER_ID);
this.imageButton.setLayoutParams(layoutParams);
this.imageButton.setImageResource(R.drawable.ic_power_on);
this.imageButton.getBackground().setAlpha(0);
this.imageButton.setOnDragListener(this);
this.addView(this.imageButton);
for(View view : views) {
this.addView(this.placeView(view));
}
}
private View placeView(View view) {
view.measure(0, 0);
this.imageButton.measure(0, 0);
int x = (int)((view.getMeasuredWidth() / 2) + this.radius * Math.cos(this.angle));
int y = (int)((view.getMeasuredHeight() / 2) + this.radius * Math.sin(this.angle));
this.angle += this.step;
int deltaX = view.getMeasuredWidth();
int deltaY = view.getMeasuredHeight();
int deltaImageX = this.imageButton.getMeasuredWidth() / 2;
int deltaImageY = this.imageButton.getMeasuredHeight() / 2;
int xToDraw = ((x - deltaX) - deltaImageX);
int yToDraw = ((y - deltaY) - deltaImageY);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.ABOVE, CENTER_ID);
layoutParams.addRule(RelativeLayout.RIGHT_OF, CENTER_ID);
layoutParams.setMargins(xToDraw, 0, 0, yToDraw);
view.setLayoutParams(layoutParams);
return view;
}
@Override
public boolean onDrag(View view, DragEvent event) {
return this.onDrop.onDrop(view, event);
}
}
不幸的是,imageview (imageViewBackgroundWave) 没有在底部对齐。它对齐得高一点:
所以问题是:如何将图像视图与屏幕底部对齐?
图像与蓝色条纹一样高和一样宽。没有
填充或白色。就是上图中的蓝色条纹
编辑:
background_wave.png:
我在 MenuFragment
中使用了这个自定义布局,并使用以下代码调用它:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// ... init the imagebuttons in the list of views
this.circleView = new CircularLayout(this.getActivity(), this, 250, views);
this.circleView.setOnDragListener(this);
this.circleView.setBackground(this.getResources().getDrawable(R.drawable.background));
return this.circleView;
}
您正在使用 RelativeLayout.LayoutParams.WRAP_CONTENT
和 RelativeLayout.ALIGN_PARENT_BOTTOM
两次设置宽度和高度
试试这个:
private void initView(Context context) {
RelativeLayout.LayoutParams layoutParamsView = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
this.setLayoutParams(layoutParamsView);
RelativeLayout.LayoutParams layoutParamsImageview = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
this.imageView = new ImageView(this.getContext());
this.imageView.setLayoutParams(layoutParamsImageview);
this.imageView.setImageDrawable(this.getResources().getDrawable(R.drawable.background_wave));
this.addView(this.imageView);
}
我还建议您使用可视化设计器 XML 来测试布局的规则和参数,然后,如果需要,您可以在代码中设置规则以获得相同的结果。
您可以通过添加这行代码让 ImageView 固定在底部:
imageView.setScaleType(ScaleType.FIT_END);
奇怪的原因是ImageView边界首先由布局引擎计算,然后ImageView内部的图像根据比例缩放以适合分配的区域类型。
对 ImageView 使用 WRAP_CONTENT 会根据 未缩放 图像位图的大小分配一个区域 - 即使它比屏幕大。您的 background_wave.png 文件比屏幕宽,因此分配的区域比需要的区域大。然后,当使用 FIT_CENTER 将图像放入布局区域内时,它会缩小并居中,因此最终会在其上方和下方出现白色 space。
您可以通过将 background_wave.png 大小调整为 1/4 来验证这一点:即使没有更改上述代码,它也应该对齐底部。
我有一个使用相对布局的自定义圆形布局:
public class CircularLayout extends RelativeLayout implements OnDragListener {
private DropCallback onDrop = null;
private ImageButton imageButton = null;
private ImageView imageViewBackgroundWave = null;
private int radius = -1;
private double step = -1;
private double angle = -1;
private static final int CENTER_ID = 111;
public CircularLayout(Context context, DropCallback onDrop, int radius, List<View> views) {
super(context);
this.onDrop = onDrop;
this.radius = radius;
this.step = (2 * Math.PI) / views.size();
this.initView(context, views);
}
private void initView(Context context, List<View> views) {
RelativeLayout.LayoutParams layoutParamsView = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
this.setLayoutParams(layoutParamsView);
RelativeLayout.LayoutParams layoutParamsImageview = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParamsImageview.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
layoutParamsImageview.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
this.imageViewBackgroundWave = new ImageView(this.getContext());
this.imageViewBackgroundWave.setLayoutParams(layoutParamsImageview);
this.imageViewBackgroundWave.setImageDrawable(this.getResources().getDrawable(R.drawable.background_wave));
this.addView(this.imageViewBackgroundWave);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
layoutParams.addRule(RelativeLayout.CENTER_VERTICAL);
this.imageButton = new ImageButton(context);
this.imageButton.setId(CENTER_ID);
this.imageButton.setLayoutParams(layoutParams);
this.imageButton.setImageResource(R.drawable.ic_power_on);
this.imageButton.getBackground().setAlpha(0);
this.imageButton.setOnDragListener(this);
this.addView(this.imageButton);
for(View view : views) {
this.addView(this.placeView(view));
}
}
private View placeView(View view) {
view.measure(0, 0);
this.imageButton.measure(0, 0);
int x = (int)((view.getMeasuredWidth() / 2) + this.radius * Math.cos(this.angle));
int y = (int)((view.getMeasuredHeight() / 2) + this.radius * Math.sin(this.angle));
this.angle += this.step;
int deltaX = view.getMeasuredWidth();
int deltaY = view.getMeasuredHeight();
int deltaImageX = this.imageButton.getMeasuredWidth() / 2;
int deltaImageY = this.imageButton.getMeasuredHeight() / 2;
int xToDraw = ((x - deltaX) - deltaImageX);
int yToDraw = ((y - deltaY) - deltaImageY);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.ABOVE, CENTER_ID);
layoutParams.addRule(RelativeLayout.RIGHT_OF, CENTER_ID);
layoutParams.setMargins(xToDraw, 0, 0, yToDraw);
view.setLayoutParams(layoutParams);
return view;
}
@Override
public boolean onDrag(View view, DragEvent event) {
return this.onDrop.onDrop(view, event);
}
}
不幸的是,imageview (imageViewBackgroundWave) 没有在底部对齐。它对齐得高一点:
所以问题是:如何将图像视图与屏幕底部对齐? 图像与蓝色条纹一样高和一样宽。没有 填充或白色。就是上图中的蓝色条纹
编辑:
background_wave.png:
我在 MenuFragment
中使用了这个自定义布局,并使用以下代码调用它:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// ... init the imagebuttons in the list of views
this.circleView = new CircularLayout(this.getActivity(), this, 250, views);
this.circleView.setOnDragListener(this);
this.circleView.setBackground(this.getResources().getDrawable(R.drawable.background));
return this.circleView;
}
您正在使用 RelativeLayout.LayoutParams.WRAP_CONTENT
和 RelativeLayout.ALIGN_PARENT_BOTTOM
试试这个:
private void initView(Context context) {
RelativeLayout.LayoutParams layoutParamsView = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
this.setLayoutParams(layoutParamsView);
RelativeLayout.LayoutParams layoutParamsImageview = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
this.imageView = new ImageView(this.getContext());
this.imageView.setLayoutParams(layoutParamsImageview);
this.imageView.setImageDrawable(this.getResources().getDrawable(R.drawable.background_wave));
this.addView(this.imageView);
}
我还建议您使用可视化设计器 XML 来测试布局的规则和参数,然后,如果需要,您可以在代码中设置规则以获得相同的结果。
您可以通过添加这行代码让 ImageView 固定在底部:
imageView.setScaleType(ScaleType.FIT_END);
奇怪的原因是ImageView边界首先由布局引擎计算,然后ImageView内部的图像根据比例缩放以适合分配的区域类型。
对 ImageView 使用 WRAP_CONTENT 会根据 未缩放 图像位图的大小分配一个区域 - 即使它比屏幕大。您的 background_wave.png 文件比屏幕宽,因此分配的区域比需要的区域大。然后,当使用 FIT_CENTER 将图像放入布局区域内时,它会缩小并居中,因此最终会在其上方和下方出现白色 space。
您可以通过将 background_wave.png 大小调整为 1/4 来验证这一点:即使没有更改上述代码,它也应该对齐底部。