Для профилей членов семьи я создал собственное представление PersonCard:
Код: Выделить всё
public class PersonCard extends FrameLayout {
private ImageView imageView;
private LinearLayout textContainer;
private View topAnchor, bottomAnchor, leftAnchor, rightAnchor;
private int imageSize;
public PersonCard(Context context) {
super(context);
init(null);
}
public PersonCard(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public PersonCard(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
private void init(AttributeSet attrs) {
setBackgroundResource(R.drawable.person_card);
int padding = getResources().getDimensionPixelSize(R.dimen.person_card_padding);
setPadding(padding, padding, padding, padding);
if (attrs != null) {
TypedArray a = getContext().getTheme().obtainStyledAttributes(
attrs,
R.styleable.PersonCard,
0, 0);
try {
imageSize = a.getDimensionPixelSize(R.styleable.PersonCard_imageSize, 0);
} finally {
a.recycle();
}
}
imageView = new ImageView(getContext());
FrameLayout.LayoutParams imageParams = new FrameLayout.LayoutParams(
imageSize,
imageSize
);
imageParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
imageView.setLayoutParams(imageParams);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setImageResource(R.drawable.default_avatar);
textContainer = new LinearLayout(getContext());
FrameLayout.LayoutParams textContainerParams = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
textContainerParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
textContainerParams.topMargin = imageSize + padding;
textContainer.setLayoutParams(textContainerParams);
textContainer.setOrientation(LinearLayout.VERTICAL);
for (int i = 0; i < 3; i++) {
TextView textView = new TextView(getContext());
textView.setLayoutParams(new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
));
textView.setText("Text " + (i + 1));
textView.setTextColor(ContextCompat.getColor(getContext(), R.color.black));
textView.setPadding(16, 16, 16, 8);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10);
textContainer.addView(textView);
}
topAnchor = new View(getContext());
bottomAnchor = new View(getContext());
leftAnchor = new View(getContext());
rightAnchor = new View(getContext());
int anchorColor = ContextCompat.getColor(getContext(), R.color.tea_rose);
int anchorSize = 10;
topAnchor.setBackgroundColor(anchorColor);
bottomAnchor.setBackgroundColor(anchorColor);
leftAnchor.setBackgroundColor(anchorColor);
rightAnchor.setBackgroundColor(anchorColor);
FrameLayout.LayoutParams topAnchorParams = new FrameLayout.LayoutParams(
anchorSize,
anchorSize
);
topAnchorParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
topAnchorParams.topMargin = -padding;
topAnchor.setLayoutParams(topAnchorParams);
FrameLayout.LayoutParams bottomAnchorParams = new FrameLayout.LayoutParams(
anchorSize,
anchorSize
);
bottomAnchorParams.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
bottomAnchorParams.bottomMargin = -padding;
bottomAnchor.setLayoutParams(bottomAnchorParams);
FrameLayout.LayoutParams leftAnchorParams = new FrameLayout.LayoutParams(
anchorSize,
anchorSize
);
leftAnchorParams.gravity = Gravity.CENTER_VERTICAL | Gravity.LEFT;
leftAnchorParams.leftMargin = -padding;
leftAnchor.setLayoutParams(leftAnchorParams);
FrameLayout.LayoutParams rightAnchorParams = new FrameLayout.LayoutParams(
anchorSize,
anchorSize
);
rightAnchorParams.gravity = Gravity.CENTER_VERTICAL | Gravity.RIGHT;
rightAnchorParams.rightMargin = -padding;
rightAnchor.setLayoutParams(rightAnchorParams);
addView(imageView);
addView(textContainer);
addView(topAnchor);
addView(bottomAnchor);
addView(leftAnchor);
addView(rightAnchor);
}
public int[] getTopAnchorPosition() {
int[] position = new int[2];
topAnchor.getLocationOnScreen(position);
return position;
}
public int[] getBottomAnchorPosition() {
int[] position = new int[2];
bottomAnchor.getLocationOnScreen(position);
return position;
}
public int[] getLeftAnchorPosition() {
int[] position = new int[2];
leftAnchor.getLocationOnScreen(position);
return position;
}
public int[] getRightAnchorPosition() {
int[] position = new int[2];
rightAnchor.getLocationOnScreen(position);
return position;
}
}
[img]https://i.sstatic. net/8MlYHEcT.png[/img]
Что важно, так это розы на каждой стороне PersonCard, поскольку я планирую соединять разные PersonCard, и мой План состоял в том, чтобы использовать эти пустые представления (розы) в качестве «якорей» для каждой PersonCard для подключения через другое пользовательское представление.
Чтобы иметь что-то, что соединяет для двух PersonCard я создал представление ConnectionLine:
Код: Выделить всё
public class ConnectionLine extends View {
private Paint paint;
private float startX, startY, endX, endY;
public ConnectionLine(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ConnectionLine(Context context) {
super(context);
init();
}
private void init() {
paint = new Paint();
paint.setColor(getResources().getColor(android.R.color.black)); // Set the color to black
paint.setStrokeWidth(5);
}
public void setPoints(float startX, float startY, float endX, float endY) {
this.startX = startX;
this.startY = startY;
this.endX = endX;
this.endY = endY;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawLine(startX, startY, endX, endY, paint);
}
}
Далее я разместил две карты PersonCard
code> и одну ConnectionLine в моем фрагменте, вот так:
[img]https://i.sstatic. net/j5IhYHFd.png[/img]
В моем ConnectionsFragment.java у меня есть следующий код:
Код: Выделить всё
public class ConnectionsFragment extends Fragment {
private PersonCard personCard1, personCard2;
private ConnectionLine connectionLine;
public ConnectionsFragment() {
}
public static ConnectionsFragment newInstance(String param1, String param2) {
ConnectionsFragment fragment = new ConnectionsFragment();
return fragment;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_connections, container, false);
personCard1 = rootView.findViewById(R.id.personCard1);
personCard2 = rootView.findViewById(R.id.personCard2);
connectionLine = rootView.findViewById(R.id.connectionLine);
personCard1.post(new Runnable() {
@Override
public void run() {
int[] startLocation = personCard1.getRightAnchorPosition();
int[] endLocation = personCard2.getLeftAnchorPosition();
connectionLine.setPoints(startLocation[0], startLocation[1], endLocation[0], endLocation[1]);
}
});
return rootView;
}
}
Код: Выделить всё
anchorПо моей логике, с помощью этих шагов ConnectionLine должен успешно соединить две карты personCard. Однако, когда я запускаю приложение, происходит следующее:
По моей логике, с помощью этих шагов ConnectionLine должен успешно соединить две карты personCard. Однако, когда я запускаю приложение, происходит следующее:

< /p>
Как видите, ConnectionLine находится далеко от точки привязки, где она должна быть.
Я также пытался соединить другие точки привязки, но они также не совсем соединились там, где я хотел, и у меня заканчиваются идеи. С моей точки зрения ConnectionLine не может быть неправильным, поскольку он просто берет координаты, которые я ему даю, и подключается к ним. Это означает, что мои координаты должны быть в чем-то неправильными. Кроме того, координата x всегда кажется правильной, но координата y всегда отключена.
Есть ли у кого-нибудь опыт работы с этим? Или может быть решение?
Подробнее здесь: https://stackoverflow.com/questions/786 ... are-offset
Мобильная версия