gpt4 book ai didi

android - 获取 View 每个角的位置,然后在该位置添加 View

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:17:45 25 4
gpt4 key购买 nike

我正在开发一个有自定义 View 的 android 项目。单击自定义 View 时,我想要在 View 的每个角放置一个 View (一个圆圈)。

目前我只是想让它在左上角工作,但它最终出现在中间。

下面是我添加 View 的点击功能。

View view = LayoutInflater.from(getContext()).inflate(R.layout.view, this, false);

TextView textItem = view.findViewById(R.id.lblItemText);

textItem.setText("View: " + counter);

view.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{

Anchor anchor1 = new Anchor(getContext());

anchor1.setLeft(v.getLeft());
anchor1.setTop(CustomView.this.getTop());
CustomView.this.addView(anchor1);
}
});

自定义 View 托管在相对布局中。自定义 View 扩展了 RelativeLayout 和应该进入自定义 View 左上角的 anchor View 扩展了按钮。

anchor 构造函数包含以下内容:

public Anchor(Context context)
{
super(context);
this.setBackgroundResource(R.drawable.anchor);
this.setPadding(0,0,0,0);
this.setWidth(1);
this.setHeight(1);
}

由于某种原因, anchor 出现在中间而不是如下所示的角落

What the end result is

下面有点期待。

Expected view

更新

几天后取得了一些进展,我确实让它工作了,除了它使用硬编码值使其处于正确的位置,这似乎不正确。我猜这只适用于我正在测试的特定设备,另一台分辨率不同的设备将定位错误。

下面是我拥有的代码,希望能够显示我正在尝试实现的目标以及我现在拥有的屏幕截图。

private void createAnchorPoints()
{

//Main View
ViewGroup mainView = activity.findViewById(android.R.id.content);

int[] viewToBeResizedLoc = new int[2];
viewToBeResized.getLocationOnScreen(viewToBeResizedLoc);


//Add top left anchor
Anchor topLeftAnchor = new Anchor(context, Anchor.ResizeMode.TOP_LEFT);
FrameLayout.LayoutParams topLeftParms = new FrameLayout.LayoutParams(150,150);
topLeftParms.leftMargin = viewToBeResizedLoc[0] - 50;
topLeftParms.topMargin = viewToBeResizedLoc[1] - viewToBeResized.getHeight() - 30;
topLeftAnchor.setLayoutParams(topLeftParms);
mainView.addView(topLeftAnchor);

//Add top right anchor
Anchor topRightAnchor = new Anchor(context, Anchor.ResizeMode.TOP_RIGHT);
FrameLayout.LayoutParams topRightParms = new FrameLayout.LayoutParams(150, 150);
topRightParms.leftMargin = topLeftParms.leftMargin + viewToBeResized.getWidth() - 40;
topRightParms.topMargin = topLeftParms.topMargin;
topRightAnchor.setLayoutParams(topRightParms);
mainView.addView(topRightAnchor);

//Add bottom left anchor
Anchor bottomLeftAnchor = new Anchor(context, Anchor.ResizeMode.BOTTOM_LEFT);
FrameLayout.LayoutParams bottomLeftParms = new FrameLayout.LayoutParams(150, 150);
bottomLeftParms.leftMargin = topLeftParms.leftMargin;
bottomLeftParms.topMargin = topLeftParms.topMargin + viewToBeResized.getHeight() - 40;
bottomLeftAnchor.setLayoutParams(bottomLeftParms);
mainView.addView(bottomLeftAnchor);

//Add bottom right anchor
Anchor bottomRightAnchor = new Anchor(context, Anchor.ResizeMode.BOTTOM_RIGHT);
FrameLayout.LayoutParams bottomRightParms = new FrameLayout.LayoutParams(150, 150);
bottomRightParms.leftMargin = topRightParms.leftMargin;
bottomRightParms.topMargin = bottomLeftParms.topMargin;
bottomRightAnchor.setLayoutParams(bottomRightParms);
mainView.addView(bottomRightAnchor);

}

Current example after update

最佳答案

由于顶级布局是 RelativeLayout,您需要使用 RelativeLayout 可用的 View 定位来实现您想要的效果。 (参见 documentation 。)

这是您希望在 XML 中实现的目标的模型。这个模型将展示我们如何接近实际的解决方案。我正在使用标准 View ,但这无关紧要。该技术将应用于您的自定义 View 。图片来自 Android Studio 的设计器,因此没有使用代码来创建图片。

enter image description here

activity_main.xml

<RelativeLayout 
android:id="@+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<RelativeLayout
android:id="@+id/customView"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_centerInParent="true"
android:background="@android:color/holo_green_light" />

<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignStart="@id/customView"
android:layout_alignTop="@id/customView"
android:src="@drawable/circle"
android:translationX="-10dp"
android:translationY="-10dp" />

<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignEnd="@id/customView"
android:layout_alignTop="@id/customView"
android:src="@drawable/circle"
android:translationX="10dp"
android:translationY="-10dp" />

<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignBottom="@id/customView"
android:layout_alignStart="@id/customView"
android:src="@drawable/circle"
android:translationX="-10dp"
android:translationY="10dp" />

<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignBottom="@id/customView"
android:layout_alignEnd="@id/customView"
android:src="@drawable/circle"
android:translationX="10dp"
android:translationY="10dp" />

</RelativeLayout>

circle.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<!-- fill color -->
<solid android:color="@android:color/holo_red_light" />
<size
android:width="20dp"
android:height="20dp" />
</shape>

实际解决方案

既然我们已经证明了模型方法的有效性,我们现在必须在代码中重现该效果。我们将不得不添加圆 View 并使用 RelativeLayout View 定位和转换将其定位在父级 RelativeLayout 中。以下代码仅显示左上角的圆圈定位,但其他圆圈将以类似的方式定位。

activity_main.java

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Drawable circle = ContextCompat.getDrawable(this, R.drawable.circle);
ImageView imageView = new ImageView(this);
imageView.setImageDrawable(circle);
int circleSize = dpToPx(CIRCLE_SIZE_DP);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(circleSize, circleSize);

// Position top left circle within the custom view.
lp.addRule(RelativeLayout.ALIGN_START, R.id.customView);
lp.addRule(RelativeLayout.ALIGN_TOP, R.id.customView);

// Uncomment these 2 lines to position the top left circle with translation.
imageView.setTranslationX(-circleSize / 2);
imageView.setTranslationY(-circleSize / 2);

// Uncomment these 3 lines to position the top left circle with margins.
// View customView = findViewById(R.id.customView);
// lp.leftMargin = customView.getLeft() - circleSize / 2;
// lp.topMargin = customView.getTop() - circleSize / 2;

((RelativeLayout) findViewById(R.id.relativeLayout)).addView(imageView, lp);
}

private int dpToPx(int dp) {
return (int) (dp * getResources().getDisplayMetrics().density);
}

private static final int CIRCLE_SIZE_DP = 20;
}

上面的代码使用了一个缩短的布局:

activity_main.xml

<RelativeLayout 
android:id="@+id/relativeLayout"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<RelativeLayout
android:id="@+id/customView"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_centerInParent="true"
android:background="@android:color/holo_green_light" />

</RelativeLayout>

也可以使用边距产生相同的定位。使用边距的代码已被注释掉,但可以使用。 (我认为负边距也可能有效,但我读到它们不是 officially supported ,所以我尽量避免使用它们。)

关于android - 获取 View 每个角的位置,然后在该位置添加 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50994978/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com