昨天我试图创建一个所有元素的自定义视图 像按钮,图像按钮,...围绕一个圆圈放置 等间距。
我的目标是得到这个:
我试过这段代码:
public class CircleView extends RelativeLayout {
private OnDrop onDrop = null;
private int radius = -1;
private double step = -1;
private double angle = -1;
private static final int CENTER_ID = 111;
public CircleView(Context context, OnDrop onDrop, int radius, List<View> elements) {
super(context);
this.onDrop = onDrop;
this.radius = radius;
this.step = (2 * Math.PI) / elements.size();
RelativeLayout.LayoutParams layoutParamsView = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
this.setLayoutParams(layoutParamsView);
this.addView(this.createCenter(context));
for(View view : elements) {
this.addView(this.placeView(view));
}
}
private View placeView(View view) {
RelativeLayout.LayoutParams layoutParams = createNewRelativeLayoutParams();
int x = (int)(view.getWidth() / 2 + this.radius * Math.cos(this.angle));
int y = (int)(view.getHeight() / 2 + this.radius * Math.sin(this.angle));
this.angle += this.step;
layoutParams.setMargins(x, 0, 0, y);
view.setLayoutParams(layoutParams);
return view;
}
private View createCenter(Context context) {
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(Globals.DRAG_TARGET_SIZE, Globals.DRAG_TARGET_SIZE);
layoutParams.addRule(CENTER_HORIZONTAL);
layoutParams.addRule(CENTER_VERTICAL);
Button button = new Button(context);
button.setId(CENTER_ID);
button.setLayoutParams(layoutParams);
return button;
}
private RelativeLayout.LayoutParams createNewRelativeLayoutParams() {
RelativeLayout.LayoutParams layoutParameters = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParameters.addRule(RelativeLayout.ABOVE, CENTER_ID);
layoutParameters.addRule(RIGHT_OF, CENTER_ID);
return layoutParameters;
}
}
我从这段代码得到的是:
这意味着创建具有相等间距的圆 元素工作得很好。但仍有问题 放置。 x和y坐标有问题。
有人可以帮我弄清楚如何纠正这种偏移吗?
答案 0 :(得分:1)
我实现了自己的布局,将按钮循环放置在中心点周围:
/**
*
*/
public class MenuCircularLayout extends MenuDragableButtonsLayout {
/**
*
*/
private RelativeLayout relativeLayoutCenter = null;
/**
*
*/
private List<View> menuButtons = null;
/**
*
*/
private ImageButton imageButtonCenter = null;
/**
*
*/
private int radius = -1;
/**
*
*/
private double step = -1;
/**
*
*/
private double angle = -1;
/**
*
*/
private static final int CENTER_ID = View.generateViewId();
/**
*
* @param context
* @param callbackDrag
* @param menuButtons
*/
public MenuCircularLayout(Context context, CallbackDrag callbackDrag, List<View> menuButtons) {
super(context);
this.callbackDrag = callbackDrag;
this.menuButtons = menuButtons;
this.radius = Sizes.getDpToPx(context, Sizes.MENU_ICON_RADIUS);
this.step = (2 * Math.PI) / menuButtons.size();
this.initView();
}
/**
*
*/
private void initView() {
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
this.setLayoutParams(layoutParams);
RelativeLayout.LayoutParams layoutParamsCenter = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, Sizes.getOptimalMenuHeight(this.getContext()));
layoutParamsCenter.addRule(RelativeLayout.CENTER_IN_PARENT);
this.relativeLayoutCenter = new RelativeLayout(this.getContext());
this.relativeLayoutCenter.setLayoutParams(layoutParamsCenter);
this.relativeLayoutCenter.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
RelativeLayout.LayoutParams layoutParamsImageButtonCenter = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParamsImageButtonCenter.addRule(RelativeLayout.CENTER_IN_PARENT);
this.imageButtonCenter = new ImageButton(this.getContext());
this.imageButtonCenter.setId(CENTER_ID);
this.imageButtonCenter.setLayoutParams(layoutParamsImageButtonCenter);
this.imageButtonCenter.setImageDrawable(Images.loadDrawableFromFile(this.getContext(), Paths.IMAGE_POWER));
this.imageButtonCenter.setBackground(null);
this.imageButtonCenter.setOnDragListener(new DropTargetOnDragListener());
this.imageButtonCenter.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
this.relativeLayoutCenter.addView(imageViewCenter);
this.relativeLayoutCenter.addView(this.imageButtonCenter);
this.relativeLayoutCenter.setOnDragListener(new MenuButtonOnDragListener());
for(View view : this.menuButtons) {
this.relativeLayoutCenter.addView(this.placeView(view));
}
this.addView(this.relativeLayoutCenter);
}
/**
*
* @param view
* @return
*/
private View placeView(View view) {
view.measure(0, 0);
this.imageButtonCenter.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.imageButtonCenter.getMeasuredWidth() / 2;
int deltaImageY = this.imageButtonCenter.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);
view.setOnTouchListener(this);
return view;
}
/**
*
*/
@Override
public void removeAllViews() {
super.removeAllViews();
this.relativeLayoutCenter.removeAllViews();
}
}
/**
*
*/
public abstract class MenuDragableButtonsLayout extends RelativeLayout implements OnTouchListener {
/**
*
*/
protected CallbackDrag callbackDrag = null;
/**
*
* @param context
*/
public MenuDragableButtonsLayout(Context context) {
super(context);
}
/**
*
*/
@Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
view.startDrag(null, shadowBuilder, view, 0);
view.setVisibility(View.INVISIBLE);
} break;
case MotionEvent.ACTION_UP: {
view.performClick();
view.setVisibility(View.VISIBLE);
} break;
}
return true;
}
/**
*
*/
public class MenuButtonOnDragListener implements OnDragListener {
/**
*
*/
@Override
public boolean onDrag(View view, DragEvent event) {
View sourceView = (View) event.getLocalState();
float sourceX = sourceView.getX();
float sourceY = sourceView.getY();
float dropX = event.getX() - (sourceView.getWidth() / 2);
float dropY = event.getY() - (sourceView.getHeight() / 2);
switch(event.getAction()) {
case DragEvent.ACTION_DRAG_EXITED : {
TranslateAnimation animation = new TranslateAnimation(dropX - sourceX, 0, dropY - sourceY, 0);
animation.setDuration(300);
sourceView.startAnimation(animation);
sourceView.setX(sourceX);
sourceView.setY(sourceY);
sourceView.setVisibility(View.VISIBLE);
} break;
case DragEvent.ACTION_DROP : {
sourceView.setX(dropX);
sourceView.setY(dropY);
sourceView.setVisibility(View.VISIBLE);
TranslateAnimation animation = new TranslateAnimation(dropX - sourceX, 0, dropY - sourceY, 0);
animation.setDuration(300);
sourceView.startAnimation(animation);
sourceView.setX(sourceX);
sourceView.setY(sourceY);
} break;
}
return true;
}
}
/**
*
*/
public class DropTargetOnDragListener implements OnDragListener {
/**
*
*/
@Override
public boolean onDrag(View view, DragEvent event) {
switch(event.getAction()) {
case DragEvent.ACTION_DROP :
return callbackDrag.onDragCompleted(view, event);
default :
return true;
}
}
}
}
/**
*
*/
public interface CallbackDrag {
/**
*
* @param view
* @param event
* @return
*/
boolean onDragCompleted(final View view, final DragEvent event);
}
使用它像:
public class AnyClass implements CallbackDrag {
private MenuCircularLayout circleView = null;
/**
*
*/
private void initMenu() {
String email = this.getEmail();
Map<String, Boolean> config = this.preferencesSettings.getSettings(email);
List<View> views = new ArrayList<View>();
views.add(this.buttonProfile);
views.add(this.buttonMeasure);
if(this.circleView != null) {
this.circleView.removeAllViews();
this.layoutMenu.removeView(this.circleView);
this.circleView = null;
}
this.circleView = new MenuCircularLayout(this.getActivity(), this, views);
this.circleView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
this.layoutMenu.addView(this.circleView);
}
/**
*
*/
@Override
public boolean onDragCompleted(View view, DragEvent event) {
View sourceView = (View) event.getLocalState();
sourceView.setVisibility(View.VISIBLE);
if(sourceView.equals(this.buttonMeasure)) {
this.performNFCResult();
} else if(sourceView.equals(this.buttonProfile)) {
this.performProfile();
}
return true;
}
}