【问题标题】:How to specify which view is clicked in layout added multiple times如何指定在多次添加的布局中单击哪个视图
【发布时间】:2016-09-01 09:36:21
【问题描述】:

我有一个包含用户孩子信息的布局。假设此布局获取有关孩子的名字、姓氏和年龄的信息。我正在使用 EditText 进行输入。还有一个显示儿童过敏类型的微调器,在选择 1 过敏类型时,它必须从 web 服务获取其详细信息并将这些详细信息填充到文本视图中。

因此,用户可以通过这种方式添加任意数量的孩子。问题发生在那里。假设用户现在已经添加了 4 次该布局,他选择了孩子 1 的微调器并调用了服务,它获取信息并将其填充到添加的最后一个布局文本视图中。

正如预期的那样,详细信息应填写相应添加的每个布局的每个文本视图。

困惑:

  1. 如何准确获取点击了哪个视图,然后如何在该视图的相同布局中采取行动,而不是最近添加的那个?
  2. 我正在膨胀具有上面指定的特定字段集的布局。所以我正在维护添加的每个布局的数组列表,所以有没有办法在该布局中获得完全相同的视图及其对应的视图?

更新 1:我的问题的一些想法

有一个主要活动,它有一个名为“添加更多孩子”的按钮。当用户点击这个时,包含孩子信息的布局会添加到 ScrollView 的指定区域中,以便用户可以添加任意数量的孩子。

所以基本上我在下面绘制了一些视图,因为以下名为 children 的布局中有太多视图。但是这个布局显示了需要完成的工作类型。所以请看下面并有一些想法

为了演示,您可以看到不同的编辑文本和微调器。微调器从 Webs 服务获取更新,每个子组件可能从 Web 服务在微调器中加载不同的数据。这整个布局膨胀到主要活动中。在按钮上单击名为 Add Children 。等等那个按钮,我在滚动视图中添加这个

private View addChildLayout(int childLayoutid, LinearLayout Targetlayout) {
    //where childLayoutid is a layout resourse id of childern layout
    // where Target layout is a scrollview in my fragment 
    LayoutInflater inflater = LayoutInflater.from(getActivity());
    View inflatedLayout1 = inflater.inflate(childLayoutid, null, false);
    inflatedLayout1.setId(numOfChildAdded);// numOfChildAdded is int number            of children added by user so far
    Targetlayout.addView(inflatedLayout1, 0);
    numOfAddedChildLayout.add(inflatedLayout1);//this is an array list i am creating to keep track of each layout added by user on add button click 

    return inflatedLayout1;
}

在布局中添加它之后,我调用了另一个方法来查找此布局的 id 并设置每个视图的点击侦听器,即微调器或编辑文本或任何需要的东西。现在假设用户添加了一个孩子。并单击获取子类别并填充 spinnerSubCatogry 的 spinnerAllergy 类型,再次单击 Web 服务时将调用 spinnerSubcategory 并获取过敏详细信息并填写 Textview(如图所示的大框)

现在主要问题出现在用户添加 2 号子项时。现在假设用户添加了 2 个子项,但他单击了 Child1 的 spinnerAllergy,child1 微调器运行 Web 服务但填充了 Child2 的微调器子类别。

看起来当添加新的孩子时,点击监听器是指新添加的新布局。

所以这是主要问题。我希望每个布局中的每个视图在其视图和边界中相应地工作。我的意思是 child1 布局视图单击侦听器应该填充其视图而不是当前添加的布局视图。

我认为这些信息足以让您获得一些清晰的想法。

请帮帮我,我在这里卡了 2 天。我的所有设计都运行良好。

【问题讨论】:

  • 把你的代码放在这里
  • 您可以设置一个监听器,当用户在通货膨胀时按下 EditText 以设置参考并在调用您的服务时使用该参考。
  • @yarakyo 你在说什么请演示
  • @VishalPatoliya 代码思路添加

标签: android android-layout layout


【解决方案1】:

正如您在上面所说,您正在跟踪(列表)您添加的每个视图。我会建议你使用它

这是您正在使用和设置 id 的行,因此这意味着每个父母都有不同的 id,而他们的孩子视图具有相同的 id,

 View inflatedLayout1 = inflater.inflate(childLayoutid, null, false);
inflatedLayout1.setId(numOfChildAdded);

当您添加具有不同 ID 的每个布局时,为什么不简单地获取父级,然后再次获取具有特定 ID 的子级,以进行演示

假设您的布局中有一个 textview ,并且在线性布局下,该线性布局具有作为根/主布局的相对布局,并且每个主布局都有不同的 id,就像您在上面所做的那样。所以这就是你将如何到达顶部(父 ID)

  ViewGroup row = (ViewGroup) yourTextView.getParent().getParent;
  TextView textView = (TextView) row.findViewById(R.id.tvClassLevels); // the next view you can find 

所以在这里我建议对每个视图执行此操作,然后设置单击侦听器。 这可能效率不高,但这会奏效。我曾经做过一次,当我为自定义布局充气时,请记住每次充气虽然可能很快但代价高昂,但您需要在 getview 附近实现一些逻辑(因为我们在适配器中实现了它)

为什么我要做两次 getParent().getParent() 正如我所说,我的 textview 在线性布局中,而线性布局位于主/根布局中,因此我们想要接近主布局,因为我们知道它是唯一具有不同 Id 的布局,所以我们正在执行 getParent() 两次由于Textview有LinearLayout作为第一个Parent,然后是根布局,所以这样如果你有另一个布局中的视图,你需要自己去挖掘它。

我再说一遍,它可能不是一个很酷或最好的实现,但它确实有效。至少它对我有用。

【讨论】:

    【解决方案2】:

    我认为问题在于:您的布局中的不同视图具有 SAME id,因为您是从同一个 xml 布局中膨胀的。

    你有不同的方法来解决这个问题:

    • 在添加子视图时跟踪变量并增加计数。充气完成后,您可以在新创建的视图上调用 setId(正如 Abdul Salam Ali 的回答中所述)。虽然 android 中的视图 id 是在编译时生成的(如果我错了,请纠正我),这在实践中应该可以完美地工作。
    • 在 res/values 文件夹中创建一个 Ids 资源文件,并预定义一些 Id 值以供将来使用。保证所有 id 值都是不同的。但正如您所说,用户可以添加任意数量的子信息,这可能不是最佳选择。
    • 使用Random 生成不同的ID。

    请注意,即使您的布局中具有相同的 ID,只要您调用 ViewGroup 的子代 findViewById(或类似的东西)具有唯一 ID,您的代码逻辑也是正确的。见this

    【讨论】:

    • 您附加的链接是很好的解释。我认为上面的答案(Abdul Salam Ali 的答案)是最完整的,不仅表明了真正的问题,而且他还告诉了解决方案,乍一看,我无法通过 getParent().getParent() 说什么。实际上他是在指出将来可能发生的问题,并且当我的复选框之一位于多个布局(嵌套)中时,我遇到了它,那么它确实对我有用。
    【解决方案3】:

    对您的设计提出一些建议。

    1. 使用列表视图和适配器设计,而不是在编程中生成视图。

      一个。添加新项目

      使用浮动操作按钮。 https://material.google.com/components/buttons-floating-action-button.html#buttons-floating-action-button-floating-action-button

      B.删除项目

      使用一些列表控件或多重选择器来删除不需要的项目。https://material.google.com/components/lists-controls.html#lists-controls-types-of-list-controls

    2. 使用列表视图来显示您的项目,而不是在您的代码中生成布局。

      https://material.google.com/components/lists.html#lists-usage

    3. 要编辑特定的子信息,建议使用全屏对话框进行编辑。

      https://material.google.com/components/dialogs.html#dialogs-full-screen-dialogs

    以上是我对你的设计的建议,因为如果你想让被点击的视图的父级找到你在布局中的实际位置,然后发送去监听相应的点击事件,这将是很困难的。如果您的父级中有任何嵌套视图,这将很难维护并且您的代码将很难调试。尝试将每个部分分开以帮助您调试代码中的错误。

    【讨论】:

    • 由于某些原因我不能使用 Listview ,所以你能告诉我如何获得父母
    • 如果需要根据点击的视图查找视图层次结构,可以看一下这个(stackoverflow.com/questions/7484471/…stackoverflow.com/questions/17879743/…)。但你应该知道,这样做不是一个好习惯。
    • 我应该做什么或者你还有什么建议
    • 我想再次确认,您的问题是关于如何根据布局中的点击视图获取位置?另外,如果您需要根据您的要求提出一些可靠的建议,请发布您的工作的一些简单代码,我们可以看看它。
    • 虽然我需要在这个问题上发布很多代码,但让我放一些代码
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    • 1970-01-01
    • 2019-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多