【问题标题】:ScrollView - Adding dynamic rows from inflated xml layoutScrollView - 从膨胀的 xml 布局添加动态行
【发布时间】:2014-06-11 13:05:16
【问题描述】:

我目前有一个滚动视图,我通过膨胀另一个 xml 布局来添加行。这一切都在正常工作,并且该行都正确显示。

我遇到的问题是我不确定如何检测选择了哪个按钮。

我已经显示了一些示例代码,适用于按钮,只需在选择此按钮时放置它在2张图像之间切换即可。但是,每当我按下按钮时,它总是会自动切换底部的行按钮,而不是选择按钮所在的行。

有没有一种方法可以实现这一点,同时仍然膨胀视图以用作行(我不想动态创建行,因为这会变得非常混乱)?

ScrollView scrollWeapons = (ScrollView)findViewById(R.id.scrollWeapons);
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
int i = 0;

for(final Weapon w : Game.Weapons)
{
    View view = new View(this);
    LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    view = inflater.inflate(R.layout.menuweapons_row, null);

    btnSelected = (ImageButton)view.findViewById(R.id.btnSelected);
    btnSelected.setId(i);
    btnSelected.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            EquipUnequip(w.WeaponID());
        }
    });
}

private void EquipUnequip(int WeaponId)
{
    if(Game.Weapons.get(WeaponId).CharacterID() == ChrSelected)
    {
        btnSelected.setImageResource(R.drawable.eqip_but_idle);
    }
    else
    {
        btnSelected.setImageResource(R.drawable.eqip_but_press);
    }
}

ll.addView(view);
i++;

【问题讨论】:

  • 有什么理由不使用带有自定义适配器的列表视图吗?
  • 我读到一般来说最好使用 ScrollView
  • 如果您的数据使用相同的视图,则相反是正确的:在滚动视图中,每个视图都必须创建并保存在内存中。 Listviews 回收视图。

标签: java android dynamic scrollview xml-layout


【解决方案1】:

OnClickListeneronClick方法有一个参数vv 的值将是被点击的View,即ImageButton。您现在要做的就是将View 传递给EquipUnequip

...
btnSelected.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        EquipUnequip(w.WeaponID(), (ImageButton)v);
    }
});
...

private void EquipUnequip(int WeaponId, ImageButton btnSelected) {
    if(Game.Weapons.get(WeaponId).CharacterID() == ChrSelected) {
        btnSelected.setImageResource(R.drawable.eqip_but_idle);
    } else {
        btnSelected.setImageResource(R.drawable.eqip_but_press);
    }
}

PS:这部分对我来说似乎有点荒谬:

View view = new View(this);
LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.menuweapons_row, null);

为什么你创建一个新的View 只是为了什么都不做,然后用LayoutInflater 的结果替换它?


编辑

如果您真的需要视图的行(并且它永远不会改变),这里有 2 种选择:

  1. 保存OnClickListener中的行

    class MyOnClickListener implements OnClickListener {
        private final int rowIndex;
        MyOnClickListener(int rowIndex) {
            this.rowIndex = rowIndex;
        }
    
        @Override
        public void onClick(View v) {
            // do something with rowIndex
        }
    }
    

    并使用它代替您的匿名类 或者只是在您的匿名类之外添加一个最终变量:

    // currentRowIndex calculated by your program
    // i.e. incremented in every iteration
    final int rowIndex = currentRowIndex;
    btnSelected.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // do something with rowIndex
        }
    });
    
  2. 将信息作为标签添加到按钮(currentRowIndex 的类型为 int):

    btnSelected.setTag(currentRowIndex); // attach Integer data to the view
    btnSelected.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            int rowIndex = (Integer)v.getTag();
            // do something with rowIndex
        }
    });
    

【讨论】:

  • 这么愚蠢的我应该发现它有效,谢谢
  • 我确实有一个后续问题,我忘记了在我的动态代码中我还有一个 ImageView,当单击它时需要以与 ImageButton 相同的方式操作。在同一行上选择 ImageView 时如何检测到 ImageButton 行?
  • @LandLPartners:可以在Listener中添加一个字段(非匿名类)或者在循环中添加一个final变量(这样就可以从匿名类监听类中访问),使用@987654321 @View,...
  • 我以前试过这个,但不能完全工作,你能提供一些示例代码吗?
【解决方案2】:

将 onClick() 的 View 参数赋予 EquipUnequip(),将其转换为 ImageButton 并使用它。否则,您将获得最后创建的按钮。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-29
    • 2017-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多